From 5783feb60d1122a37fb100a108db49d0e534d2f8 Mon Sep 17 00:00:00 2001 From: hz4th_coder Date: Sun, 5 Jul 2026 01:28:24 +0800 Subject: [PATCH] =?UTF-8?q?=E9=9B=86=E6=88=90=20playwright-stealth=20?= =?UTF-8?q?=E4=B8=93=E4=B8=9A=E5=8F=8D=E6=A3=80=E6=B5=8B=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加: - playwright-stealth 反检测库 - 增强 navigator 属性模拟 - 真实 Chrome 浏览器支持(如果已安装) - 更强的反自动化检测配置 注意: - 某些高防护网站(如 Cloudflare)仍可能拦截 - 建议使用代理或真实 Chrome 浏览器 --- app.py | 104 +++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 86 insertions(+), 18 deletions(-) diff --git a/app.py b/app.py index 2d16f9d..4761568 100644 --- a/app.py +++ b/app.py @@ -20,8 +20,17 @@ from datetime import datetime try: from playwright.async_api import async_playwright PLAYWRIGHT_AVAILABLE = True + # 尝试导入 stealth 反检测 + try: + from playwright_stealth import stealth_async + STEALTH_AVAILABLE = True + except ImportError: + STEALTH_AVAILABLE = False + print("⚠️ playwright-stealth 未安装,反爬虫能力降低") except ImportError: PLAYWRIGHT_AVAILABLE = False + STEALTH_AVAILABLE = False + print("⚠️ Playwright 未安装,请运行: pip install playwright && playwright install chromium") # 检查 agent-browser 是否可用 def check_agent_browser(): @@ -204,16 +213,30 @@ async def capture_with_playwright( try: async with async_playwright() as p: # 启动浏览器,添加反检测配置 - browser = await p.chromium.launch( - headless=True, - args=[ - '--disable-blink-features=AutomationControlled', # 反自动化检测 - '--disable-dev-shm-usage', - '--no-sandbox', - '--disable-setuid-sandbox', - '--disable-web-security', - ] - ) + # 尝试使用真实 Chrome(如果安装了) + try: + # 首先尝试使用真实 Chrome 浏览器 + browser = await p.chromium.launch( + headless=True, + channel='chrome', # 使用真实 Chrome 而不是 Chromium + args=[ + '--disable-blink-features=AutomationControlled', + '--disable-dev-shm-usage', + '--no-sandbox', + '--ignore-certificate-errors', + ] + ) + except: + # 如果没有 Chrome,使用 Chromium + browser = await p.chromium.launch( + headless=True, + args=[ + '--disable-blink-features=AutomationControlled', + '--disable-dev-shm-usage', + '--no-sandbox', + '--ignore-certificate-errors', + ] + ) viewport_settings = viewport or {"width": 1920, "height": 1080} @@ -223,32 +246,77 @@ async def capture_with_playwright( "width": viewport_settings.get("width", 1920), "height": viewport_settings.get("height", 1080) }, - user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', + user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.6099.109 Safari/537.36', # 添加更多浏览器特征 - locale='zh-CN', - timezone_id='Asia/Shanghai', - geolocation={'latitude': 31.2304, 'longitude': 121.4737}, # 上海坐标 - permissions=['geolocation'], + locale='en-US', + timezone_id='America/New_York', + color_scheme='light', + has_touch=False, + is_mobile=False, + java_script_enabled=True, + accept_downloads=True, ) # 注入反检测脚本 await context.add_init_script(""" + // 移除 webdriver 标记 Object.defineProperty(navigator, 'webdriver', { get: () => undefined }); + + // 添加插件 Object.defineProperty(navigator, 'plugins', { - get: () => [1, 2, 3, 4, 5] + get: () => { + return [ + {name: 'Chrome PDF Plugin', filename: 'internal-pdf-viewer', description: 'Portable Document Format'}, + {name: 'Chrome PDF Viewer', filename: 'mhjfbmdgncjokjjpdkfnmlglggk', description: ''}, + {name: 'Native Client', filename: 'internal-nacl-plugin', description: ''} + ]; + } }); + + // 语言列表 Object.defineProperty(navigator, 'languages', { - get: () => ['zh-CN', 'zh', 'en', 'en-US'] + get: () => ['en-US', 'en', 'zh-CN'] }); + + // 平台 + Object.defineProperty(navigator, 'platform', { + get: () => 'Win32' + }); + + // 硬件并发 + Object.defineProperty(navigator, 'hardwareConcurrency', { + get: () => 8 + }); + + // 设备内存 + Object.defineProperty(navigator, 'deviceMemory', { + get: () => 8 + }); + + // Chrome 对象 window.chrome = { - runtime: {} + runtime: { + PlatformOs: {MAC: 'mac', WIN: 'win', ANDROID: 'android', CROS: 'cros', LINUX: 'linux', OPENBSD: 'openbsd'}, + PlatformArch: {ARM: 'arm', X86_32: 'x86-32', X86_64: 'x86-64'}, + PlatformNaclArch: {ARM: 'arm', X86_32: 'x86-32', X86_64: 'x86-64'}, + Request: function() {}, + connect: function() {}, + sendMessage: function() {} + }, + loadTimes: function() {}, + csi: function() {}, + app: {} }; """) page = await context.new_page() + # 应用 stealth 反检测(如果可用) + if STEALTH_AVAILABLE: + await stealth_async(page) + try: await page.goto(url, wait_until="networkidle", timeout=30000) except: