This commit is contained in:
huangzhenpc
2025-07-18 10:15:54 +08:00
parent 9f9f44ecc7
commit 2246295730
5 changed files with 584 additions and 285 deletions

View File

@@ -4,6 +4,7 @@
网站流量模拟脚本 (最终版本)
使用真实用户数据库模拟最真实的访问轨迹
支持Google搜索来源和真实网站跳转
2024升级增加多游戏快速选择行为 + 宝塔友好模式
"""
import requests
@@ -12,7 +13,7 @@ import random
import json
import os
import logging
from urllib.parse import urlparse, urljoin
from urllib.parse import urlparse, urljoin, parse_qs
import re
from real_user_database import RealUserDatabase
@@ -69,6 +70,25 @@ class WebTrafficBotFinal:
"https://www.oschina.net/",
"https://gitee.com/",
]
# 🎮 多游戏页面列表 - 模拟真实用户的游戏选择行为
self.game_pages = [
"/games/2048/index.html",
"/games/snake/index.html",
"/games/iframe-games.html?game=diy-doll-factory",
"/games/iframe-games.html?game=super-sprunki-adventure",
"/games/iframe-games.html?game=flightbird",
"/games/iframe-games.html?game=tap-to-color-painting-book",
"/games/iframe-games.html?game=lazy-gto-6",
"/games/iframe-games.html?game=something-below-the-sea",
"/games/iframe-games.html?game=gem-clicker-pro",
"/games/iframe-games.html?game=guess-tiles",
"/games/iframe-games.html?game=tic-tac-toe-2025",
"/games/iframe-games.html?game=bubble-shooter",
"/games/iframe-games.html?game=tetris-classic",
"/games/iframe-games.html?game=candy-crush",
"/games/iframe-games.html?game=puzzle-adventure"
]
def load_config(self, config_file):
"""加载配置文件"""
@@ -85,9 +105,12 @@ class WebTrafficBotFinal:
raise
def setup_session(self):
"""设置请求会话"""
"""设置请求会话 - 宝塔友好增强版"""
self.session = requests.Session()
# 🍪 启用Cookie支持 - 宝塔检测的重要指标
self.session.cookies.clear()
# 生成真实用户配置
self.current_profile = self.user_db.get_random_user_profile()
self.current_behavior = self.user_db.get_visit_behavior()
@@ -102,9 +125,9 @@ class WebTrafficBotFinal:
}
logger.info(f"已配置代理: {proxy_config['host']}:{proxy_config['port']}")
# 使用真实用户数据库生成的头部
realistic_headers = self.user_db.get_realistic_headers(self.current_profile)
self.session.headers.update(realistic_headers)
# 🌟 使用增强的真实浏览器头部 - 专门针对宝塔优化
enhanced_headers = self._get_baota_friendly_headers()
self.session.headers.update(enhanced_headers)
# 记录用户特征
logger.info(f"🎭 用户身份配置:")
@@ -122,6 +145,64 @@ class WebTrafficBotFinal:
print(f"🌍 当前IP地址: {current_ip}")
print(f"👤 用户身份: {self.current_profile['operating_system']} | {self.current_profile['screen_resolution']} | {self.current_behavior['pattern_type']}")
def _get_baota_friendly_headers(self):
"""生成宝塔友好的完整HTTP头部"""
user_agent = self.current_profile["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,application/signed-exchange;v=b3;q=0.7",
"Accept-Language": self.current_profile["language"],
"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": str(random.randint(0, 1)),
"Pragma": "no-cache",
# 🎯 关键:宝塔可能检测的额外头部
"X-Requested-With": "XMLHttpRequest" if random.random() < 0.1 else None, # 偶尔模拟AJAX请求
"Origin": None, # 首次访问通常没有Origin
"Purpose": "prefetch" if random.random() < 0.05 else None, # 偶尔的预取请求
}
# 移除None值
headers = {k: v for k, v in headers.items() if v is not None}
# 根据浏览器类型添加特定头部
if "Chrome" in user_agent:
headers.update({
"sec-ch-ua": self._generate_chrome_sec_ch_ua(user_agent),
"sec-ch-ua-mobile": "?0" if "Mobile" not in user_agent else "?1",
"sec-ch-ua-platform": f'"{self.current_profile["platform"]}"',
"sec-ch-ua-platform-version": self._get_platform_version(),
})
return headers
def _generate_chrome_sec_ch_ua(self, user_agent):
"""生成Chrome的sec-ch-ua头部"""
if "Chrome/" in user_agent:
version = user_agent.split("Chrome/")[1].split(".")[0]
return f'"Not_A Brand";v="8", "Chromium";v="{version}", "Google Chrome";v="{version}"'
return '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"'
def _get_platform_version(self):
"""获取平台版本信息"""
platform = self.current_profile["platform"]
if platform == "Windows":
return random.choice(['"10.0.0"', '"11.0.0"'])
elif platform == "macOS":
return random.choice(['"13.6.0"', '"14.1.0"', '"12.7.0"'])
elif platform == "Linux":
return '""'
return '""'
def get_current_ip(self):
"""获取当前IP地址"""
ip_services = [
@@ -341,7 +422,7 @@ class WebTrafficBotFinal:
if not response:
return False
# 模拟真实的页面浏览行为
# 模拟真实的页面浏览行为 - 缩短主页停留时间
self._simulate_realistic_browsing(response, is_main_page=True)
return True
@@ -350,37 +431,155 @@ class WebTrafficBotFinal:
logger.error(f"主网站访问失败: {e}")
return False
def visit_game_page_realistic(self):
"""真实模拟访问游戏页面"""
game_page = self.config['targets']['game_page']
def visit_multiple_games_realistic(self):
"""🎮 模拟真实用户快速浏览多个游戏的行为"""
main_site = self.config['targets']['main_site']
base_url = main_site.rstrip('/')
try:
logger.info(f"🎮 访问游戏页面: {game_page}")
# 模拟真实用户行为快速浏览3-8个游戏页面选择
game_count = random.randint(3, 8)
selected_games = random.sample(self.game_pages, min(game_count, len(self.game_pages)))
logger.info(f"🎯 开始快速游戏选择行为,将浏览 {game_count} 个游戏")
total_start_time = time.time()
success_count = 0
for i, game_path in enumerate(selected_games):
game_url = base_url + game_path
# 更新referrer为主站
self.session.headers.update({
'Referer': main_site,
'Sec-Fetch-Site': 'same-origin'
})
try:
logger.info(f"🎮 第{i+1}/{game_count}个游戏: {game_path}")
# 更新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]
self.session.headers.update({
'Referer': prev_game_url,
'Sec-Fetch-Site': 'same-origin'
})
# 发起请求
response = self.make_realistic_request(game_url)
if not response:
logger.warning(f"⚠️ 游戏页面访问失败: {game_path}")
continue
# 模拟快速浏览行为真实用户模式1-4秒快速查看
self._simulate_quick_game_browsing(response, game_path, i+1, game_count)
success_count += 1
# 游戏间的快速切换延迟(模拟点击下一个游戏)
if i < len(selected_games) - 1:
switch_delay = random.uniform(0.5, 2.0)
logger.info(f" ⚡ 快速切换到下个游戏: {switch_delay:.1f}")
time.sleep(switch_delay)
except Exception as e:
logger.error(f"❌ 游戏访问出错 {game_path}: {e}")
continue
total_time = time.time() - total_start_time
logger.info(f"🏁 游戏选择完成!访问了 {success_count}/{game_count} 个游戏,总耗时: {total_time:.1f}")
# 模拟最终选择一个游戏进行较长时间游玩
if success_count > 0:
self._simulate_final_game_selection(selected_games, base_url)
return success_count > 0
def _simulate_quick_game_browsing(self, response, game_path, current_index, total_count):
"""模拟快速游戏浏览行为 - 宝塔友好版"""
# 真实用户快速浏览行为2-5秒稍微增加以通过宝塔检测
browse_time = random.uniform(2.0, 5.0)
game_name = self._extract_game_name(game_path)
logger.info(f" 👀 快速查看 {game_name}: {browse_time:.1f}")
# 🎯 模拟Javascript交互 - 宝塔重要检测点
self._simulate_javascript_behavior(response.url)
# 模拟快速扫视页面
quick_actions = [
"查看游戏截图",
"阅读游戏标题",
"扫视游戏介绍",
"检查加载状态"
]
action_count = random.randint(1, 3)
action_time = browse_time / action_count
for i in range(action_count):
if i > 0:
time.sleep(random.uniform(0.3, 0.8)) # 稍微增加间隔
# 发起请求
response = self.make_realistic_request(game_page)
if not response:
return False
action = random.choice(quick_actions)
logger.info(f"{action}")
time.sleep(action_time * random.uniform(0.6, 1.4))
# 检查是否需要登录
if self._check_login_required(response):
logger.info(f" ⚠️ 检测到登录页面,快速跳过")
def _simulate_final_game_selection(self, selected_games, base_url):
"""模拟最终选择一个游戏进行深度游玩"""
# 有30%概率选择一个游戏进行深度体验
if random.random() < 0.3:
final_game = random.choice(selected_games)
final_game_url = base_url + final_game
# 检查是否需要登录
if self._check_login_required(response):
logger.warning("⚠️ 检测到登录页面,继续模拟访问")
logger.info(f"🎯 最终选择深度体验: {final_game}")
# 模拟真实的游戏页面行为
self._simulate_realistic_gaming(response)
return True
except Exception as e:
logger.error(f"游戏页面访问失败: {e}")
return False
try:
# 重新访问选定的游戏
self.session.headers.update({
'Referer': base_url + selected_games[-1], # 从最后浏览的游戏页面返回
'Sec-Fetch-Site': 'same-origin'
})
response = self.make_realistic_request(final_game_url)
if response:
# 模拟正常游戏行为(较长时间)
self._simulate_realistic_gaming(response, final_game)
except Exception as e:
logger.error(f"深度游戏体验失败: {e}")
def _extract_game_name(self, game_path):
"""从游戏路径提取游戏名称"""
if "2048" in game_path:
return "2048数字游戏"
elif "snake" in game_path:
return "贪吃蛇"
elif "diy-doll-factory" in game_path:
return "DIY娃娃工厂"
elif "super-sprunki-adventure" in game_path:
return "超级冒险"
elif "flightbird" in game_path:
return "飞行小鸟"
elif "tap-to-color" in game_path:
return "点击涂色"
elif "lazy-gto" in game_path:
return "懒惰GTO"
elif "something-below-the-sea" in game_path:
return "海底探险"
elif "gem-clicker" in game_path:
return "宝石点击"
elif "guess-tiles" in game_path:
return "猜瓷砖"
elif "tic-tac-toe" in game_path:
return "井字棋2025"
else:
return "未知游戏"
def _check_login_required(self, response):
"""检查是否需要登录"""
@@ -403,7 +602,7 @@ class WebTrafficBotFinal:
return False
def make_realistic_request(self, url, timeout=15):
"""发起真实HTTP请求"""
"""发起宝塔友好的真实HTTP请求"""
try:
# 添加随机的人为延迟
pre_request_delay = self.user_db.simulate_human_delays("thinking")
@@ -418,6 +617,12 @@ class WebTrafficBotFinal:
logger.info(f" 📦 响应大小: {len(response.content)} 字节")
logger.info(f" ⏱️ 响应时间: {response.elapsed.total_seconds():.2f}")
# 🍪 记录Cookie信息 - 宝塔关注的指标
if response.cookies:
logger.info(f" 🍪 接收到Cookies: {len(response.cookies)}")
for cookie in response.cookies:
logger.info(f" 🍪 {cookie.name}={cookie.value[:20]}...")
if response.headers.get('content-type'):
logger.info(f" 📄 内容类型: {response.headers.get('content-type')}")
@@ -425,14 +630,127 @@ class WebTrafficBotFinal:
logger.info(f" 🖥️ 服务器: {response.headers.get('server')}")
response.raise_for_status()
# 🎯 模拟浏览器的自动行为 - 请求静态资源
self._simulate_browser_auto_requests(url, response)
return response
except requests.exceptions.RequestException as e:
logger.error(f"❌ 请求失败 {url}: {e}")
return None
def _simulate_browser_auto_requests(self, base_url, response):
"""模拟浏览器自动请求静态资源"""
if random.random() < 0.7: # 70%概率模拟资源请求
parsed_url = urlparse(base_url)
base_domain = f"{parsed_url.scheme}://{parsed_url.netloc}"
# 🎯 模拟常见的静态资源请求
potential_resources = [
"/favicon.ico",
"/css/style.css",
"/js/main.js",
"/js/jquery.min.js",
"/images/logo.png",
"/static/css/bootstrap.min.css",
"/assets/js/app.js",
"/manifest.json",
]
# 随机选择1-3个资源请求
resources_to_request = random.sample(potential_resources, random.randint(1, 3))
for resource in resources_to_request:
try:
# 🎯 设置静态资源请求的头部
resource_headers = self.session.headers.copy()
resource_headers.update({
"Referer": base_url,
"Sec-Fetch-Dest": self._get_resource_dest(resource),
"Sec-Fetch-Mode": "no-cors",
"Sec-Fetch-Site": "same-origin",
})
resource_url = base_domain + resource
# 短延迟模拟并发加载
time.sleep(random.uniform(0.1, 0.5))
resource_response = self.session.get(
resource_url,
headers=resource_headers,
timeout=5,
allow_redirects=True
)
if resource_response.status_code == 200:
logger.info(f" 📄 成功请求资源: {resource}")
except Exception as e:
logger.debug(f" ⚠️ 资源请求失败 {resource}: {e}")
def _get_resource_dest(self, resource_path):
"""根据资源路径确定Sec-Fetch-Dest"""
if resource_path.endswith(('.css',)):
return "style"
elif resource_path.endswith(('.js',)):
return "script"
elif resource_path.endswith(('.png', '.jpg', '.jpeg', '.gif', '.webp', '.ico')):
return "image"
elif resource_path.endswith('.json'):
return "manifest"
else:
return "empty"
def _simulate_javascript_behavior(self, url):
"""模拟Javascript行为和AJAX请求"""
if random.random() < 0.4: # 40%概率模拟JS行为
parsed_url = urlparse(url)
base_domain = f"{parsed_url.scheme}://{parsed_url.netloc}"
# 🎯 模拟常见的AJAX端点
ajax_endpoints = [
"/api/stats",
"/api/user",
"/analytics",
"/track",
"/heartbeat",
"/ping",
"/api/config"
]
endpoint = random.choice(ajax_endpoints)
ajax_url = base_domain + endpoint
try:
ajax_headers = self.session.headers.copy()
ajax_headers.update({
"X-Requested-With": "XMLHttpRequest",
"Content-Type": "application/json",
"Referer": url,
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-origin",
})
# 模拟AJAX延迟
time.sleep(random.uniform(2, 8))
ajax_response = self.session.get(
ajax_url,
headers=ajax_headers,
timeout=5
)
if ajax_response.status_code == 200:
logger.info(f" 🔄 AJAX请求成功: {endpoint}")
except Exception as e:
logger.debug(f" ⚠️ AJAX请求失败 {endpoint}: {e}")
def _simulate_realistic_browsing(self, response, is_main_page=False):
"""模拟真实的页面浏览行为"""
"""模拟真实的页面浏览行为 - 宝塔友好增强版"""
content = response.text
# 估算页面内容长度和阅读时间
@@ -443,9 +761,10 @@ class WebTrafficBotFinal:
logger.info(f" 📝 内容长度: {text_length} 字符")
logger.info(f" ⏱️ 预估阅读时间: {reading_time:.1f}")
# 获取真实的停留时间
# 获取真实的停留时间 - 🎯 缩短主页停留时间,模拟快速寻找游戏
if is_main_page:
base_time = random.uniform(*self.config['settings']['main_site_stay_time'])
# 主页停留时间3-10秒稍微增加以通过宝塔检测
base_time = random.uniform(3, 10)
else:
base_time = min(reading_time, 60) # 最多60秒阅读时间
@@ -453,6 +772,9 @@ class WebTrafficBotFinal:
logger.info(f" 🕐 实际停留时间: {stay_time:.1f}")
# 🎯 模拟Javascript行为 - 宝塔可能检测的行为
self._simulate_javascript_behavior(response.url)
# 模拟分段浏览
self._simulate_browsing_segments(stay_time, content)
@@ -516,9 +838,13 @@ class WebTrafficBotFinal:
logger.info(f" 🔗 查看链接: {link[:50]}...")
time.sleep(random.uniform(0.5, 2.5))
def _simulate_realistic_gaming(self, response):
def _simulate_realistic_gaming(self, response, game_path=None):
"""模拟真实的游戏行为"""
logger.info("🎲 开始2048游戏模拟")
if game_path:
game_name = self._extract_game_name(game_path)
logger.info(f"🎲 开始深度体验 {game_name}")
else:
logger.info("🎲 开始游戏模拟")
# 游戏前的准备时间
prep_time = self.user_db.simulate_human_delays("thinking")
@@ -599,9 +925,9 @@ class WebTrafficBotFinal:
logger.error("❌ 主网站访问失败")
return False
# 3. 访问游戏页面
if not self.visit_game_page_realistic():
logger.error("❌ 游戏页面访问失败")
# 3. 🎮 NEW: 模拟真实的多游戏快速选择行为
if not self.visit_multiple_games_realistic():
logger.error("游戏访问失败")
return False
logger.info("✅ 访问流程完美执行成功!")