diff --git a/config_enhanced_ads.json b/config_enhanced_ads.json new file mode 100644 index 0000000..f4bd2de --- /dev/null +++ b/config_enhanced_ads.json @@ -0,0 +1,47 @@ +{ + "proxy": { + "host": "your-proxy-host.com", + "port": "823", + "username": "your-username", + "password": "your-password" + }, + "targets": { + "main_site": "https://game.586vip.cn/", + "game_page": "https://game.586vip.cn/games/2048/index.html" + }, + "settings": { + "default_visits": 20, + "min_delay": 30, + "max_delay": 120, + "main_site_stay_time": [25, 60], + "game_page_stay_time": [30, 90] + }, + "ad_settings": { + "enable_close_button_clicks": true, + "close_button_probability": 0.75, + "mobile_device_probability": 0.85, + "ad_annoyance_factor": 0.8, + "real_user_behavior": true + }, + "supported_ad_types": [ + "popup", + "interstitial", + "banner", + "native", + "side", + "bottom" + ], + "user_behavior_config": { + "find_close_button_time": [0.5, 2.5], + "think_time": [2, 5], + "reaction_time": [1, 3], + "click_delay": [0.2, 0.8], + "relief_time": [0.5, 1.5] + }, + "game_specific": { + "pre_game_ad_skip_rate": 0.7, + "mid_game_ad_close_rate": 0.8, + "post_game_ad_close_rate": 0.5, + "game_play_time": [30, 90] + } +} \ No newline at end of file diff --git a/enhanced_ad_bot.py b/enhanced_ad_bot.py new file mode 100644 index 0000000..769568f --- /dev/null +++ b/enhanced_ad_bot.py @@ -0,0 +1,880 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +增强版广告刷量机器人 (真实用户行为版) +专门用于与多种广告类型进行真实交互 +包括模拟点击关闭按钮的真实用户行为 +""" + +import requests +import time +import random +import json +import os +import logging +from urllib.parse import urlparse, urljoin +import re +from real_user_database import RealUserDatabase + +# 配置日志 +logging.basicConfig( + level=logging.INFO, + format='%(asctime)s - %(levelname)s - %(message)s', + handlers=[ + logging.FileHandler('enhanced_ad_bot.log', encoding='utf-8'), + logging.StreamHandler() + ] +) +logger = logging.getLogger(__name__) + +class EnhancedAdBot: + def __init__(self, config_file='config.json'): + """ + 初始化增强版广告机器人 + """ + self.config = self.load_config(config_file) + self.session = None + self.user_db = RealUserDatabase() + self.current_profile = None + self.current_behavior = None + + # 🎯 广告类型和真实行为概率 + self.ad_behaviors = { + "popup": { + "close_probability": 0.75, # 75%概率关闭弹窗 + "click_probability": 0.15, # 15%概率点击广告 + "ignore_probability": 0.10, # 10%概率忽略 + "stay_time": (2, 8), # 停留时间范围 + "annoyance_level": 0.8 # 用户讨厌程度 + }, + "interstitial": { + "close_probability": 0.60, # 60%概率关闭插页 + "click_probability": 0.25, # 25%概率点击广告 + "wait_probability": 0.15, # 15%概率等待倒计时 + "stay_time": (5, 15), # 停留时间范围 + "annoyance_level": 0.6 # 用户讨厌程度 + }, + "banner": { + "close_probability": 0.85, # 85%概率关闭横幅 + "click_probability": 0.10, # 10%概率点击广告 + "ignore_probability": 0.05, # 5%概率忽略 + "stay_time": (1, 4), # 停留时间范围 + "annoyance_level": 0.9 # 用户讨厌程度 + }, + "native": { + "close_probability": 0.45, # 45%概率关闭原生广告 + "click_probability": 0.35, # 35%概率点击广告 + "read_probability": 0.20, # 20%概率仔细阅读 + "stay_time": (3, 12), # 停留时间范围 + "annoyance_level": 0.3 # 用户讨厌程度较低 + }, + "side": { + "close_probability": 0.70, # 70%概率关闭侧边广告 + "click_probability": 0.20, # 20%概率点击广告 + "ignore_probability": 0.10, # 10%概率忽略 + "stay_time": (1, 5), # 停留时间范围 + "annoyance_level": 0.7 # 用户讨厌程度 + }, + "bottom": { + "close_probability": 0.80, # 80%概率关闭底部广告 + "click_probability": 0.12, # 12%概率点击广告 + "ignore_probability": 0.08, # 8%概率忽略 + "stay_time": (1, 3), # 停留时间范围 + "annoyance_level": 0.8 # 用户讨厌程度 + } + } + + # 🎮 游戏列表 + self.games_list = [ + {"name": "2048", "url": "/games/2048/index.html", "category": "puzzle"}, + {"name": "Snake", "url": "/games/snake/index.html", "category": "arcade"}, + {"name": "DIY Doll Factory", "url": "/games/iframe-games.html?game=diy-doll-factory", "category": "puzzle"}, + {"name": "Super Sprunki Adventure", "url": "/games/iframe-games.html?game=super-sprunki-adventure", "category": "action"}, + {"name": "FlightBird", "url": "/games/iframe-games.html?game=flightbird", "category": "action"}, + ] + + # 🎯 真实的访问来源 + self.traffic_sources = [ + "https://www.google.com/search?q=free+online+games", + "https://www.google.com/search?q=2048+game+online", + "https://www.google.com/search?q=html5+games+mobile", + "https://www.google.com/search?q=在线小游戏", + "https://www.google.com/search?q=免费网页游戏", + "https://www.baidu.com/s?wd=2048数字游戏", + "https://www.reddit.com/r/WebGames/", + "https://github.com/topics/html5-game", + "https://news.ycombinator.com/", + ] + + # 📊 访问统计 + self.visit_stats = { + "total_visits": 0, + "ad_interactions": { + "popup": {"shows": 0, "closes": 0, "clicks": 0}, + "interstitial": {"shows": 0, "closes": 0, "clicks": 0}, + "banner": {"shows": 0, "closes": 0, "clicks": 0}, + "native": {"shows": 0, "closes": 0, "clicks": 0}, + "side": {"shows": 0, "closes": 0, "clicks": 0}, + "bottom": {"shows": 0, "closes": 0, "clicks": 0} + }, + "total_ad_time": 0, + "close_button_clicks": 0, + "ad_content_clicks": 0 + } + + def load_config(self, config_file): + """加载配置文件""" + try: + with open(config_file, 'r', encoding='utf-8') as f: + config = json.load(f) + logger.info(f"配置文件加载成功: {config_file}") + return config + except FileNotFoundError: + logger.error(f"配置文件未找到: {config_file}") + raise + except json.JSONDecodeError as e: + logger.error(f"配置文件格式错误: {e}") + raise + + def setup_session(self): + """设置请求会话""" + self.session = requests.Session() + self.session.cookies.clear() + + # 生成真实用户配置 + self.current_profile = self.user_db.get_random_user_profile() + self.current_behavior = self.user_db.get_visit_behavior() + + # 设置代理 + proxy_config = self.config.get('proxy') + if proxy_config: + proxy_url = f"http://{proxy_config['username']}:{proxy_config['password']}@{proxy_config['host']}:{proxy_config['port']}" + self.session.proxies = { + 'http': proxy_url, + 'https': proxy_url + } + logger.info(f"已配置代理: {proxy_config['host']}:{proxy_config['port']}") + + # 🎯 真实用户代理 - 优先移动端 + if random.random() < 0.85: # 85%概率使用移动端 + mobile_agents = [ + "Mozilla/5.0 (iPhone; CPU iPhone OS 17_1_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.1 Mobile/15E148 Safari/604.1", + "Mozilla/5.0 (iPhone; CPU iPhone OS 16_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1", + "Mozilla/5.0 (Linux; Android 14; SM-G991B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36", + "Mozilla/5.0 (Linux; Android 13; SM-A515F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Mobile Safari/537.36", + "Mozilla/5.0 (iPad; CPU OS 17_1_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.1 Mobile/15E148 Safari/604.1", + ] + user_agent = random.choice(mobile_agents) + is_mobile = True + else: + user_agent = self.current_profile["user_agent"] + is_mobile = "Mobile" in user_agent + + # 广告友好的请求头 + headers = { + "User-Agent": user_agent, + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", + "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8", + "Accept-Encoding": "gzip, deflate, br", + "Connection": "keep-alive", + "Upgrade-Insecure-Requests": "1", + "Sec-Fetch-Dest": "document", + "Sec-Fetch-Mode": "navigate", + "Sec-Fetch-Site": "none", + "Sec-Fetch-User": "?1", + "Cache-Control": "max-age=0", + "DNT": "0", # 不启用DNT,对广告友好 + } + + if is_mobile: + headers.update({ + "Sec-CH-UA-Mobile": "?1", + "Viewport-Width": str(random.choice([375, 414, 390, 393, 412])), + }) + + self.session.headers.update(headers) + + logger.info(f"🎭 增强版广告机器人配置:") + logger.info(f" 📱 移动端: {is_mobile}") + logger.info(f" 🎯 访问模式: {self.current_behavior['pattern_type']}") + logger.info(f" 😤 用户讨厌广告概率: 75%") + + def simulate_traffic_source(self): + """模拟真实的访问来源""" + source = random.choice(self.traffic_sources) + + try: + logger.info(f"🔗 模拟从来源访问: {source}") + + # 根据来源类型设置不同的行为 + if "google.com" in source or "baidu.com" in source: + stay_time = random.uniform(2, 8) + logger.info(f"🔍 搜索引擎停留: {stay_time:.1f}秒") + elif "reddit.com" in source: + stay_time = random.uniform(8, 20) + logger.info(f"🔍 Reddit停留: {stay_time:.1f}秒") + elif "github.com" in source: + stay_time = random.uniform(5, 15) + logger.info(f"🔍 GitHub停留: {stay_time:.1f}秒") + else: + stay_time = random.uniform(3, 12) + logger.info(f"🔍 其他来源停留: {stay_time:.1f}秒") + + # 模拟来源网站行为 + self._simulate_source_behavior(stay_time) + + # 设置referrer + self.session.headers.update({ + 'Referer': source, + 'Sec-Fetch-Site': 'cross-site' + }) + + return True + + except Exception as e: + logger.error(f"来源访问模拟失败: {e}") + return False + + def _simulate_source_behavior(self, total_time): + """模拟在来源网站的行为""" + actions = ["浏览搜索结果", "阅读页面内容", "查看相关链接", "滚动浏览页面"] + segments = random.randint(2, 4) + segment_time = total_time / segments + + for i in range(segments): + if i > 0: + time.sleep(random.uniform(0.5, 2)) + + action = random.choice(actions) + logger.info(f" 🔍 {action}") + time.sleep(segment_time * random.uniform(0.7, 1.3)) + + def visit_homepage_with_enhanced_ads(self): + """访问增强版首页并进行真实广告交互""" + main_site = self.config['targets']['main_site'] + + try: + logger.info(f"🏠 访问增强版首页: {main_site}") + + # 访问前延迟 + pre_delay = random.uniform(2, 5) + logger.info(f"🕐 访问前延迟: {pre_delay:.1f}秒") + time.sleep(pre_delay) + + # 发起请求 + response = self.session.get(main_site, timeout=20, allow_redirects=True) + + if response.status_code == 200: + logger.info(f"✅ 首页访问成功 ({response.status_code})") + logger.info(f"📦 页面大小: {len(response.content)} 字节") + + # 🎯 核心:模拟真实的多广告交互 + self._simulate_enhanced_ad_interactions(response) + + return True + else: + logger.error(f"❌ 首页访问失败 ({response.status_code})") + return False + + except Exception as e: + logger.error(f"首页访问出错: {e}") + return False + + def _simulate_enhanced_ad_interactions(self, response): + """模拟增强版广告交互 - 真实用户行为""" + base_url = response.url + + # 首页总停留时间 + homepage_stay_time = random.uniform(25, 60) # 25-60秒 + logger.info(f"🏠 首页总停留时间: {homepage_stay_time:.1f}秒") + + # 阶段性广告交互 + ad_interaction_phases = [ + {"name": "页面加载阶段", "duration": 0.15, "ads": ["side", "bottom"]}, + {"name": "内容浏览阶段", "duration": 0.25, "ads": ["banner", "native"]}, + {"name": "弹窗广告阶段", "duration": 0.30, "ads": ["popup", "interstitial"]}, + {"name": "深度浏览阶段", "duration": 0.30, "ads": ["all"]} + ] + + for phase in ad_interaction_phases: + phase_time = homepage_stay_time * phase["duration"] + logger.info(f"🎯 {phase['name']}: {phase_time:.1f}秒") + + # 在每个阶段处理对应的广告 + if phase["ads"] == ["all"]: + # 处理所有剩余广告 + self._handle_all_remaining_ads(base_url, phase_time) + else: + # 处理特定广告类型 + for ad_type in phase["ads"]: + self._handle_specific_ad_type(base_url, ad_type, phase_time / len(phase["ads"])) + + # 📊 输出广告交互统计 + self._log_ad_interaction_stats() + + def _handle_specific_ad_type(self, base_url, ad_type, allocated_time): + """处理特定类型的广告""" + if ad_type not in self.ad_behaviors: + return + + behavior = self.ad_behaviors[ad_type] + logger.info(f" 📺 处理{ad_type}广告 (分配时间: {allocated_time:.1f}秒)") + + # 记录广告显示 + self.visit_stats["ad_interactions"][ad_type]["shows"] += 1 + + # 模拟广告显示延迟 + display_delay = random.uniform(0.5, 2.5) + logger.info(f" 🔄 广告显示延迟: {display_delay:.1f}秒") + time.sleep(display_delay) + + # 模拟用户看到广告的反应时间 + reaction_time = random.uniform(1, 3) + logger.info(f" 👀 用户反应时间: {reaction_time:.1f}秒") + time.sleep(reaction_time) + + # 根据广告类型和用户心理决定行为 + user_action = self._decide_user_action(ad_type, behavior) + + # 执行用户行为 + self._execute_user_action(base_url, ad_type, user_action, allocated_time - display_delay - reaction_time) + + def _decide_user_action(self, ad_type, behavior): + """基于用户心理决定对广告的行为""" + # 考虑用户的讨厌程度 + annoyance_factor = behavior["annoyance_level"] + + # 考虑当前时间段(用户在不同时间对广告的容忍度不同) + time_factor = self._get_time_tolerance_factor() + + # 综合讨厌程度 + final_annoyance = min(annoyance_factor * time_factor, 1.0) + + # 随机数决定行为 + rand = random.random() + + if rand < behavior["close_probability"] * final_annoyance: + return "close" + elif rand < behavior["close_probability"] * final_annoyance + behavior["click_probability"]: + return "click" + elif hasattr(behavior, "read_probability") and rand < behavior["close_probability"] * final_annoyance + behavior["click_probability"] + behavior.get("read_probability", 0): + return "read" + elif hasattr(behavior, "wait_probability") and rand < behavior["close_probability"] * final_annoyance + behavior["click_probability"] + behavior.get("wait_probability", 0): + return "wait" + else: + return "ignore" + + def _get_time_tolerance_factor(self): + """获取时间容忍度因子""" + current_hour = time.localtime().tm_hour + + if 9 <= current_hour <= 18: # 工作时间 + return 1.2 # 更讨厌广告 + elif 19 <= current_hour <= 23: # 休闲时间 + return 0.8 # 相对容忍 + else: # 深夜 + return 1.0 # 普通 + + def _execute_user_action(self, base_url, ad_type, action, remaining_time): + """执行用户对广告的行为""" + logger.info(f" 🎯 用户行为: {action}") + + if action == "close": + self._simulate_close_ad(base_url, ad_type, remaining_time) + elif action == "click": + self._simulate_click_ad(base_url, ad_type, remaining_time) + elif action == "read": + self._simulate_read_ad(base_url, ad_type, remaining_time) + elif action == "wait": + self._simulate_wait_ad(base_url, ad_type, remaining_time) + else: # ignore + self._simulate_ignore_ad(base_url, ad_type, remaining_time) + + def _simulate_close_ad(self, base_url, ad_type, time_budget): + """模拟点击关闭广告按钮 - 真实用户行为""" + logger.info(f" ❌ 关闭{ad_type}广告") + + # 模拟寻找关闭按钮的时间 + find_close_time = random.uniform(0.5, 2.5) + logger.info(f" 🔍 寻找关闭按钮: {find_close_time:.1f}秒") + time.sleep(find_close_time) + + # 模拟点击关闭按钮 + click_delay = random.uniform(0.2, 0.8) + logger.info(f" 🖱️ 点击关闭按钮") + time.sleep(click_delay) + + # 模拟关闭按钮点击请求 + self._send_close_ad_request(base_url, ad_type) + + # 记录统计 + self.visit_stats["ad_interactions"][ad_type]["closes"] += 1 + self.visit_stats["close_button_clicks"] += 1 + + # 关闭后的心理释放时间 + relief_time = random.uniform(0.5, 1.5) + logger.info(f" 😌 关闭后释放: {relief_time:.1f}秒") + time.sleep(relief_time) + + def _simulate_click_ad(self, base_url, ad_type, time_budget): + """模拟点击广告内容""" + logger.info(f" 🖱️ 点击{ad_type}广告内容") + + # 模拟思考时间 + think_time = random.uniform(2, 5) + logger.info(f" 🤔 思考时间: {think_time:.1f}秒") + time.sleep(think_time) + + # 模拟点击广告 + click_delay = random.uniform(0.3, 1.0) + time.sleep(click_delay) + + # 模拟广告点击请求 + self._send_ad_click_request(base_url, ad_type) + + # 记录统计 + self.visit_stats["ad_interactions"][ad_type]["clicks"] += 1 + self.visit_stats["ad_content_clicks"] += 1 + + # 点击后可能的停留时间 + if random.random() < 0.7: # 70%概率会快速返回 + return_time = random.uniform(1, 3) + logger.info(f" 🔙 快速返回: {return_time:.1f}秒") + time.sleep(return_time) + + def _simulate_read_ad(self, base_url, ad_type, time_budget): + """模拟仔细阅读广告""" + logger.info(f" 📖 仔细阅读{ad_type}广告") + + # 模拟阅读时间 + read_time = random.uniform(5, 12) + logger.info(f" 📚 阅读时间: {read_time:.1f}秒") + time.sleep(read_time) + + # 阅读后可能的行为 + if random.random() < 0.3: # 30%概率阅读后点击 + self._simulate_click_ad(base_url, ad_type, time_budget - read_time) + else: + # 阅读后离开 + leave_time = random.uniform(1, 2) + time.sleep(leave_time) + + def _simulate_wait_ad(self, base_url, ad_type, time_budget): + """模拟等待广告倒计时""" + logger.info(f" ⏳ 等待{ad_type}广告倒计时") + + # 模拟等待倒计时时间 + wait_time = random.uniform(5, 8) + logger.info(f" ⏰ 等待倒计时: {wait_time:.1f}秒") + time.sleep(wait_time) + + # 倒计时结束后的行为 + if random.random() < 0.6: # 60%概率倒计时结束后关闭 + self._simulate_close_ad(base_url, ad_type, time_budget - wait_time) + + def _simulate_ignore_ad(self, base_url, ad_type, time_budget): + """模拟忽略广告""" + logger.info(f" 🙈 忽略{ad_type}广告") + + # 模拟忽略时间 + ignore_time = min(time_budget, random.uniform(2, 6)) + logger.info(f" 😐 忽略时间: {ignore_time:.1f}秒") + time.sleep(ignore_time) + + def _send_close_ad_request(self, base_url, ad_type): + """发送关闭广告的请求""" + try: + # 模拟关闭广告的API请求 + close_endpoints = [ + f"/api/ads/{ad_type}/close", + f"/ads/close?type={ad_type}", + f"/tracking/ad_close/{ad_type}", + f"/analytics/ad_interaction?action=close&type={ad_type}" + ] + + endpoint = random.choice(close_endpoints) + parsed_url = urlparse(base_url) + close_url = f"{parsed_url.scheme}://{parsed_url.netloc}{endpoint}" + + headers = self.session.headers.copy() + headers.update({ + "X-Requested-With": "XMLHttpRequest", + "Content-Type": "application/json", + "Referer": base_url, + }) + + response = self.session.post(close_url, headers=headers, + json={"ad_type": ad_type, "action": "close"}, + timeout=5) + + logger.info(f" 📤 关闭广告请求: {endpoint} ({response.status_code})") + + except Exception as e: + logger.debug(f" ⚠️ 关闭广告请求失败: {e}") + + def _send_ad_click_request(self, base_url, ad_type): + """发送广告点击请求""" + try: + # 模拟广告点击的API请求 + click_endpoints = [ + f"/api/ads/{ad_type}/click", + f"/ads/click?type={ad_type}", + f"/tracking/ad_click/{ad_type}", + f"/analytics/ad_interaction?action=click&type={ad_type}" + ] + + endpoint = random.choice(click_endpoints) + parsed_url = urlparse(base_url) + click_url = f"{parsed_url.scheme}://{parsed_url.netloc}{endpoint}" + + headers = self.session.headers.copy() + headers.update({ + "X-Requested-With": "XMLHttpRequest", + "Content-Type": "application/json", + "Referer": base_url, + }) + + response = self.session.post(click_url, headers=headers, + json={"ad_type": ad_type, "action": "click"}, + timeout=5) + + logger.info(f" 📤 广告点击请求: {endpoint} ({response.status_code})") + + except Exception as e: + logger.debug(f" ⚠️ 广告点击请求失败: {e}") + + def _handle_all_remaining_ads(self, base_url, phase_time): + """处理所有剩余的广告""" + logger.info(f" 📺 处理所有剩余广告") + + # 为每种广告类型分配时间 + ad_types = list(self.ad_behaviors.keys()) + time_per_ad = phase_time / len(ad_types) + + for ad_type in ad_types: + if random.random() < 0.8: # 80%概率处理该广告 + self._handle_specific_ad_type(base_url, ad_type, time_per_ad) + + def _log_ad_interaction_stats(self): + """记录广告交互统计""" + logger.info("📊 广告交互统计:") + + total_shows = 0 + total_closes = 0 + total_clicks = 0 + + for ad_type, stats in self.visit_stats["ad_interactions"].items(): + if stats["shows"] > 0: + close_rate = (stats["closes"] / stats["shows"]) * 100 + click_rate = (stats["clicks"] / stats["shows"]) * 100 + + logger.info(f" {ad_type}: 显示{stats['shows']}次, 关闭{stats['closes']}次({close_rate:.1f}%), 点击{stats['clicks']}次({click_rate:.1f}%)") + + total_shows += stats["shows"] + total_closes += stats["closes"] + total_clicks += stats["clicks"] + + if total_shows > 0: + overall_close_rate = (total_closes / total_shows) * 100 + overall_click_rate = (total_clicks / total_shows) * 100 + + logger.info(f" 总计: 显示{total_shows}次, 关闭{total_closes}次({overall_close_rate:.1f}%), 点击{total_clicks}次({overall_click_rate:.1f}%)") + logger.info(f" 关闭按钮点击: {self.visit_stats['close_button_clicks']}次") + logger.info(f" 广告内容点击: {self.visit_stats['ad_content_clicks']}次") + + def browse_games_with_ads(self): + """浏览游戏页面并处理广告""" + main_site = self.config['targets']['main_site'] + base_url = main_site.rstrip('/') + + games_to_browse = random.randint(2, 4) + selected_games = random.sample(self.games_list, min(games_to_browse, len(self.games_list))) + + logger.info(f"🎮 浏览 {games_to_browse} 个游戏页面") + + for i, game in enumerate(selected_games): + game_url = base_url + game["url"] + + try: + logger.info(f"🎯 游戏 {i+1}/{games_to_browse}: {game['name']}") + + # 设置referrer + if i == 0: + self.session.headers.update({'Referer': main_site}) + else: + prev_game_url = base_url + selected_games[i-1]["url"] + self.session.headers.update({'Referer': prev_game_url}) + + # 访问游戏页面 + response = self.session.get(game_url, timeout=15) + + if response.status_code == 200: + logger.info(f"✅ 游戏页面访问成功") + + # 模拟游戏页面的广告交互 + self._simulate_game_page_ads(response, game) + + else: + logger.warning(f"⚠️ 游戏页面访问失败 ({response.status_code})") + + # 页面间延迟 + if i < len(selected_games) - 1: + delay = random.uniform(3, 8) + logger.info(f" ⏳ 页面切换延迟: {delay:.1f}秒") + time.sleep(delay) + + except Exception as e: + logger.error(f"游戏页面访问出错: {e}") + continue + + return True + + def _simulate_game_page_ads(self, response, game): + """模拟游戏页面的广告交互""" + game_stay_time = random.uniform(30, 90) + logger.info(f" 🎮 游戏页面停留: {game_stay_time:.1f}秒") + + # 分配时间给不同的活动 + game_time = game_stay_time * 0.7 # 70%时间玩游戏 + ad_time = game_stay_time * 0.3 # 30%时间处理广告 + + logger.info(f" 🎯 游戏时间: {game_time:.1f}秒") + logger.info(f" 💰 广告时间: {ad_time:.1f}秒") + + # 模拟游戏前广告 + if random.random() < 0.8: # 80%概率有游戏前广告 + pre_ad_time = random.uniform(5, 15) + logger.info(f" 📺 游戏前广告: {pre_ad_time:.1f}秒") + + # 真实用户行为:大多数人讨厌游戏前广告 + if random.random() < 0.7: # 70%概率跳过或关闭 + logger.info(f" ⏭️ 用户厌烦,跳过广告") + time.sleep(random.uniform(2, 5)) + else: + logger.info(f" ✅ 用户耐心等待广告") + time.sleep(pre_ad_time) + + # 模拟游戏过程 + self._simulate_game_play(game, game_time) + + # 模拟游戏中广告 + if random.random() < 0.6: # 60%概率有游戏中广告 + mid_ad_time = random.uniform(3, 10) + logger.info(f" 📺 游戏中广告: {mid_ad_time:.1f}秒") + + # 游戏中广告更容易被关闭 + if random.random() < 0.8: # 80%概率关闭 + logger.info(f" ❌ 关闭游戏中广告") + time.sleep(random.uniform(1, 3)) + else: + time.sleep(mid_ad_time) + + # 模拟游戏结束广告 + if random.random() < 0.9: # 90%概率有结束广告 + end_ad_time = random.uniform(5, 20) + logger.info(f" 📺 游戏结束广告: {end_ad_time:.1f}秒") + + # 结束广告的处理较为复杂 + if random.random() < 0.5: # 50%概率立即关闭 + logger.info(f" ❌ 立即关闭结束广告") + time.sleep(random.uniform(1, 2)) + elif random.random() < 0.3: # 30%概率点击 + logger.info(f" 🖱️ 点击结束广告") + time.sleep(random.uniform(2, 5)) + else: # 20%概率看完 + logger.info(f" ✅ 看完结束广告") + time.sleep(end_ad_time) + + def _simulate_game_play(self, game, duration): + """模拟游戏过程""" + logger.info(f" 🎮 开始游戏: {game['name']}") + + # 根据游戏类型模拟不同行为 + if game["category"] == "puzzle": + actions = ["思考", "移动", "尝试", "撤销"] + segments = random.randint(4, 8) + elif game["category"] == "arcade": + actions = ["开始", "快速操作", "躲避", "收集"] + segments = random.randint(6, 12) + else: + actions = ["开始", "操作", "进行", "暂停"] + segments = random.randint(3, 6) + + segment_time = duration / segments + + for i in range(segments): + action = random.choice(actions) + logger.info(f" 🎯 {action}") + time.sleep(segment_time * random.uniform(0.8, 1.2)) + + def run_enhanced_ad_visit(self): + """执行增强版广告访问流程""" + logger.info("🚀 开始增强版广告访问流程") + + # 设置会话 + self.setup_session() + + try: + # 1. 模拟来源访问 + if not self.simulate_traffic_source(): + logger.warning("⚠️ 来源访问失败,继续执行") + + # 2. 访问增强版首页 + if not self.visit_homepage_with_enhanced_ads(): + logger.error("❌ 首页广告访问失败") + return False + + # 3. 浏览游戏页面 + if not self.browse_games_with_ads(): + logger.error("❌ 游戏页面访问失败") + return False + + # 更新统计 + self.visit_stats["total_visits"] += 1 + + logger.info("✅ 增强版广告访问流程完成!") + return True + + except Exception as e: + logger.error(f"❌ 访问流程出错: {e}") + return False + + finally: + if self.session: + self.session.close() + + def run_continuous_enhanced_visits(self, total_visits=None, delay_range=None): + """连续执行增强版广告访问""" + if total_visits is None: + total_visits = self.config['settings']['default_visits'] + + if delay_range is None: + delay_range = ( + self.config['settings']['min_delay'], + self.config['settings']['max_delay'] + ) + + success_count = 0 + + logger.info(f"🎯 开始连续增强版广告访问,目标: {total_visits} 次") + + for i in range(total_visits): + logger.info(f"{'='*70}") + logger.info(f"🔄 第 {i+1}/{total_visits} 次增强版广告访问") + logger.info(f"{'='*70}") + + visit_start_time = time.time() + + if self.run_enhanced_ad_visit(): + success_count += 1 + visit_time = time.time() - visit_start_time + + logger.info(f"✅ 第 {i+1} 次访问成功!耗时: {visit_time:.1f}秒") + + # 显示累计统计 + total_ad_shows = sum(stats["shows"] for stats in self.visit_stats["ad_interactions"].values()) + logger.info(f"📊 累计: 成功{success_count}, 广告显示{total_ad_shows}, 关闭{self.visit_stats['close_button_clicks']}, 点击{self.visit_stats['ad_content_clicks']}") + else: + logger.error(f"❌ 第 {i+1} 次访问失败!") + + # 访问间隔 + if i < total_visits - 1: + delay = random.uniform(delay_range[0], delay_range[1]) + logger.info(f"⏳ 等待 {delay:.1f} 秒") + time.sleep(delay) + + # 最终统计 + self._print_final_stats(success_count, total_visits) + + return success_count + + def _print_final_stats(self, success_count, total_visits): + """打印最终统计信息""" + success_rate = (success_count / total_visits) * 100 + total_ad_shows = sum(stats["shows"] for stats in self.visit_stats["ad_interactions"].values()) + total_ad_closes = sum(stats["closes"] for stats in self.visit_stats["ad_interactions"].values()) + total_ad_clicks = sum(stats["clicks"] for stats in self.visit_stats["ad_interactions"].values()) + + logger.info(f"🎉 增强版广告访问任务完成!") + logger.info(f"📊 访问统计:") + logger.info(f" 成功率: {success_count}/{total_visits} ({success_rate:.1f}%)") + logger.info(f" 广告显示总数: {total_ad_shows}") + logger.info(f" 关闭按钮点击: {self.visit_stats['close_button_clicks']} ({(self.visit_stats['close_button_clicks']/total_ad_shows*100):.1f}%)") + logger.info(f" 广告内容点击: {self.visit_stats['ad_content_clicks']} ({(self.visit_stats['ad_content_clicks']/total_ad_shows*100):.1f}%)") + logger.info(f"💡 真实用户行为: 75%的用户讨厌广告并选择关闭") + +def main(): + """主函数""" + config_file = 'config.json' + + if not os.path.exists(config_file): + print(f"❌ 配置文件 {config_file} 不存在!") + return + + try: + bot = EnhancedAdBot(config_file) + + print("=" * 80) + print("🎯 增强版广告刷量机器人 (真实用户行为版)") + print("=" * 80) + print("💡 核心特性:") + print(" 🎭 真实用户行为模拟 - 75%概率讨厌广告") + print(" ❌ 智能关闭广告按钮 - 模拟真实用户习惯") + print(" 📱 移动端优先 - 85%概率使用移动设备") + print(" 🎯 6种广告类型 - 弹窗、插页、横幅、原生、侧边、底部") + print(" 📊 详细交互统计 - 关闭率、点击率等") + print(" ⚠️ 请确保仅用于测试自己的网站!") + print() + print(f"🎯 目标网站: {bot.config['targets']['main_site']}") + print(f"📺 广告类型: {len(bot.ad_behaviors)} 种") + print(f"😤 用户讨厌广告: 75%概率") + print() + + print("请选择运行模式:") + print("1. 💎 单次增强版广告访问测试") + print("2. 🚀 连续增强版广告访问 (使用配置参数)") + print("3. ⚙️ 自定义连续增强版广告访问") + + choice = input("请输入选择 (1/2/3): ").strip() + + if choice == "1": + logger.info("🎬 开始单次增强版广告访问测试") + success = bot.run_enhanced_ad_visit() + if success: + print("🎉 单次增强版广告访问测试成功!") + else: + print("😞 单次增强版广告访问测试失败!") + + elif choice == "2": + logger.info("🎬 开始连续增强版广告访问") + success_count = bot.run_continuous_enhanced_visits() + total = bot.config['settings']['default_visits'] + print(f"🎉 连续增强版广告访问完成!成功: {success_count}/{total}") + + elif choice == "3": + try: + visit_count = int(input("请输入访问次数: ").strip()) + min_delay = int(input("请输入最小延迟秒数: ").strip()) + max_delay = int(input("请输入最大延迟秒数: ").strip()) + + logger.info(f"🎬 开始自定义增强版广告访问,次数: {visit_count}") + success_count = bot.run_continuous_enhanced_visits( + total_visits=visit_count, + delay_range=(min_delay, max_delay) + ) + + print(f"🎉 自定义增强版广告访问完成!成功: {success_count}/{visit_count}") + + except ValueError: + print("❌ 输入参数错误!") + else: + print("❌ 无效选择!") + + except KeyboardInterrupt: + print("\n⚠️ 用户中断执行") + except Exception as e: + logger.error(f"程序执行出错: {e}") + print("❌ 程序执行出错,请查看日志文件 enhanced_ad_bot.log") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/run_ad_bot.bat b/run_ad_bot.bat new file mode 100644 index 0000000..4046349 --- /dev/null +++ b/run_ad_bot.bat @@ -0,0 +1,76 @@ +@echo off +chcp 65001 >nul +title 广告刷量机器人 - Fun Games Hub专版 + +echo ============================================================ +echo 💰 广告刷量机器人 (Fun Games Hub专版) +echo ============================================================ +echo 🎯 专为Fun Games Hub游戏网站优化 +echo 💰 重点关注广告展示和交互 +echo 📱 移动端优先(广告收益更高) +echo 🎮 支持7种游戏类型 +echo ⚠️ 请确保仅用于测试自己的网站! +echo. + +:: 检查Python +python --version >nul 2>&1 +if %errorlevel% neq 0 ( + echo ❌ Python未安装!请先安装Python 3.7+ + pause + exit /b 1 +) + +echo ✅ Python已安装 +python --version + +:: 检查必要文件 +if not exist config.json ( + echo ❌ 配置文件 config.json 不存在! + pause + exit /b 1 +) + +if not exist real_user_database.py ( + echo ❌ 用户数据库文件 real_user_database.py 不存在! + pause + exit /b 1 +) + +if not exist website_traffic_ad_bot.py ( + echo ❌ 广告机器人文件 website_traffic_ad_bot.py 不存在! + pause + exit /b 1 +) + +echo ✅ 所有文件检查完成 + +:: 安装依赖 +echo. +echo 📦 检查并安装依赖... +pip install requests --quiet +if %errorlevel% neq 0 ( + echo ❌ 依赖安装失败! + pause + exit /b 1 +) +echo ✅ 依赖安装成功 + +echo. +echo 🎯 广告刷量机器人特性: +echo 📱 移动端优先 (80%概率) +echo 🏠 首页深度停留 (15-45秒) +echo 💰 广告专项行为模拟 +echo 🎮 多游戏页面浏览 +echo 📺 游戏前、中、后广告 +echo 🖱️ 广告点击模拟 (15%概率) +echo 🔄 广告交互行为 +echo 📊 详细广告统计 +echo. + +echo 🚀 启动广告刷量机器人... +python website_traffic_ad_bot.py + +echo. +echo 🏁 广告刷量任务完成! +echo 📝 详细日志请查看 ad_bot.log 文件 +pause \ No newline at end of file diff --git a/run_enhanced_ad_bot.bat b/run_enhanced_ad_bot.bat new file mode 100644 index 0000000..8aae1ba --- /dev/null +++ b/run_enhanced_ad_bot.bat @@ -0,0 +1,87 @@ +@echo off +chcp 65001 >nul +title 增强版广告刷量机器人 - 真实用户行为版 + +echo =============================================================== +echo 🎯 增强版广告刷量机器人 (真实用户行为版) +echo =============================================================== +echo 💡 核心特性: +echo 🎭 真实用户行为模拟 - 75%概率讨厌广告 +echo ❌ 智能关闭广告按钮 - 模拟真实用户习惯 +echo 📱 移动端优先 - 85%概率使用移动设备 +echo 🎯 6种广告类型 - 弹窗、插页、横幅、原生、侧边、底部 +echo 📊 详细交互统计 - 关闭率、点击率等 +echo ⚠️ 请确保仅用于测试自己的网站! +echo. + +:: 检查Python +python --version >nul 2>&1 +if %errorlevel% neq 0 ( + echo ❌ Python未安装!请先安装Python 3.7+ + pause + exit /b 1 +) + +echo ✅ Python已安装 +python --version + +:: 检查必要文件 +if not exist config.json ( + echo ❌ 配置文件 config.json 不存在! + pause + exit /b 1 +) + +if not exist real_user_database.py ( + echo ❌ 用户数据库文件 real_user_database.py 不存在! + pause + exit /b 1 +) + +if not exist enhanced_ad_bot.py ( + echo ❌ 增强版广告机器人文件 enhanced_ad_bot.py 不存在! + pause + exit /b 1 +) + +if not exist index_enhanced_ads.html ( + echo ❌ 增强版首页文件 index_enhanced_ads.html 不存在! + pause + exit /b 1 +) + +echo ✅ 所有文件检查完成 + +:: 安装依赖 +echo. +echo 📦 检查并安装依赖... +pip install requests --quiet +if %errorlevel% neq 0 ( + echo ❌ 依赖安装失败! + pause + exit /b 1 +) +echo ✅ 依赖安装成功 + +echo. +echo 🎯 增强版广告机器人特性: +echo 😤 用户讨厌广告 - 75%概率点击关闭按钮 +echo 📱 移动端优先 - 85%概率使用移动设备 +echo 🎭 真实行为模拟 - 寻找关闭按钮、思考时间等 +echo 📊 详细统计 - 关闭率、点击率、用户行为分析 +echo 🎯 多种广告类型 - 弹窗、插页、横幅、原生、侧边、底部 +echo ⏳ 真实时间模拟 - 反应时间、操作延迟等 +echo. + +echo 🚀 启动增强版广告刷量机器人... +python enhanced_ad_bot.py + +echo. +echo 🏁 增强版广告刷量任务完成! +echo 📝 详细日志请查看 enhanced_ad_bot.log 文件 +echo 💡 真实用户行为特点: +echo - 75%的用户讨厌广告并选择关闭 +echo - 移动端用户更容易关闭广告 +echo - 游戏前、中、后广告处理不同 +echo - 包含寻找关闭按钮、思考时间等真实行为 +pause \ No newline at end of file diff --git a/run_universal_ad_bot.bat b/run_universal_ad_bot.bat new file mode 100644 index 0000000..21dce0c --- /dev/null +++ b/run_universal_ad_bot.bat @@ -0,0 +1,83 @@ +@echo off +chcp 65001 >nul +title 通用广告刷量机器人 - 智能识别版 + +echo =============================================================== +echo 🎯 通用广告刷量机器人 (智能识别版) +echo =============================================================== +echo 💡 核心特性: +echo 🔍 智能广告识别 - 自动检测各种广告类型 +echo 🎭 真实用户行为 - 75%概率讨厌广告 +echo ❌ 智能关闭按钮 - 自动寻找并点击关闭按钮 +echo 📱 移动端优先 - 85%概率使用移动设备 +echo 🌐 通用适配 - 适用于任何广告网络 +echo 📊 详细统计 - 检测率、关闭率、点击率 +echo ⚠️ 请确保仅用于测试自己的网站! +echo. + +:: 检查Python +python --version >nul 2>&1 +if %errorlevel% neq 0 ( + echo ❌ Python未安装!请先安装Python 3.7+ + pause + exit /b 1 +) + +echo ✅ Python已安装 +python --version + +:: 检查必要文件 +if not exist config.json ( + echo ❌ 配置文件 config.json 不存在! + pause + exit /b 1 +) + +if not exist real_user_database.py ( + echo ❌ 用户数据库文件 real_user_database.py 不存在! + pause + exit /b 1 +) + +if not exist universal_ad_bot.py ( + echo ❌ 通用广告机器人文件 universal_ad_bot.py 不存在! + pause + exit /b 1 +) + +echo ✅ 所有文件检查完成 + +:: 安装依赖 +echo. +echo 📦 检查并安装依赖... +pip install requests --quiet +if %errorlevel% neq 0 ( + echo ❌ 依赖安装失败! + pause + exit /b 1 +) +echo ✅ 依赖安装成功 + +echo. +echo 🎯 智能广告识别特性: +echo 🔍 支持广告网络: Google AdSense, MonetTag, PropellerAds +echo 📱 移动端优先 - 85%概率使用移动设备 +echo 🎭 真实行为模拟 - 寻找关闭按钮、思考时间等 +echo 📊 智能统计 - 检测率、关闭率、点击率分析 +echo 🌐 通用适配 - 无需修改HTML,适用于任何网站 +echo ⏳ 真实时间模拟 - 反应时间、操作延迟等 +echo. + +echo 🚀 启动通用广告刷量机器人... +python universal_ad_bot.py + +echo. +echo 🏁 通用广告刷量任务完成! +echo 📝 详细日志请查看 universal_ad_bot.log 文件 +echo 💡 智能识别特点: +echo - 自动检测各种广告网络和类型 +echo - 75%的用户讨厌广告并选择关闭 +echo - 智能识别关闭按钮并模拟点击 +echo - 适用于任何使用智能合一广告的网站 +echo - 无需修改现有HTML结构 +pause \ No newline at end of file diff --git a/traffic_bot_final.log b/traffic_bot_final.log index 8f0d3d6..4025887 100644 --- a/traffic_bot_final.log +++ b/traffic_bot_final.log @@ -18,3 +18,22 @@ 2025-07-18 11:25:02,200 - INFO - 🔗 模拟从来源访问: https://github.com/topics/game 2025-07-18 11:25:02,203 - INFO - 🐙 GitHub页面停留 18.7 秒 2025-07-18 11:25:02,203 - INFO - 🐙 GitHub行为: 查看项目描述 +2025-07-18 11:25:14,691 - INFO - 🐙 GitHub行为: 阅读README文件 +2025-07-18 11:25:27,164 - INFO - 🐙 GitHub行为: 阅读README文件 +2025-07-18 11:25:31,529 - INFO - 🏠 访问目标网站: https://game.586vip.cn/ +2025-07-18 11:25:31,529 - INFO - 🕐 人工延迟: 6.6秒 +2025-07-18 11:25:39,452 - INFO - 📡 HTTP请求详情: +2025-07-18 11:25:39,452 - INFO - 📍 访问URL: https://game.586vip.cn/ +2025-07-18 11:25:39,452 - INFO - 📊 状态码: 200 +2025-07-18 11:25:39,452 - INFO - 📦 响应大小: 34940 字节 +2025-07-18 11:25:39,452 - INFO - ⏱️ 响应时间: 1.32秒 +2025-07-18 11:25:39,453 - INFO - 📄 内容类型: text/html +2025-07-18 11:25:39,453 - INFO - 🖥️ 服务器: nginx +2025-07-18 11:25:39,453 - INFO - 📖 页面分析: +2025-07-18 11:25:39,453 - INFO - 📝 内容长度: 16619 字符 +2025-07-18 11:25:39,453 - INFO - ⏱️ 预估阅读时间: 3716.4 秒 +2025-07-18 11:25:39,453 - INFO - 🕐 实际停留时间: 5.9 秒 +2025-07-18 11:25:39,454 - INFO - 📱 查看页脚信息 +2025-07-18 11:25:40,273 - INFO - 📖 阅读页面内容 +2025-07-18 11:25:40,906 - INFO - 🔗 检查页面链接 +2025-07-18 11:25:41,956 - INFO - 📱 查看页脚信息 diff --git a/universal_ad_bot.py b/universal_ad_bot.py new file mode 100644 index 0000000..c6ed205 --- /dev/null +++ b/universal_ad_bot.py @@ -0,0 +1,1189 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +通用广告刷量机器人 (智能识别版) +智能识别网页上的各种广告类型并模拟真实用户行为 +适用于任何使用智能合一广告系统的网站 +""" + +import requests +import time +import random +import json +import os +import logging +from urllib.parse import urlparse, urljoin +import re +from real_user_database import RealUserDatabase + +# 配置日志 +logging.basicConfig( + level=logging.INFO, + format='%(asctime)s - %(levelname)s - %(message)s', + handlers=[ + logging.FileHandler('universal_ad_bot.log', encoding='utf-8'), + logging.StreamHandler() + ] +) +logger = logging.getLogger(__name__) + +class UniversalAdBot: + def __init__(self, config_file='config.json'): + """ + 初始化通用广告机器人 + """ + self.config = self.load_config(config_file) + self.session = None + self.user_db = RealUserDatabase() + self.current_profile = None + self.current_behavior = None + + # 🎯 广告元素识别模式 + self.ad_selectors = { + # 通用广告容器 + "containers": [ + "div[class*='ad']", "div[id*='ad']", "div[class*='banner']", + "div[class*='popup']", "div[class*='modal']", "div[class*='overlay']", + "div[class*='interstitial']", "div[class*='native']", "div[class*='sponsor']", + "iframe[src*='ads']", "iframe[src*='doubleclick']", "iframe[src*='googlesyndication']", + "ins[class*='adsbygoogle']", "[data-ad-client]", "[data-ad-slot]" + ], + # 关闭按钮模式 + "close_buttons": [ + "button[class*='close']", "span[class*='close']", "div[class*='close']", + "a[class*='close']", "i[class*='close']", "[aria-label*='close']", + "[title*='close']", "[alt*='close']", "button[type='button']", + ".close", ".btn-close", ".modal-close", ".popup-close", + "span:contains('×')", "span:contains('✕')", "span:contains('Close')" + ], + # 广告点击区域 + "clickable_areas": [ + "a[href*='ads']", "a[href*='click']", "a[href*='redirect']", + "button[onclick*='ad']", "div[onclick*='ad']", "[data-click]", + "img[src*='ad']", "video[src*='ad']", "[data-ad-click]" + ] + } + + # 🎯 广告行为概率配置 + self.ad_behaviors = { + "popup_modal": { + "close_probability": 0.80, # 80%概率关闭弹窗 + "click_probability": 0.12, # 12%概率点击 + "ignore_probability": 0.08, # 8%概率忽略 + "annoyance_level": 0.9 # 高讨厌程度 + }, + "banner_display": { + "close_probability": 0.85, # 85%概率关闭横幅 + "click_probability": 0.10, # 10%概率点击 + "ignore_probability": 0.05, # 5%概率忽略 + "annoyance_level": 0.8 # 高讨厌程度 + }, + "native_content": { + "close_probability": 0.45, # 45%概率关闭原生广告 + "click_probability": 0.35, # 35%概率点击 + "read_probability": 0.20, # 20%概率阅读 + "annoyance_level": 0.3 # 低讨厌程度 + }, + "video_preroll": { + "skip_probability": 0.70, # 70%概率跳过视频广告 + "watch_probability": 0.20, # 20%概率观看 + "click_probability": 0.10, # 10%概率点击 + "annoyance_level": 0.7 # 较高讨厌程度 + }, + "interstitial_fullscreen": { + "close_probability": 0.65, # 65%概率关闭全屏广告 + "click_probability": 0.20, # 20%概率点击 + "wait_probability": 0.15, # 15%概率等待 + "annoyance_level": 0.6 # 中等讨厌程度 + } + } + + # 🎮 游戏列表 + self.games_list = [ + {"name": "2048", "url": "/games/2048/index.html", "category": "puzzle"}, + {"name": "Snake", "url": "/games/snake/index.html", "category": "arcade"}, + {"name": "DIY Doll Factory", "url": "/games/iframe-games.html?game=diy-doll-factory", "category": "puzzle"}, + {"name": "Super Sprunki Adventure", "url": "/games/iframe-games.html?game=super-sprunki-adventure", "category": "action"}, + {"name": "FlightBird", "url": "/games/iframe-games.html?game=flightbird", "category": "action"}, + ] + + # 🎯 真实的访问来源 + self.traffic_sources = [ + "https://www.google.com/search?q=free+online+games", + "https://www.google.com/search?q=2048+game+online", + "https://www.google.com/search?q=html5+games+mobile", + "https://www.google.com/search?q=在线小游戏", + "https://www.google.com/search?q=免费网页游戏", + "https://www.baidu.com/s?wd=2048数字游戏", + "https://www.reddit.com/r/WebGames/", + "https://github.com/topics/html5-game", + "https://news.ycombinator.com/", + ] + + # 📊 访问统计 + self.visit_stats = { + "total_visits": 0, + "ad_interactions": { + "detected_ads": 0, + "close_button_clicks": 0, + "ad_content_clicks": 0, + "skip_actions": 0, + "ignored_ads": 0 + }, + "ad_types_found": {}, + "total_ad_time": 0, + "detection_success_rate": 0 + } + + def load_config(self, config_file): + """加载配置文件""" + try: + with open(config_file, 'r', encoding='utf-8') as f: + config = json.load(f) + logger.info(f"配置文件加载成功: {config_file}") + return config + except FileNotFoundError: + logger.error(f"配置文件未找到: {config_file}") + raise + except json.JSONDecodeError as e: + logger.error(f"配置文件格式错误: {e}") + raise + + def setup_session(self): + """设置请求会话""" + self.session = requests.Session() + self.session.cookies.clear() + + # 生成真实用户配置 + self.current_profile = self.user_db.get_random_user_profile() + self.current_behavior = self.user_db.get_visit_behavior() + + # 设置代理 + proxy_config = self.config.get('proxy') + if proxy_config: + proxy_url = f"http://{proxy_config['username']}:{proxy_config['password']}@{proxy_config['host']}:{proxy_config['port']}" + self.session.proxies = { + 'http': proxy_url, + 'https': proxy_url + } + logger.info(f"已配置代理: {proxy_config['host']}:{proxy_config['port']}") + + # 🎯 真实用户代理 - 优先移动端 + if random.random() < 0.85: # 85%概率使用移动端 + mobile_agents = [ + "Mozilla/5.0 (iPhone; CPU iPhone OS 17_1_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.1 Mobile/15E148 Safari/604.1", + "Mozilla/5.0 (iPhone; CPU iPhone OS 16_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1", + "Mozilla/5.0 (Linux; Android 14; SM-G991B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36", + "Mozilla/5.0 (Linux; Android 13; SM-A515F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Mobile Safari/537.36", + "Mozilla/5.0 (iPad; CPU OS 17_1_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.1 Mobile/15E148 Safari/604.1", + ] + user_agent = random.choice(mobile_agents) + is_mobile = True + else: + user_agent = self.current_profile["user_agent"] + is_mobile = "Mobile" in user_agent + + # 广告友好的请求头 + headers = { + "User-Agent": user_agent, + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", + "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8", + "Accept-Encoding": "gzip, deflate, br", + "Connection": "keep-alive", + "Upgrade-Insecure-Requests": "1", + "Sec-Fetch-Dest": "document", + "Sec-Fetch-Mode": "navigate", + "Sec-Fetch-Site": "none", + "Sec-Fetch-User": "?1", + "Cache-Control": "max-age=0", + "DNT": "0", # 不启用DNT,对广告友好 + } + + if is_mobile: + headers.update({ + "Sec-CH-UA-Mobile": "?1", + "Viewport-Width": str(random.choice([375, 414, 390, 393, 412])), + }) + + self.session.headers.update(headers) + + logger.info(f"🎭 通用广告机器人配置:") + logger.info(f" 📱 移动端: {is_mobile}") + logger.info(f" 🎯 访问模式: {self.current_behavior['pattern_type']}") + logger.info(f" 🔍 智能广告识别: 启用") + logger.info(f" 😤 用户讨厌广告概率: 75%") + + def simulate_traffic_source(self): + """模拟真实的访问来源""" + source = random.choice(self.traffic_sources) + + try: + logger.info(f"🔗 模拟从来源访问: {source}") + + # 根据来源类型设置不同的行为 + if "google.com" in source or "baidu.com" in source: + stay_time = random.uniform(2, 8) + logger.info(f"🔍 搜索引擎停留: {stay_time:.1f}秒") + elif "reddit.com" in source: + stay_time = random.uniform(8, 20) + logger.info(f"🔍 Reddit停留: {stay_time:.1f}秒") + elif "github.com" in source: + stay_time = random.uniform(5, 15) + logger.info(f"🔍 GitHub停留: {stay_time:.1f}秒") + else: + stay_time = random.uniform(3, 12) + logger.info(f"🔍 其他来源停留: {stay_time:.1f}秒") + + # 模拟来源网站行为 + self._simulate_source_behavior(stay_time) + + # 设置referrer + self.session.headers.update({ + 'Referer': source, + 'Sec-Fetch-Site': 'cross-site' + }) + + return True + + except Exception as e: + logger.error(f"来源访问模拟失败: {e}") + return False + + def _simulate_source_behavior(self, total_time): + """模拟在来源网站的行为""" + actions = ["浏览搜索结果", "阅读页面内容", "查看相关链接", "滚动浏览页面"] + segments = random.randint(2, 4) + segment_time = total_time / segments + + for i in range(segments): + if i > 0: + time.sleep(random.uniform(0.5, 2)) + + action = random.choice(actions) + logger.info(f" 🔍 {action}") + time.sleep(segment_time * random.uniform(0.7, 1.3)) + + def visit_homepage_with_universal_ads(self): + """访问首页并智能识别处理广告""" + main_site = self.config['targets']['main_site'] + + try: + logger.info(f"🏠 访问首页并智能识别广告: {main_site}") + + # 访问前延迟 + pre_delay = random.uniform(2, 5) + logger.info(f"🕐 访问前延迟: {pre_delay:.1f}秒") + time.sleep(pre_delay) + + # 发起请求 + response = self.session.get(main_site, timeout=20, allow_redirects=True) + + if response.status_code == 200: + logger.info(f"✅ 首页访问成功 ({response.status_code})") + logger.info(f"📦 页面大小: {len(response.content)} 字节") + + # 🎯 核心:智能识别和处理广告 + self._intelligent_ad_detection_and_interaction(response) + + return True + else: + logger.error(f"❌ 首页访问失败 ({response.status_code})") + return False + + except Exception as e: + logger.error(f"首页访问出错: {e}") + return False + + def _intelligent_ad_detection_and_interaction(self, response): + """智能识别和处理广告""" + base_url = response.url + page_content = response.text + + # 首页总停留时间 + homepage_stay_time = random.uniform(25, 60) + logger.info(f"🏠 首页总停留时间: {homepage_stay_time:.1f}秒") + + # 🔍 智能检测页面上的广告 + detected_ads = self._detect_ads_in_page(page_content) + + if detected_ads: + logger.info(f"🎯 智能检测到 {len(detected_ads)} 个广告元素") + self.visit_stats["ad_interactions"]["detected_ads"] += len(detected_ads) + + # 分阶段处理检测到的广告 + self._process_detected_ads(base_url, detected_ads, homepage_stay_time) + else: + logger.info("🔍 未检测到明显的广告元素,进行通用广告行为模拟") + self._simulate_generic_ad_behavior(base_url, homepage_stay_time) + + # 📊 输出检测和交互统计 + self._log_universal_ad_stats() + + def _detect_ads_in_page(self, page_content): + """在页面内容中检测广告""" + detected_ads = [] + + # 检测广告脚本标签 + ad_scripts = [ + r'googlesyndication\.com', + r'doubleclick\.net', + r'googletagmanager\.com', + r'facebook\.com/tr', + r'monetag', + r'adnxs\.com', + r'adsystem\.com', + r'amazon-adsystem\.com', + r'ads\.yahoo\.com', + r'media\.net', + r'popads\.net', + r'propellerads\.com', + r'adsterra\.com', + r'exoclick\.com', + r'clickadu\.com', + r'hilltopads\.com', + r'theprofitzone\.com', + r'revcontent\.com', + r'outbrain\.com', + r'taboola\.com', + r'mgid\.com' + ] + + for script_pattern in ad_scripts: + matches = re.findall(script_pattern, page_content, re.IGNORECASE) + if matches: + ad_type = self._classify_ad_type(script_pattern) + detected_ads.append({ + "type": ad_type, + "source": script_pattern, + "count": len(matches) + }) + logger.info(f" 🔍 检测到 {ad_type} 广告: {len(matches)} 个") + + # 检测广告HTML元素 + ad_elements = [ + r']*class="[^"]*ad[^"]*"[^>]*>', + r']*id="[^"]*ad[^"]*"[^>]*>', + r']*class="[^"]*adsbygoogle[^"]*"[^>]*>', + r']*src="[^"]*ads[^"]*"[^>]*>', + r']*class="[^"]*banner[^"]*"[^>]*>', + r']*class="[^"]*popup[^"]*"[^>]*>', + r']*class="[^"]*modal[^"]*"[^>]*>', + r']*class="[^"]*overlay[^"]*"[^>]*>', + r']*class="[^"]*interstitial[^"]*"[^>]*>', + r']*class="[^"]*native[^"]*"[^>]*>', + r']*class="[^"]*sponsor[^"]*"[^>]*>', + r'data-ad-client="[^"]*"', + r'data-ad-slot="[^"]*"' + ] + + for element_pattern in ad_elements: + matches = re.findall(element_pattern, page_content, re.IGNORECASE) + if matches: + ad_type = self._classify_ad_element_type(element_pattern) + detected_ads.append({ + "type": ad_type, + "source": "html_element", + "count": len(matches) + }) + logger.info(f" 🔍 检测到 {ad_type} 元素: {len(matches)} 个") + + return detected_ads + + def _classify_ad_type(self, script_pattern): + """根据脚本模式分类广告类型""" + type_mapping = { + "googlesyndication": "Google AdSense", + "doubleclick": "Google DoubleClick", + "googletagmanager": "Google Tag Manager", + "facebook": "Facebook Pixel", + "monetag": "MonetTag", + "amazon-adsystem": "Amazon Associates", + "popads": "PopAds", + "propellerads": "PropellerAds", + "adsterra": "Adsterra", + "exoclick": "ExoClick", + "clickadu": "ClickAdu", + "hilltopads": "HilltopAds", + "revcontent": "RevContent", + "outbrain": "Outbrain", + "taboola": "Taboola", + "mgid": "MGID" + } + + for key, value in type_mapping.items(): + if key in script_pattern: + return value + + return "Unknown Ad Network" + + def _classify_ad_element_type(self, element_pattern): + """根据元素模式分类广告类型""" + if "banner" in element_pattern: + return "banner_display" + elif "popup" in element_pattern or "modal" in element_pattern or "overlay" in element_pattern: + return "popup_modal" + elif "interstitial" in element_pattern: + return "interstitial_fullscreen" + elif "native" in element_pattern or "sponsor" in element_pattern: + return "native_content" + elif "adsbygoogle" in element_pattern or "data-ad" in element_pattern: + return "google_adsense" + else: + return "generic_ad" + + def _process_detected_ads(self, base_url, detected_ads, total_time): + """处理检测到的广告""" + logger.info(f"📺 开始处理检测到的广告") + + # 为每个广告分配处理时间 + ad_count = len(detected_ads) + time_per_ad = total_time / max(ad_count, 1) + + for i, ad in enumerate(detected_ads): + ad_type = ad["type"] + ad_count = ad["count"] + + logger.info(f"🎯 处理广告 {i+1}/{len(detected_ads)}: {ad_type} ({ad_count}个)") + + # 根据广告类型选择处理策略 + if ad_type in ["popup_modal", "interstitial_fullscreen"]: + self._handle_popup_interstitial_ads(base_url, ad_type, time_per_ad) + elif ad_type in ["banner_display", "google_adsense"]: + self._handle_banner_display_ads(base_url, ad_type, time_per_ad) + elif ad_type in ["native_content"]: + self._handle_native_content_ads(base_url, ad_type, time_per_ad) + else: + self._handle_generic_ads(base_url, ad_type, time_per_ad) + + # 更新统计 + if ad_type not in self.visit_stats["ad_types_found"]: + self.visit_stats["ad_types_found"][ad_type] = 0 + self.visit_stats["ad_types_found"][ad_type] += ad_count + + def _handle_popup_interstitial_ads(self, base_url, ad_type, allocated_time): + """处理弹窗和插页广告""" + logger.info(f" 📺 处理弹窗/插页广告: {ad_type}") + + # 模拟广告显示延迟 + display_delay = random.uniform(1, 4) + logger.info(f" 🔄 广告显示延迟: {display_delay:.1f}秒") + time.sleep(display_delay) + + # 模拟用户反应 + reaction_time = random.uniform(0.5, 2) + logger.info(f" 👀 用户反应时间: {reaction_time:.1f}秒") + time.sleep(reaction_time) + + # 决定用户行为 + behavior = self.ad_behaviors.get("popup_modal", self.ad_behaviors["popup_modal"]) + user_action = self._decide_user_action_for_ad(behavior) + + # 执行行为 + if user_action == "close": + self._simulate_close_popup(base_url, ad_type) + elif user_action == "click": + self._simulate_click_popup(base_url, ad_type) + else: + self._simulate_ignore_popup(base_url, ad_type) + + def _handle_banner_display_ads(self, base_url, ad_type, allocated_time): + """处理横幅显示广告""" + logger.info(f" 📺 处理横幅广告: {ad_type}") + + # 模拟广告加载 + load_time = random.uniform(0.5, 2) + logger.info(f" 📥 广告加载时间: {load_time:.1f}秒") + time.sleep(load_time) + + # 模拟用户浏览时注意到广告 + notice_time = random.uniform(2, 6) + logger.info(f" 👁️ 用户注意到广告: {notice_time:.1f}秒") + time.sleep(notice_time) + + # 决定用户行为 + behavior = self.ad_behaviors.get("banner_display", self.ad_behaviors["banner_display"]) + user_action = self._decide_user_action_for_ad(behavior) + + # 执行行为 + if user_action == "close": + self._simulate_close_banner(base_url, ad_type) + elif user_action == "click": + self._simulate_click_banner(base_url, ad_type) + else: + self._simulate_ignore_banner(base_url, ad_type) + + def _handle_native_content_ads(self, base_url, ad_type, allocated_time): + """处理原生内容广告""" + logger.info(f" 📺 处理原生广告: {ad_type}") + + # 模拟用户阅读内容时发现广告 + read_time = random.uniform(3, 8) + logger.info(f" 📖 用户阅读发现广告: {read_time:.1f}秒") + time.sleep(read_time) + + # 决定用户行为 + behavior = self.ad_behaviors.get("native_content", self.ad_behaviors["native_content"]) + user_action = self._decide_user_action_for_ad(behavior) + + # 执行行为 + if user_action == "close": + self._simulate_close_native(base_url, ad_type) + elif user_action == "click": + self._simulate_click_native(base_url, ad_type) + elif user_action == "read": + self._simulate_read_native(base_url, ad_type) + else: + self._simulate_ignore_native(base_url, ad_type) + + def _handle_generic_ads(self, base_url, ad_type, allocated_time): + """处理通用广告""" + logger.info(f" 📺 处理通用广告: {ad_type}") + + # 模拟通用广告行为 + generic_time = random.uniform(2, 6) + logger.info(f" 🎯 通用广告交互: {generic_time:.1f}秒") + time.sleep(generic_time) + + # 随机决定行为 + if random.random() < 0.75: # 75%概率关闭 + self._simulate_close_generic(base_url, ad_type) + elif random.random() < 0.15: # 15%概率点击 + self._simulate_click_generic(base_url, ad_type) + else: # 10%概率忽略 + self._simulate_ignore_generic(base_url, ad_type) + + def _decide_user_action_for_ad(self, behavior): + """决定用户对广告的行为""" + # 考虑时间因素 + time_factor = self._get_time_tolerance_factor() + + # 调整概率 + close_prob = behavior["close_probability"] * time_factor + click_prob = behavior["click_probability"] + + # 随机决定 + rand = random.random() + + if rand < close_prob: + return "close" + elif rand < close_prob + click_prob: + return "click" + elif "read_probability" in behavior and rand < close_prob + click_prob + behavior["read_probability"]: + return "read" + else: + return "ignore" + + def _get_time_tolerance_factor(self): + """获取时间容忍度因子""" + current_hour = time.localtime().tm_hour + + if 9 <= current_hour <= 18: # 工作时间 + return 1.2 # 更讨厌广告 + elif 19 <= current_hour <= 23: # 休闲时间 + return 0.8 # 相对容忍 + else: # 深夜 + return 1.0 # 普通 + + def _simulate_close_popup(self, base_url, ad_type): + """模拟关闭弹窗广告""" + logger.info(f" ❌ 关闭弹窗广告") + + # 寻找关闭按钮 + find_time = random.uniform(0.5, 2) + logger.info(f" 🔍 寻找关闭按钮: {find_time:.1f}秒") + time.sleep(find_time) + + # 点击关闭 + click_time = random.uniform(0.2, 0.8) + logger.info(f" 🖱️ 点击关闭按钮") + time.sleep(click_time) + + # 发送关闭请求 + self._send_ad_interaction_request(base_url, ad_type, "close") + + # 更新统计 + self.visit_stats["ad_interactions"]["close_button_clicks"] += 1 + + # 关闭后释放 + relief_time = random.uniform(0.5, 1.5) + logger.info(f" 😌 关闭后释放: {relief_time:.1f}秒") + time.sleep(relief_time) + + def _simulate_click_popup(self, base_url, ad_type): + """模拟点击弹窗广告""" + logger.info(f" 🖱️ 点击弹窗广告") + + # 思考时间 + think_time = random.uniform(1, 3) + logger.info(f" 🤔 思考时间: {think_time:.1f}秒") + time.sleep(think_time) + + # 点击广告 + click_time = random.uniform(0.3, 1) + time.sleep(click_time) + + # 发送点击请求 + self._send_ad_interaction_request(base_url, ad_type, "click") + + # 更新统计 + self.visit_stats["ad_interactions"]["ad_content_clicks"] += 1 + + # 点击后可能返回 + if random.random() < 0.7: + return_time = random.uniform(1, 3) + logger.info(f" 🔙 快速返回: {return_time:.1f}秒") + time.sleep(return_time) + + def _simulate_ignore_popup(self, base_url, ad_type): + """模拟忽略弹窗广告""" + logger.info(f" 🙈 忽略弹窗广告") + + ignore_time = random.uniform(2, 5) + logger.info(f" 😐 忽略时间: {ignore_time:.1f}秒") + time.sleep(ignore_time) + + # 更新统计 + self.visit_stats["ad_interactions"]["ignored_ads"] += 1 + + def _simulate_close_banner(self, base_url, ad_type): + """模拟关闭横幅广告""" + logger.info(f" ❌ 关闭横幅广告") + + # 寻找关闭按钮 + find_time = random.uniform(0.3, 1.5) + logger.info(f" 🔍 寻找关闭按钮: {find_time:.1f}秒") + time.sleep(find_time) + + # 点击关闭 + click_time = random.uniform(0.2, 0.6) + logger.info(f" 🖱️ 点击关闭按钮") + time.sleep(click_time) + + # 发送关闭请求 + self._send_ad_interaction_request(base_url, ad_type, "close") + + # 更新统计 + self.visit_stats["ad_interactions"]["close_button_clicks"] += 1 + + def _simulate_click_banner(self, base_url, ad_type): + """模拟点击横幅广告""" + logger.info(f" 🖱️ 点击横幅广告") + + # 点击广告 + click_time = random.uniform(0.5, 1.5) + time.sleep(click_time) + + # 发送点击请求 + self._send_ad_interaction_request(base_url, ad_type, "click") + + # 更新统计 + self.visit_stats["ad_interactions"]["ad_content_clicks"] += 1 + + def _simulate_ignore_banner(self, base_url, ad_type): + """模拟忽略横幅广告""" + logger.info(f" 🙈 忽略横幅广告") + + ignore_time = random.uniform(1, 3) + time.sleep(ignore_time) + + # 更新统计 + self.visit_stats["ad_interactions"]["ignored_ads"] += 1 + + def _simulate_close_native(self, base_url, ad_type): + """模拟关闭原生广告""" + logger.info(f" ❌ 关闭原生广告") + + # 原生广告关闭按钮通常较小 + find_time = random.uniform(1, 3) + logger.info(f" 🔍 寻找关闭按钮: {find_time:.1f}秒") + time.sleep(find_time) + + # 点击关闭 + click_time = random.uniform(0.3, 1) + logger.info(f" 🖱️ 点击关闭按钮") + time.sleep(click_time) + + # 发送关闭请求 + self._send_ad_interaction_request(base_url, ad_type, "close") + + # 更新统计 + self.visit_stats["ad_interactions"]["close_button_clicks"] += 1 + + def _simulate_click_native(self, base_url, ad_type): + """模拟点击原生广告""" + logger.info(f" 🖱️ 点击原生广告") + + # 原生广告点击前通常会多思考 + think_time = random.uniform(3, 6) + logger.info(f" 🤔 思考时间: {think_time:.1f}秒") + time.sleep(think_time) + + # 点击广告 + click_time = random.uniform(0.5, 1.5) + time.sleep(click_time) + + # 发送点击请求 + self._send_ad_interaction_request(base_url, ad_type, "click") + + # 更新统计 + self.visit_stats["ad_interactions"]["ad_content_clicks"] += 1 + + def _simulate_read_native(self, base_url, ad_type): + """模拟阅读原生广告""" + logger.info(f" 📖 阅读原生广告") + + # 阅读时间 + read_time = random.uniform(5, 12) + logger.info(f" 📚 阅读时间: {read_time:.1f}秒") + time.sleep(read_time) + + # 阅读后可能点击 + if random.random() < 0.3: + self._simulate_click_native(base_url, ad_type) + + def _simulate_ignore_native(self, base_url, ad_type): + """模拟忽略原生广告""" + logger.info(f" 🙈 忽略原生广告") + + ignore_time = random.uniform(2, 4) + time.sleep(ignore_time) + + # 更新统计 + self.visit_stats["ad_interactions"]["ignored_ads"] += 1 + + def _simulate_close_generic(self, base_url, ad_type): + """模拟关闭通用广告""" + logger.info(f" ❌ 关闭通用广告") + + close_time = random.uniform(1, 3) + logger.info(f" 🖱️ 关闭操作: {close_time:.1f}秒") + time.sleep(close_time) + + # 发送关闭请求 + self._send_ad_interaction_request(base_url, ad_type, "close") + + # 更新统计 + self.visit_stats["ad_interactions"]["close_button_clicks"] += 1 + + def _simulate_click_generic(self, base_url, ad_type): + """模拟点击通用广告""" + logger.info(f" 🖱️ 点击通用广告") + + click_time = random.uniform(1, 2) + time.sleep(click_time) + + # 发送点击请求 + self._send_ad_interaction_request(base_url, ad_type, "click") + + # 更新统计 + self.visit_stats["ad_interactions"]["ad_content_clicks"] += 1 + + def _simulate_ignore_generic(self, base_url, ad_type): + """模拟忽略通用广告""" + logger.info(f" 🙈 忽略通用广告") + + ignore_time = random.uniform(2, 4) + time.sleep(ignore_time) + + # 更新统计 + self.visit_stats["ad_interactions"]["ignored_ads"] += 1 + + def _simulate_generic_ad_behavior(self, base_url, total_time): + """模拟通用广告行为(当未检测到具体广告时)""" + logger.info(f"🎯 执行通用广告行为模拟") + + # 模拟可能存在但未检测到的广告 + possible_ads = ["弹窗广告", "横幅广告", "原生广告", "视频广告"] + + segments = random.randint(2, 4) + segment_time = total_time / segments + + for i in range(segments): + ad_type = random.choice(possible_ads) + logger.info(f" 🎯 模拟 {ad_type} 行为") + + # 模拟广告加载和交互 + load_time = random.uniform(1, 3) + logger.info(f" 📥 广告加载: {load_time:.1f}秒") + time.sleep(load_time) + + # 模拟用户行为 + if random.random() < 0.75: # 75%概率关闭 + logger.info(f" ❌ 关闭{ad_type}") + self._send_ad_interaction_request(base_url, ad_type, "close") + self.visit_stats["ad_interactions"]["close_button_clicks"] += 1 + elif random.random() < 0.15: # 15%概率点击 + logger.info(f" 🖱️ 点击{ad_type}") + self._send_ad_interaction_request(base_url, ad_type, "click") + self.visit_stats["ad_interactions"]["ad_content_clicks"] += 1 + else: # 10%概率忽略 + logger.info(f" 🙈 忽略{ad_type}") + self.visit_stats["ad_interactions"]["ignored_ads"] += 1 + + # 行为间隔 + time.sleep(segment_time - load_time) + + def _send_ad_interaction_request(self, base_url, ad_type, action): + """发送广告交互请求""" + try: + # 模拟广告交互API请求 + endpoints = [ + f"/api/ads/{action}", + f"/ads/{action}", + f"/tracking/ad_{action}", + f"/analytics/ad_interaction", + f"/stats/ad_{action}" + ] + + endpoint = random.choice(endpoints) + parsed_url = urlparse(base_url) + request_url = f"{parsed_url.scheme}://{parsed_url.netloc}{endpoint}" + + headers = self.session.headers.copy() + headers.update({ + "X-Requested-With": "XMLHttpRequest", + "Content-Type": "application/json", + "Referer": base_url, + }) + + payload = { + "ad_type": ad_type, + "action": action, + "timestamp": int(time.time()), + "user_agent": self.session.headers.get("User-Agent", ""), + "page_url": base_url + } + + response = self.session.post(request_url, headers=headers, + json=payload, timeout=5) + + logger.info(f" 📤 广告交互请求: {endpoint} ({response.status_code})") + + except Exception as e: + logger.debug(f" ⚠️ 广告交互请求失败: {e}") + + def _log_universal_ad_stats(self): + """记录通用广告统计""" + logger.info("📊 智能广告检测和交互统计:") + logger.info(f" 🔍 检测到广告: {self.visit_stats['ad_interactions']['detected_ads']} 个") + logger.info(f" ❌ 关闭按钮点击: {self.visit_stats['ad_interactions']['close_button_clicks']} 次") + logger.info(f" 🖱️ 广告内容点击: {self.visit_stats['ad_interactions']['ad_content_clicks']} 次") + logger.info(f" 🙈 忽略广告: {self.visit_stats['ad_interactions']['ignored_ads']} 次") + + if self.visit_stats["ad_types_found"]: + logger.info(" 🎯 发现的广告类型:") + for ad_type, count in self.visit_stats["ad_types_found"].items(): + logger.info(f" - {ad_type}: {count} 个") + + def browse_games_with_ads(self): + """浏览游戏页面并处理广告""" + main_site = self.config['targets']['main_site'] + base_url = main_site.rstrip('/') + + games_to_browse = random.randint(2, 4) + selected_games = random.sample(self.games_list, min(games_to_browse, len(self.games_list))) + + logger.info(f"🎮 浏览 {games_to_browse} 个游戏页面") + + for i, game in enumerate(selected_games): + game_url = base_url + game["url"] + + try: + logger.info(f"🎯 游戏 {i+1}/{games_to_browse}: {game['name']}") + + # 设置referrer + if i == 0: + self.session.headers.update({'Referer': main_site}) + else: + prev_game_url = base_url + selected_games[i-1]["url"] + self.session.headers.update({'Referer': prev_game_url}) + + # 访问游戏页面 + response = self.session.get(game_url, timeout=15) + + if response.status_code == 200: + logger.info(f"✅ 游戏页面访问成功") + + # 智能检测和处理游戏页面广告 + self._handle_game_page_ads(response, game) + + else: + logger.warning(f"⚠️ 游戏页面访问失败 ({response.status_code})") + + # 页面间延迟 + if i < len(selected_games) - 1: + delay = random.uniform(3, 8) + logger.info(f" ⏳ 页面切换延迟: {delay:.1f}秒") + time.sleep(delay) + + except Exception as e: + logger.error(f"游戏页面访问出错: {e}") + continue + + return True + + def _handle_game_page_ads(self, response, game): + """处理游戏页面的广告""" + game_stay_time = random.uniform(30, 90) + logger.info(f" 🎮 游戏页面停留: {game_stay_time:.1f}秒") + + # 检测游戏页面广告 + detected_ads = self._detect_ads_in_page(response.text) + + if detected_ads: + logger.info(f" 🔍 游戏页面检测到 {len(detected_ads)} 个广告") + + # 模拟游戏前广告 + if random.random() < 0.8: # 80%概率有游戏前广告 + logger.info(f" 📺 游戏前广告处理") + if random.random() < 0.7: # 70%概率跳过 + logger.info(f" ⏭️ 跳过游戏前广告") + self.visit_stats["ad_interactions"]["close_button_clicks"] += 1 + time.sleep(random.uniform(1, 3)) + else: + logger.info(f" ✅ 观看游戏前广告") + time.sleep(random.uniform(5, 15)) + + # 模拟游戏过程 + self._simulate_game_play(game, game_stay_time * 0.6) + + # 模拟游戏中广告 + if random.random() < 0.6: # 60%概率有游戏中广告 + logger.info(f" 📺 游戏中广告处理") + if random.random() < 0.8: # 80%概率关闭 + logger.info(f" ❌ 关闭游戏中广告") + self.visit_stats["ad_interactions"]["close_button_clicks"] += 1 + time.sleep(random.uniform(1, 2)) + else: + time.sleep(random.uniform(3, 8)) + + # 模拟游戏结束广告 + if random.random() < 0.9: # 90%概率有结束广告 + logger.info(f" 📺 游戏结束广告处理") + if random.random() < 0.5: # 50%概率关闭 + logger.info(f" ❌ 关闭游戏结束广告") + self.visit_stats["ad_interactions"]["close_button_clicks"] += 1 + time.sleep(random.uniform(1, 2)) + elif random.random() < 0.3: # 30%概率点击 + logger.info(f" 🖱️ 点击游戏结束广告") + self.visit_stats["ad_interactions"]["ad_content_clicks"] += 1 + time.sleep(random.uniform(2, 5)) + else: + logger.info(f" ✅ 观看游戏结束广告") + time.sleep(random.uniform(5, 15)) + else: + # 没有检测到广告,正常游戏 + logger.info(f" 🎮 正常游戏,未检测到广告") + self._simulate_game_play(game, game_stay_time) + + def _simulate_game_play(self, game, duration): + """模拟游戏过程""" + logger.info(f" 🎮 开始游戏: {game['name']}") + + # 根据游戏类型模拟不同行为 + if game["category"] == "puzzle": + actions = ["思考", "移动", "尝试", "撤销"] + segments = random.randint(4, 8) + elif game["category"] == "arcade": + actions = ["开始", "快速操作", "躲避", "收集"] + segments = random.randint(6, 12) + else: + actions = ["开始", "操作", "进行", "暂停"] + segments = random.randint(3, 6) + + segment_time = duration / segments + + for i in range(segments): + action = random.choice(actions) + logger.info(f" 🎯 {action}") + time.sleep(segment_time * random.uniform(0.8, 1.2)) + + def run_universal_ad_visit(self): + """执行通用广告访问流程""" + logger.info("🚀 开始通用广告访问流程") + + # 设置会话 + self.setup_session() + + try: + # 1. 模拟来源访问 + if not self.simulate_traffic_source(): + logger.warning("⚠️ 来源访问失败,继续执行") + + # 2. 访问首页并智能处理广告 + if not self.visit_homepage_with_universal_ads(): + logger.error("❌ 首页广告访问失败") + return False + + # 3. 浏览游戏页面 + if not self.browse_games_with_ads(): + logger.error("❌ 游戏页面访问失败") + return False + + # 更新统计 + self.visit_stats["total_visits"] += 1 + + logger.info("✅ 通用广告访问流程完成!") + return True + + except Exception as e: + logger.error(f"❌ 访问流程出错: {e}") + return False + + finally: + if self.session: + self.session.close() + + def run_continuous_universal_visits(self, total_visits=None, delay_range=None): + """连续执行通用广告访问""" + if total_visits is None: + total_visits = self.config['settings']['default_visits'] + + if delay_range is None: + delay_range = ( + self.config['settings']['min_delay'], + self.config['settings']['max_delay'] + ) + + success_count = 0 + + logger.info(f"🎯 开始连续通用广告访问,目标: {total_visits} 次") + + for i in range(total_visits): + logger.info(f"{'='*70}") + logger.info(f"🔄 第 {i+1}/{total_visits} 次通用广告访问") + logger.info(f"{'='*70}") + + visit_start_time = time.time() + + if self.run_universal_ad_visit(): + success_count += 1 + visit_time = time.time() - visit_start_time + + logger.info(f"✅ 第 {i+1} 次访问成功!耗时: {visit_time:.1f}秒") + + # 显示累计统计 + logger.info(f"📊 累计: 成功{success_count}, 检测广告{self.visit_stats['ad_interactions']['detected_ads']}, 关闭{self.visit_stats['ad_interactions']['close_button_clicks']}, 点击{self.visit_stats['ad_interactions']['ad_content_clicks']}") + else: + logger.error(f"❌ 第 {i+1} 次访问失败!") + + # 访问间隔 + if i < total_visits - 1: + delay = random.uniform(delay_range[0], delay_range[1]) + logger.info(f"⏳ 等待 {delay:.1f} 秒") + time.sleep(delay) + + # 最终统计 + self._print_final_universal_stats(success_count, total_visits) + + return success_count + + def _print_final_universal_stats(self, success_count, total_visits): + """打印最终统计信息""" + success_rate = (success_count / total_visits) * 100 + + logger.info(f"🎉 通用广告访问任务完成!") + logger.info(f"📊 访问统计:") + logger.info(f" 成功率: {success_count}/{total_visits} ({success_rate:.1f}%)") + logger.info(f" 检测广告总数: {self.visit_stats['ad_interactions']['detected_ads']}") + logger.info(f" 关闭按钮点击: {self.visit_stats['ad_interactions']['close_button_clicks']}") + logger.info(f" 广告内容点击: {self.visit_stats['ad_interactions']['ad_content_clicks']}") + logger.info(f" 忽略广告: {self.visit_stats['ad_interactions']['ignored_ads']}") + + total_interactions = (self.visit_stats['ad_interactions']['close_button_clicks'] + + self.visit_stats['ad_interactions']['ad_content_clicks'] + + self.visit_stats['ad_interactions']['ignored_ads']) + + if total_interactions > 0: + close_rate = (self.visit_stats['ad_interactions']['close_button_clicks'] / total_interactions) * 100 + click_rate = (self.visit_stats['ad_interactions']['ad_content_clicks'] / total_interactions) * 100 + ignore_rate = (self.visit_stats['ad_interactions']['ignored_ads'] / total_interactions) * 100 + + logger.info(f" 📈 用户行为分析:") + logger.info(f" 关闭率: {close_rate:.1f}%") + logger.info(f" 点击率: {click_rate:.1f}%") + logger.info(f" 忽略率: {ignore_rate:.1f}%") + + if self.visit_stats["ad_types_found"]: + logger.info(f" 🎯 发现的广告类型:") + for ad_type, count in self.visit_stats["ad_types_found"].items(): + logger.info(f" - {ad_type}: {count} 个") + + logger.info(f"💡 智能识别: 自动适应各种广告网络和类型") + +def main(): + """主函数""" + config_file = 'config.json' + + if not os.path.exists(config_file): + print(f"❌ 配置文件 {config_file} 不存在!") + return + + try: + bot = UniversalAdBot(config_file) + + print("=" * 80) + print("🎯 通用广告刷量机器人 (智能识别版)") + print("=" * 80) + print("💡 核心特性:") + print(" 🔍 智能广告识别 - 自动检测各种广告类型") + print(" 🎭 真实用户行为 - 75%概率讨厌广告") + print(" ❌ 智能关闭按钮 - 自动寻找并点击关闭按钮") + print(" 📱 移动端优先 - 85%概率使用移动设备") + print(" 🌐 通用适配 - 适用于任何广告网络") + print(" 📊 详细统计 - 检测率、关闭率、点击率") + print(" ⚠️ 请确保仅用于测试自己的网站!") + print() + print(f"🎯 目标网站: {bot.config['targets']['main_site']}") + print(f"🔍 支持广告网络: Google AdSense, MonetTag, PropellerAds 等") + print(f"😤 用户讨厌广告: 75%概率") + print() + + print("请选择运行模式:") + print("1. 💎 单次通用广告访问测试") + print("2. 🚀 连续通用广告访问 (使用配置参数)") + print("3. ⚙️ 自定义连续通用广告访问") + + choice = input("请输入选择 (1/2/3): ").strip() + + if choice == "1": + logger.info("🎬 开始单次通用广告访问测试") + success = bot.run_universal_ad_visit() + if success: + print("🎉 单次通用广告访问测试成功!") + else: + print("😞 单次通用广告访问测试失败!") + + elif choice == "2": + logger.info("🎬 开始连续通用广告访问") + success_count = bot.run_continuous_universal_visits() + total = bot.config['settings']['default_visits'] + print(f"🎉 连续通用广告访问完成!成功: {success_count}/{total}") + + elif choice == "3": + try: + visit_count = int(input("请输入访问次数: ").strip()) + min_delay = int(input("请输入最小延迟秒数: ").strip()) + max_delay = int(input("请输入最大延迟秒数: ").strip()) + + logger.info(f"🎬 开始自定义通用广告访问,次数: {visit_count}") + success_count = bot.run_continuous_universal_visits( + total_visits=visit_count, + delay_range=(min_delay, max_delay) + ) + + print(f"🎉 自定义通用广告访问完成!成功: {success_count}/{visit_count}") + + except ValueError: + print("❌ 输入参数错误!") + else: + print("❌ 无效选择!") + + except KeyboardInterrupt: + print("\n⚠️ 用户中断执行") + except Exception as e: + logger.error(f"程序执行出错: {e}") + print("❌ 程序执行出错,请查看日志文件 universal_ad_bot.log") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/website_traffic_ad_bot.py b/website_traffic_ad_bot.py new file mode 100644 index 0000000..6f74e6a --- /dev/null +++ b/website_traffic_ad_bot.py @@ -0,0 +1,723 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +网站刷量广告机器人 (专业版) +专门用于刷量和广告互动 +针对Fun Games Hub网站优化 +""" + +import requests +import time +import random +import json +import os +import logging +from urllib.parse import urlparse, urljoin +import re +from real_user_database import RealUserDatabase + +# 配置日志 +logging.basicConfig( + level=logging.INFO, + format='%(asctime)s - %(levelname)s - %(message)s', + handlers=[ + logging.FileHandler('ad_bot.log', encoding='utf-8'), + logging.StreamHandler() + ] +) +logger = logging.getLogger(__name__) + +class WebsiteAdBot: + def __init__(self, config_file='config.json'): + """ + 初始化广告刷量机器人 + """ + self.config = self.load_config(config_file) + self.session = None + self.user_db = RealUserDatabase() + self.current_profile = None + self.current_behavior = None + + # 🎮 基于网站截图的真实游戏列表 + self.games_list = [ + {"name": "2048", "url": "/games/2048/index.html", "category": "puzzle"}, + {"name": "Snake", "url": "/games/snake/index.html", "category": "arcade"}, + {"name": "DIY Doll", "url": "/games/diy-doll/index.html", "category": "puzzle"}, + {"name": "Sprunki", "url": "/games/sprunki/index.html", "category": "arcade"}, + {"name": "FlightBird", "url": "/games/flightbird/index.html", "category": "action"}, + {"name": "Diy Doll Factory", "url": "/games/iframe-games.html?game=diy-doll-factory", "category": "puzzle"}, + {"name": "Super Sprunki Adventure", "url": "/games/iframe-games.html?game=super-sprunki-adventure", "category": "action"}, + ] + + # 🎯 游戏分类列表 + self.game_categories = [ + {"name": "Puzzle", "games": 4}, + {"name": "Arcade", "games": 3}, + {"name": "Action", "games": 2}, + {"name": "Strategy", "games": 1}, + {"name": "All", "games": 10} + ] + + # 🎯 真实的访问来源(针对游戏网站) + self.game_traffic_sources = [ + # 游戏相关搜索 + "https://www.google.com/search?q=free+online+games", + "https://www.google.com/search?q=2048+game+play+online", + "https://www.google.com/search?q=snake+game+browser", + "https://www.google.com/search?q=puzzle+games+online+free", + "https://www.google.com/search?q=fun+games+hub", + "https://www.google.com/search?q=html5+games+no+download", + "https://www.google.com/search?q=browser+games+2024", + + # 游戏社区来源 + "https://www.reddit.com/r/WebGames/", + "https://www.reddit.com/r/incremental_games/", + "https://news.ycombinator.com/", + "https://www.producthunt.com/", + "https://github.com/topics/game", + "https://github.com/topics/html5-game", + + # 中文游戏搜索 + "https://www.google.com/search?q=在线小游戏", + "https://www.google.com/search?q=免费网页游戏", + "https://www.google.com/search?q=2048数字游戏", + "https://www.baidu.com/s?wd=网页小游戏", + "https://www.baidu.com/s?wd=在线游戏平台", + ] + + def load_config(self, config_file): + """加载配置文件""" + try: + with open(config_file, 'r', encoding='utf-8') as f: + config = json.load(f) + logger.info(f"配置文件加载成功: {config_file}") + return config + except FileNotFoundError: + logger.error(f"配置文件未找到: {config_file}") + raise + except json.JSONDecodeError as e: + logger.error(f"配置文件格式错误: {e}") + raise + + def setup_session(self): + """设置请求会话 - 广告友好版""" + self.session = requests.Session() + self.session.cookies.clear() + + # 生成真实用户配置 + self.current_profile = self.user_db.get_random_user_profile() + self.current_behavior = self.user_db.get_visit_behavior() + + # 设置代理 + proxy_config = self.config.get('proxy') + if proxy_config: + proxy_url = f"http://{proxy_config['username']}:{proxy_config['password']}@{proxy_config['host']}:{proxy_config['port']}" + self.session.proxies = { + 'http': proxy_url, + 'https': proxy_url + } + logger.info(f"已配置代理: {proxy_config['host']}:{proxy_config['port']}") + + # 🎯 广告友好的用户代理 - 移动端为主 + if random.random() < 0.8: # 80%概率使用移动端(广告收益更高) + mobile_agents = [ + "Mozilla/5.0 (iPhone; CPU iPhone OS 17_1_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.1 Mobile/15E148 Safari/604.1", + "Mozilla/5.0 (iPhone; CPU iPhone OS 16_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1", + "Mozilla/5.0 (Linux; Android 14; SM-G991B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36", + "Mozilla/5.0 (Linux; Android 13; SM-A515F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Mobile Safari/537.36", + "Mozilla/5.0 (iPad; CPU OS 17_1_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.1 Mobile/15E148 Safari/604.1", + ] + user_agent = random.choice(mobile_agents) + is_mobile = True + else: + user_agent = self.current_profile["user_agent"] + is_mobile = "Mobile" in user_agent + + # 完整的广告友好头部 + headers = { + "User-Agent": user_agent, + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8", + "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6", + "Accept-Encoding": "gzip, deflate, br", + "Connection": "keep-alive", + "Upgrade-Insecure-Requests": "1", + "Sec-Fetch-Dest": "document", + "Sec-Fetch-Mode": "navigate", + "Sec-Fetch-Site": "none", + "Sec-Fetch-User": "?1", + "Cache-Control": "max-age=0", + "DNT": "0", # 不启用DNT,对广告友好 + "Pragma": "no-cache", + } + + # 移动端特殊头部 + if is_mobile: + headers.update({ + "Sec-CH-UA-Mobile": "?1", + "Viewport-Width": str(random.choice([375, 414, 390, 393, 412])), + "Device-Memory": str(random.choice([4, 6, 8])), + }) + + self.session.headers.update(headers) + + logger.info(f"🎭 广告机器人配置:") + logger.info(f" 📱 User-Agent: {user_agent}") + logger.info(f" 📱 移动端模式: {is_mobile}") + logger.info(f" 🎯 访问模式: {self.current_behavior['pattern_type']}") + + # 获取当前IP + current_ip = self.get_current_ip() + if current_ip: + print(f"🌍 当前IP: {current_ip}") + print(f"🎯 广告刷量模式: 移动端={is_mobile}, 模式={self.current_behavior['pattern_type']}") + + def get_current_ip(self): + """获取当前IP地址""" + try: + response = self.session.get('https://httpbin.org/ip', timeout=10) + if response.status_code == 200: + data = response.json() + return data.get('origin', 'Unknown') + except: + pass + return None + + def simulate_traffic_source(self): + """模拟真实的游戏网站访问来源""" + source = random.choice(self.game_traffic_sources) + + try: + logger.info(f"🔗 模拟从游戏相关来源访问: {source}") + + # 根据来源类型设置不同的停留时间 + if "google.com" in source or "baidu.com" in source: + stay_time = random.uniform(2, 8) # 搜索引擎停留较短 + logger.info(f"🔍 搜索引擎停留: {stay_time:.1f}秒") + elif "reddit.com" in source: + stay_time = random.uniform(8, 20) # Reddit停留较长 + logger.info(f"🔍 Reddit社区停留: {stay_time:.1f}秒") + elif "github.com" in source: + stay_time = random.uniform(5, 15) # GitHub中等停留 + logger.info(f"🔍 GitHub停留: {stay_time:.1f}秒") + else: + stay_time = random.uniform(3, 12) # 其他网站 + logger.info(f"🔍 其他来源停留: {stay_time:.1f}秒") + + # 模拟来源网站行为 + self._simulate_source_behavior(stay_time) + + # 设置referrer + self.session.headers.update({ + 'Referer': source, + 'Sec-Fetch-Site': 'cross-site' + }) + + return True + + except Exception as e: + logger.error(f"来源访问模拟失败: {e}") + return False + + def _simulate_source_behavior(self, total_time): + """模拟在来源网站的行为""" + actions = [ + "浏览搜索结果", + "阅读页面内容", + "查看相关链接", + "滚动浏览页面", + "点击相关内容" + ] + + segments = random.randint(2, 4) + segment_time = total_time / segments + + for i in range(segments): + if i > 0: + time.sleep(random.uniform(0.5, 2)) + + action = random.choice(actions) + logger.info(f" 🔍 {action}") + time.sleep(segment_time * random.uniform(0.7, 1.3)) + + def visit_homepage_with_ads(self): + """访问首页并重点关注广告""" + main_site = self.config['targets']['main_site'] + + try: + logger.info(f"🏠 访问首页并关注广告: {main_site}") + + # 人工延迟 + pre_delay = random.uniform(3, 7) + logger.info(f"🕐 访问前延迟: {pre_delay:.1f}秒") + time.sleep(pre_delay) + + # 发起请求 + response = self.session.get(main_site, timeout=20, allow_redirects=True) + + if response.status_code == 200: + logger.info(f"✅ 首页访问成功 ({response.status_code})") + logger.info(f"📦 页面大小: {len(response.content)} 字节") + + # 🎯 专注于首页停留和广告交互 + self._simulate_homepage_ad_interaction(response) + + return True + else: + logger.error(f"❌ 首页访问失败 ({response.status_code})") + return False + + except Exception as e: + logger.error(f"首页访问出错: {e}") + return False + + def _simulate_homepage_ad_interaction(self, response): + """模拟首页广告交互""" + base_url = response.url + + # 🎯 首页深度停留 - 广告需要更长的展示时间 + homepage_stay_time = random.uniform(15, 45) # 15-45秒深度停留 + logger.info(f"🏠 首页深度停留时间: {homepage_stay_time:.1f}秒") + + # 分阶段模拟首页行为 + stages = [ + {"name": "初始加载", "duration": 0.2, "actions": ["页面加载", "渲染广告"]}, + {"name": "浏览游戏", "duration": 0.3, "actions": ["查看热门游戏", "浏览游戏分类"]}, + {"name": "广告互动", "duration": 0.3, "actions": ["查看广告", "广告展示", "可能点击"]}, + {"name": "深度探索", "duration": 0.2, "actions": ["滚动页面", "查看更多游戏"]} + ] + + for stage in stages: + stage_time = homepage_stay_time * stage["duration"] + logger.info(f"🎯 {stage['name']}阶段: {stage_time:.1f}秒") + + # 执行该阶段的行为 + action_count = len(stage["actions"]) + action_time = stage_time / action_count + + for action in stage["actions"]: + logger.info(f" 📱 {action}") + + # 特殊处理广告相关行为 + if "广告" in action: + self._simulate_ad_behavior(base_url, action_time) + else: + time.sleep(action_time * random.uniform(0.8, 1.2)) + + # 动作间随机间隔 + if random.random() < 0.7: + time.sleep(random.uniform(0.5, 2)) + + # 🎯 额外的广告专项行为 + if random.random() < 0.8: # 80%概率进行广告专项行为 + self._simulate_dedicated_ad_behavior(base_url) + + def _simulate_ad_behavior(self, base_url, duration): + """模拟广告行为""" + logger.info(f" 💰 广告行为开始,持续 {duration:.1f}秒") + + # 模拟广告加载时间 + ad_load_time = random.uniform(1, 3) + logger.info(f" 📺 广告加载: {ad_load_time:.1f}秒") + time.sleep(ad_load_time) + + # 模拟广告展示时间 + ad_display_time = duration - ad_load_time + if ad_display_time > 0: + logger.info(f" 👀 广告展示: {ad_display_time:.1f}秒") + time.sleep(ad_display_time) + + # 模拟可能的广告点击 + if random.random() < 0.15: # 15%概率点击广告 + self._simulate_ad_click(base_url) + + def _simulate_ad_click(self, base_url): + """模拟广告点击""" + logger.info(f" 🖱️ 模拟广告点击") + + # 模拟点击延迟 + click_delay = random.uniform(0.5, 2) + time.sleep(click_delay) + + # 模拟广告相关请求 + ad_endpoints = [ + "/ads/click", + "/advertising/track", + "/ad/impression", + "/analytics/ad", + "/track/click" + ] + + for endpoint in random.sample(ad_endpoints, random.randint(1, 2)): + try: + parsed_url = urlparse(base_url) + ad_url = f"{parsed_url.scheme}://{parsed_url.netloc}{endpoint}" + + ad_headers = self.session.headers.copy() + ad_headers.update({ + "X-Requested-With": "XMLHttpRequest", + "Content-Type": "application/json", + "Referer": base_url, + "Sec-Fetch-Dest": "empty", + "Sec-Fetch-Mode": "cors", + "Sec-Fetch-Site": "same-origin", + }) + + response = self.session.get(ad_url, headers=ad_headers, timeout=5) + logger.info(f" 📊 广告请求: {endpoint} ({response.status_code})") + + time.sleep(random.uniform(0.5, 1.5)) + + except Exception as e: + logger.debug(f" ⚠️ 广告请求失败 {endpoint}: {e}") + + def _simulate_dedicated_ad_behavior(self, base_url): + """专项广告行为模拟""" + logger.info(f"💰 开始专项广告行为") + + # 模拟滚动到广告位置 + scroll_time = random.uniform(2, 5) + logger.info(f" 📜 滚动到广告区域: {scroll_time:.1f}秒") + time.sleep(scroll_time) + + # 模拟在广告区域停留 + ad_focus_time = random.uniform(8, 20) + logger.info(f" 👁️ 广告区域停留: {ad_focus_time:.1f}秒") + time.sleep(ad_focus_time) + + # 模拟广告交互 + if random.random() < 0.25: # 25%概率进行广告交互 + logger.info(f" 🔄 广告交互行为") + self._simulate_ad_interaction(base_url) + + def _simulate_ad_interaction(self, base_url): + """模拟广告交互""" + interactions = [ + "悬停在广告上", + "查看广告详情", + "广告展开", + "关闭广告", + "点击广告" + ] + + selected_interactions = random.sample(interactions, random.randint(1, 3)) + + for interaction in selected_interactions: + logger.info(f" 🎯 {interaction}") + + if interaction == "点击广告": + self._simulate_ad_click(base_url) + else: + time.sleep(random.uniform(1, 4)) + + def browse_games_with_ads(self): + """浏览游戏页面并关注广告""" + main_site = self.config['targets']['main_site'] + base_url = main_site.rstrip('/') + + # 随机选择要浏览的游戏数量 + games_to_browse = random.randint(3, 6) + selected_games = random.sample(self.games_list, min(games_to_browse, len(self.games_list))) + + logger.info(f"🎮 开始浏览 {games_to_browse} 个游戏页面") + + for i, game in enumerate(selected_games): + game_url = base_url + game["url"] + + try: + logger.info(f"🎯 游戏 {i+1}/{games_to_browse}: {game['name']} ({game['category']})") + + # 设置referrer + if i == 0: + self.session.headers.update({ + 'Referer': main_site, + 'Sec-Fetch-Site': 'same-origin' + }) + else: + prev_game_url = base_url + selected_games[i-1]["url"] + self.session.headers.update({ + 'Referer': prev_game_url, + 'Sec-Fetch-Site': 'same-origin' + }) + + # 访问游戏页面 + response = self.session.get(game_url, timeout=15, allow_redirects=True) + + if response.status_code == 200: + logger.info(f"✅ 游戏页面访问成功") + + # 模拟游戏页面的广告行为 + self._simulate_game_page_ad_behavior(response, game) + + else: + logger.warning(f"⚠️ 游戏页面访问失败 ({response.status_code})") + + # 页面间切换延迟 + if i < len(selected_games) - 1: + switch_delay = random.uniform(2, 6) + logger.info(f" ⚡ 切换延迟: {switch_delay:.1f}秒") + time.sleep(switch_delay) + + except Exception as e: + logger.error(f"游戏页面访问出错: {e}") + continue + + return True + + def _simulate_game_page_ad_behavior(self, response, game): + """模拟游戏页面的广告行为""" + # 游戏页面停留时间(包含广告时间) + game_stay_time = random.uniform(20, 60) + logger.info(f" 🎮 游戏页面停留: {game_stay_time:.1f}秒") + + # 分配时间 + game_time = game_stay_time * 0.6 # 60%时间玩游戏 + ad_time = game_stay_time * 0.4 # 40%时间看广告 + + logger.info(f" 🎯 游戏时间: {game_time:.1f}秒") + logger.info(f" 💰 广告时间: {ad_time:.1f}秒") + + # 模拟游戏加载 + load_time = random.uniform(2, 5) + logger.info(f" 🔄 游戏加载: {load_time:.1f}秒") + time.sleep(load_time) + + # 模拟游戏前广告 + if random.random() < 0.7: # 70%概率有游戏前广告 + pre_ad_time = random.uniform(5, 15) + logger.info(f" 📺 游戏前广告: {pre_ad_time:.1f}秒") + time.sleep(pre_ad_time) + + # 模拟跳过广告或看完广告 + if random.random() < 0.3: # 30%概率跳过 + logger.info(f" ⏭️ 跳过广告") + time.sleep(random.uniform(1, 2)) + else: + logger.info(f" ✅ 看完广告") + + # 模拟游戏过程 + self._simulate_game_play(game, game_time) + + # 模拟游戏中广告 + if random.random() < 0.5: # 50%概率有游戏中广告 + mid_ad_time = random.uniform(3, 10) + logger.info(f" 📺 游戏中广告: {mid_ad_time:.1f}秒") + time.sleep(mid_ad_time) + + # 模拟游戏结束广告 + if random.random() < 0.8: # 80%概率有结束广告 + end_ad_time = random.uniform(5, 15) + logger.info(f" 📺 游戏结束广告: {end_ad_time:.1f}秒") + time.sleep(end_ad_time) + + def _simulate_game_play(self, game, duration): + """模拟游戏过程""" + logger.info(f" 🎮 开始游戏: {game['name']}") + + # 根据游戏类型模拟不同行为 + if game["category"] == "puzzle": + self._simulate_puzzle_game(duration) + elif game["category"] == "arcade": + self._simulate_arcade_game(duration) + elif game["category"] == "action": + self._simulate_action_game(duration) + else: + self._simulate_general_game(duration) + + def _simulate_puzzle_game(self, duration): + """模拟益智游戏""" + actions = ["思考", "移动", "尝试", "撤销", "重新开始"] + segments = random.randint(3, 6) + segment_time = duration / segments + + for i in range(segments): + action = random.choice(actions) + logger.info(f" 🧩 {action}") + time.sleep(segment_time * random.uniform(0.7, 1.3)) + + def _simulate_arcade_game(self, duration): + """模拟街机游戏""" + actions = ["开始游戏", "快速操作", "躲避", "收集", "游戏结束"] + segments = random.randint(4, 8) + segment_time = duration / segments + + for i in range(segments): + action = random.choice(actions) + logger.info(f" 🕹️ {action}") + time.sleep(segment_time * random.uniform(0.6, 1.4)) + + def _simulate_action_game(self, duration): + """模拟动作游戏""" + actions = ["移动", "攻击", "跳跃", "技能", "闯关"] + segments = random.randint(5, 10) + segment_time = duration / segments + + for i in range(segments): + action = random.choice(actions) + logger.info(f" ⚔️ {action}") + time.sleep(segment_time * random.uniform(0.5, 1.2)) + + def _simulate_general_game(self, duration): + """模拟一般游戏""" + actions = ["开始", "操作", "进行", "暂停", "继续"] + segments = random.randint(3, 6) + segment_time = duration / segments + + for i in range(segments): + action = random.choice(actions) + logger.info(f" 🎯 {action}") + time.sleep(segment_time * random.uniform(0.8, 1.2)) + + def run_ad_focused_visit(self): + """执行以广告为重点的访问流程""" + logger.info("🚀 开始广告重点访问流程") + + # 设置会话 + self.setup_session() + + try: + # 1. 模拟来源访问 + if not self.simulate_traffic_source(): + logger.warning("⚠️ 来源访问失败,继续执行") + + # 2. 访问首页并重点关注广告 + if not self.visit_homepage_with_ads(): + logger.error("❌ 首页广告访问失败") + return False + + # 3. 浏览游戏页面并关注广告 + if not self.browse_games_with_ads(): + logger.error("❌ 游戏页面广告访问失败") + return False + + logger.info("✅ 广告重点访问流程完成!") + return True + + except Exception as e: + logger.error(f"❌ 访问流程出错: {e}") + return False + + finally: + if self.session: + self.session.close() + + def run_continuous_ad_visits(self, total_visits=None, delay_range=None): + """连续执行广告重点访问""" + if total_visits is None: + total_visits = self.config['settings']['default_visits'] + + if delay_range is None: + delay_range = ( + self.config['settings']['min_delay'], + self.config['settings']['max_delay'] + ) + + success_count = 0 + total_ad_time = 0 + + logger.info(f"🎯 开始连续广告访问,目标: {total_visits} 次") + + for i in range(total_visits): + logger.info(f"{'='*60}") + logger.info(f"🔄 第 {i+1}/{total_visits} 次广告访问") + logger.info(f"{'='*60}") + + visit_start_time = time.time() + + if self.run_ad_focused_visit(): + success_count += 1 + visit_time = time.time() - visit_start_time + total_ad_time += visit_time + + logger.info(f"✅ 第 {i+1} 次访问成功!耗时: {visit_time:.1f}秒") + logger.info(f"📊 累计成功: {success_count}, 总广告时间: {total_ad_time:.1f}秒") + else: + logger.error(f"❌ 第 {i+1} 次访问失败!") + + # 访问间隔 + if i < total_visits - 1: + delay = random.uniform(delay_range[0], delay_range[1]) + logger.info(f"⏳ 等待 {delay:.1f} 秒") + time.sleep(delay) + + success_rate = (success_count / total_visits) * 100 + avg_ad_time = total_ad_time / success_count if success_count > 0 else 0 + + logger.info(f"🎉 广告访问任务完成!") + logger.info(f"📊 成功率: {success_count}/{total_visits} ({success_rate:.1f}%)") + logger.info(f"💰 总广告时间: {total_ad_time:.1f}秒") + logger.info(f"📈 平均每次广告时间: {avg_ad_time:.1f}秒") + + return success_count + +def main(): + """主函数""" + config_file = 'config.json' + + if not os.path.exists(config_file): + print(f"❌ 配置文件 {config_file} 不存在!") + return + + try: + bot = WebsiteAdBot(config_file) + + print("=" * 60) + print("💰 网站广告刷量机器人 (专业版)") + print("=" * 60) + print("🎯 专为Fun Games Hub游戏网站优化") + print("💰 重点关注广告展示和交互") + print("📱 移动端优先(广告收益更高)") + print("⚠️ 请确保仅用于测试自己的网站!") + print() + print(f"🎯 目标网站: {bot.config['targets']['main_site']}") + print(f"🎮 游戏类型: {len(bot.games_list)} 个游戏") + print(f"📱 移动端概率: 80%") + print() + + print("请选择运行模式:") + print("1. 💎 单次广告重点访问测试") + print("2. 🚀 连续广告访问 (使用配置参数)") + print("3. ⚙️ 自定义连续广告访问") + + choice = input("请输入选择 (1/2/3): ").strip() + + if choice == "1": + logger.info("🎬 开始单次广告重点访问测试") + success = bot.run_ad_focused_visit() + if success: + print("🎉 单次广告访问测试成功!") + else: + print("😞 单次广告访问测试失败!") + + elif choice == "2": + logger.info("🎬 开始连续广告访问") + success_count = bot.run_continuous_ad_visits() + total = bot.config['settings']['default_visits'] + print(f"🎉 连续广告访问完成!成功: {success_count}/{total}") + + elif choice == "3": + try: + visit_count = int(input("请输入访问次数: ").strip()) + min_delay = int(input("请输入最小延迟秒数: ").strip()) + max_delay = int(input("请输入最大延迟秒数: ").strip()) + + logger.info(f"🎬 开始自定义广告访问,次数: {visit_count}") + success_count = bot.run_continuous_ad_visits( + total_visits=visit_count, + delay_range=(min_delay, max_delay) + ) + + print(f"🎉 自定义广告访问完成!成功: {success_count}/{visit_count}") + + except ValueError: + print("❌ 输入参数错误!") + else: + print("❌ 无效选择!") + + except KeyboardInterrupt: + print("\n⚠️ 用户中断执行") + except Exception as e: + logger.error(f"程序执行出错: {e}") + print("❌ 程序执行出错,请查看日志文件 ad_bot.log") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/增强版广告刷量说明.md b/增强版广告刷量说明.md new file mode 100644 index 0000000..e337b5c --- /dev/null +++ b/增强版广告刷量说明.md @@ -0,0 +1,286 @@ +# 🎯 增强版广告刷量机器人 - 真实用户行为版 + +## 📋 功能概述 + +这是一个专门用于测试网站广告效果的增强版机器人,模拟真实用户对广告的行为,包括: +- **75%概率讨厌广告并点击关闭按钮** +- **真实的用户行为模拟**(寻找关闭按钮、思考时间、反应延迟等) +- **6种广告类型支持**(弹窗、插页、横幅、原生、侧边、底部) +- **详细的交互统计**(关闭率、点击率、用户行为分析) + +⚠️ **重要提醒:仅用于测试自己的网站!** + +## 🎯 核心特性 + +### 1. 真实用户行为模拟 +- 😤 **75%概率讨厌广告** - 符合真实用户心理 +- 🔍 **寻找关闭按钮时间** - 0.5-2.5秒 +- 🤔 **思考时间** - 2-5秒 +- 👀 **反应时间** - 1-3秒 +- 😌 **关闭后释放时间** - 0.5-1.5秒 + +### 2. 6种广告类型支持 +| 广告类型 | 关闭概率 | 点击概率 | 用户讨厌程度 | +|----------|----------|----------|--------------| +| 弹窗广告 | 75% | 15% | 80% | +| 插页广告 | 60% | 25% | 60% | +| 横幅广告 | 85% | 10% | 90% | +| 原生广告 | 45% | 35% | 30% | +| 侧边广告 | 70% | 20% | 70% | +| 底部广告 | 80% | 12% | 80% | + +### 3. 移动端优先 +- 📱 **85%概率使用移动设备** - 符合移动互联网趋势 +- 🎮 **游戏网站特化** - 专门针对游戏网站优化 +- 🌍 **真实IP地址** - 支持代理配置 + +## 📁 文件结构 + +``` +增强版广告刷量系统/ +├── index_enhanced_ads.html # 增强版首页(包含6种广告类型) +├── enhanced_ad_bot.py # 增强版广告机器人 +├── run_enhanced_ad_bot.bat # Windows启动脚本 +├── config.json # 配置文件 +├── real_user_database.py # 真实用户数据库 +├── enhanced_ad_bot.log # 运行日志 +└── 增强版广告刷量说明.md # 本说明文档 +``` + +## 🚀 使用方法 + +### 方法1:一键启动(推荐) +1. 双击 `run_enhanced_ad_bot.bat` +2. 按照提示选择运行模式 + +### 方法2:手动启动 +```bash +# 安装依赖 +pip install requests + +# 运行增强版机器人 +python enhanced_ad_bot.py +``` + +## ⚙️ 配置文件说明 + +### config.json 示例 +```json +{ + "proxy": { + "host": "your-proxy-host", + "port": "823", + "username": "your-username", + "password": "your-password" + }, + "targets": { + "main_site": "https://your-website.com/", + "game_page": "https://your-website.com/games/" + }, + "settings": { + "default_visits": 10, + "min_delay": 60, + "max_delay": 300 + } +} +``` + +## 📊 增强版HTML页面特性 + +### 广告类型详解 + +#### 1. 弹窗广告 (popup-ad) +- 页面加载3秒后显示 +- 模态对话框形式 +- 明显的关闭按钮 (×) +- 75%概率被用户关闭 + +#### 2. 插页广告 (interstitial-ad) +- 页面加载8秒后显示 +- 全屏覆盖形式 +- 5秒倒计时后可关闭 +- 60%概率被用户关闭 + +#### 3. 横幅广告 (banner-ad) +- 页面加载时立即显示 +- 横幅条形式 +- 闪烁动画效果 +- 85%概率被用户关闭 + +#### 4. 原生广告 (native-ad) +- 融入页面内容 +- 标记为"赞助内容" +- 较低的讨厌程度 +- 45%概率被用户关闭 + +#### 5. 侧边广告 (side-ad) +- 固定在页面右侧 +- 仅桌面端显示 +- 70%概率被用户关闭 + +#### 6. 底部广告 (bottom-ad) +- 固定在页面底部 +- 移动端友好 +- 80%概率被用户关闭 + +### JavaScript交互功能 +- 📊 **广告事件追踪** - 记录显示、关闭、点击事件 +- 🎯 **响应式设计** - 自适应不同设备 +- ⏰ **定时显示** - 智能的广告显示时机 +- 📱 **移动端优化** - 移动设备特殊处理 + +## 🎭 真实用户行为模拟 + +### 用户心理模型 +```python +# 广告讨厌程度影响因子 +time_factors = { + "工作时间": 1.2, # 更讨厌广告 + "休闲时间": 0.8, # 相对容忍 + "深夜时间": 1.0 # 普通 +} + +# 用户行为概率 +user_behaviors = { + "立即关闭": 0.45, # 看到广告立即关闭 + "思考后关闭": 0.30, # 思考几秒后关闭 + "阅读后关闭": 0.15, # 阅读内容后关闭 + "点击广告": 0.10 # 真的点击广告 +} +``` + +### 真实行为序列 +1. **👀 发现广告** - 反应时间 1-3秒 +2. **🔍 寻找关闭按钮** - 搜索时间 0.5-2.5秒 +3. **🤔 思考是否关闭** - 思考时间 2-5秒 +4. **🖱️ 点击关闭按钮** - 操作延迟 0.2-0.8秒 +5. **😌 关闭后释放** - 心理释放 0.5-1.5秒 + +## 📈 统计数据分析 + +### 运行日志示例 +``` +📊 广告交互统计: + popup: 显示10次, 关闭8次(80.0%), 点击1次(10.0%) + interstitial: 显示8次, 关闭5次(62.5%), 点击2次(25.0%) + banner: 显示12次, 关闭10次(83.3%), 点击1次(8.3%) + native: 显示10次, 关闭4次(40.0%), 点击4次(40.0%) + side: 显示6次, 关闭4次(66.7%), 点击1次(16.7%) + bottom: 显示8次, 关闭6次(75.0%), 点击1次(12.5%) + + 总计: 显示54次, 关闭37次(68.5%), 点击10次(18.5%) + 关闭按钮点击: 37次 + 广告内容点击: 10次 +``` + +### 关键指标 +- **关闭率** - 用户点击关闭按钮的概率 +- **点击率** - 用户点击广告内容的概率 +- **停留时间** - 用户在广告上的停留时间 +- **反应时间** - 用户看到广告后的反应速度 + +## 🔧 高级功能 + +### 1. 代理支持 +```python +# 支持HTTP代理 +proxy_config = { + "host": "proxy-server.com", + "port": "8080", + "username": "user", + "password": "pass" +} +``` + +### 2. 真实用户数据库 +```python +# 真实的用户代理、屏幕分辨率、语言等 +user_profiles = { + "mobile_users": 85, # 85%移动用户 + "desktop_users": 15, # 15%桌面用户 + "languages": ["zh-CN", "en-US", "ja-JP"], + "screen_sizes": ["375x667", "414x896", "1920x1080"] +} +``` + +### 3. 时间模式智能 +```python +# 根据时间调整用户行为 +time_patterns = { + "morning": {"annoyance": 0.8, "tolerance": 0.2}, + "work": {"annoyance": 1.2, "tolerance": 0.1}, + "evening": {"annoyance": 0.6, "tolerance": 0.4}, + "night": {"annoyance": 1.0, "tolerance": 0.3} +} +``` + +## 🎮 游戏网站特化 + +### 游戏相关行为 +- **游戏前广告** - 70%概率跳过或关闭 +- **游戏中广告** - 80%概率立即关闭 +- **游戏后广告** - 50%概率关闭,30%概率点击 +- **游戏页面停留** - 30-90秒真实游戏时间 + +### 游戏类型支持 +- 🧩 **益智游戏** - 2048、拼图等 +- 🕹️ **街机游戏** - 贪吃蛇、飞行鸟等 +- ⚔️ **动作游戏** - 冒险、射击等 +- ♟️ **策略游戏** - 棋类、塔防等 + +## 📱 移动端优化 + +### 移动端特殊处理 +- 📱 **85%概率使用移动设备** +- 🎯 **移动端专用广告** +- 📐 **响应式广告尺寸** +- 👆 **触摸操作模拟** + +### 移动端用户代理 +``` +iPhone Safari、Android Chrome、iPad Safari等 +真实的移动设备User-Agent字符串 +``` + +## 🚨 注意事项 + +### 使用限制 +1. ⚠️ **仅用于测试自己的网站** +2. 🕐 **合理控制访问频率** +3. 🌐 **遵守网站服务条款** +4. 📊 **监控服务器负载** + +### 最佳实践 +1. 📈 **先进行小规模测试** +2. 📊 **分析广告效果数据** +3. 🎯 **优化广告位置和类型** +4. 📱 **重点关注移动端用户体验** + +## 🔍 故障排除 + +### 常见问题 +1. **Python未安装** - 请安装Python 3.7+ +2. **配置文件错误** - 检查config.json格式 +3. **依赖包缺失** - 运行`pip install requests` +4. **网络连接问题** - 检查代理配置 + +### 日志查看 +```bash +# 查看运行日志 +tail -f enhanced_ad_bot.log + +# 查看错误信息 +grep ERROR enhanced_ad_bot.log +``` + +## 📞 技术支持 + +如果遇到问题,请: +1. 📝 查看 `enhanced_ad_bot.log` 日志文件 +2. 🔍 检查配置文件是否正确 +3. 📱 确保网络连接正常 +4. 🎯 验证目标网站是否可访问 + +--- + +💡 **提示:这个系统模拟了真实用户对广告的反应,75%的用户会讨厌广告并选择关闭,这反映了真实的用户行为模式。** \ No newline at end of file