腾讯系反爬页面自动化(patchright 人工驾驶模式)
环境安装(首次使用必做)
# 建议在隔离 venv 里装,别污染系统 Python
python -m pip install patchright
# 需要系统 Chrome:常见位置 C:\Program Files\Google\Chrome\Application\chrome.exe
# patchright 用 channel="chrome" 直接驱动系统 Chrome,通常无需再下载浏览器内核
> 注意:~/.workbuddy/binaries/python/envs/default 只是某一个宿主环境下的安装位置,换机器不一定存在。跑之前先 python -c "from patchright.sync_api import sync_playwright" 确认装好了,别假定「本机已就绪」。
核心结论(血泪教训,按序排查)
| 症状 | 根因 | 正解 |
|---|---|---|
| qqbrowser-skill daemon 拉浏览器即死 | QQ 浏览器对启动环境挑剔,后台服务环境下闪退 | 弃用,用户手动开正常也没法自动化接管 |
| agent-browser/playwright 打开页面几秒后变 about:blank | 微信反爬 JS 检测自动化(navigator.webdriver / CDP 痕迹)清空页面 | patchright(playwright 反检测魔改版) |
| connect_over_cdp 附着已有浏览器 | CDP 连接暴露自动化痕迹 | 用 launch_persistent_context,别用 connect |
| headless 模式 | 反爬更容易识别 + 用户无法扫码 | 必须 headless=False 有头 |
| 同一 user_data_dir 起两个 Chrome | profile 锁,第二个实例拿不到页面句柄 | 重启会话前必须 taskkill chrome 清残留 |
| curl 能抓到完整 HTML 但浏览器白屏 | 服务端没拦,是浏览器端反爬 JS 清空 DOM | 用 patchright 绕过,见上 |
标准会话模板
from patchright.sync_api import sync_playwright
PROFILE_DIR = r"<持久 profile 目录>" # 例:<临时目录>\patchright-profile;登录态跨脚本保留
with sync_playwright() as p:
ctx = p.chromium.launch_persistent_context(
user_data_dir=PROFILE_DIR, # 持久化,登录态跨脚本保留
channel="chrome", # 系统 Chrome
headless=False, # 有头(用户可见、可扫码、反检测更强)
no_viewport=True,
)
page = ctx.pages[0] if ctx.pages else ctx.new_page()
page.goto(URL, wait_until="domcontentloaded", timeout=60000)
# ... 用 page.evaluate 提取 DOM 文本判断状态(本机模型读不了截图!)
ctx.close() # 不关则登录态/页面随脚本退出丢失
要点:
- 页面状态判断全靠 page.evaluate dump document.body.innerText,不要依赖截图(模型读不了 PNG)
- 定位元素用稳定 id(如 mp 注册页:#js_email / #pw1 / #pw2 / #js_agree / #js_email_verifycode)
- 点击按钮用 page.locator("text=按钮文字").first.click()
- 后台运行(run_in_background)+ 30 秒轮询 dump 文本到 stdout,用 TaskOutput 随时查进度
人工驾驶模式(涉及身份验证的页面必用)
滑块验证(TCaptcha)、邮箱/短信验证码、身份证、微信扫码——这些不要自动化,让用户在可见窗口里亲手做:
- AI 脚本:打开页面 + 填好所有非敏感字段 + 勾协议 → 打印「轮到你了」提示
- 脚本进入轮询循环(每 30s dump 页面文本),用户在窗口操作
- 通过关键词检测状态推进:
已被占用/验证码错误= 报错;主体类型/管理员= 进入下一步;captcha iframe 出现 = 等用户拖滑块 - 完成目标步骤后再 keepalive 15 分钟(给用户后续操作留窗口),然后 ctx.close()
- 会话丢失可恢复:cookie 持久化在 user_data_dir,重开浏览器导航原 URL 即可接上
分工铁律
- AI:填表、点按钮(非身份类)、状态监控、错误诊断、重试
- 用户:滑块拖动、短信/邮箱验证码、身份证号、微信扫码、人脸
- GUI-only 环节不要硬自动化:遇"开通/签约/授权"这类只能用图形界面完成、官方 MCP/CLI 都不提供能力的环节,直接给一份简短的操作步骤让用户自己点,别用浏览器自动化去绕。自动化的定位是读状态、抓数据、填非敏感表单。
驾驶器模式(长任务远程操控)
脚本退出即丢会话的问题解法——浏览器常驻 + 命令文件轮询:
- 驱动脚本(放临时目录即可,如 <临时目录>/driver.py):patchright 常驻,每 3s 读同目录的命令文件(如 cmd.json,JSON 动作数组:goto/click/click_text/type/eval/dump/find/pages/switch/wait/quit),执行后清空并逐条打印结果
- AI 与浏览器解耦:写命令文件 → sleep → TaskOutput 读 [result|...] 行
- 注意:Write 工具改命令文件前必须先 Read(驱动器会清写它,直接 Write 会报 modified 冲突);窗口可能被用户误关,动作会报 "browser has been closed",需重启驱动器
环境备忘(换成你自己的路径)
- patchright venv:装它的那个 Python 解释器路径(
<venv>/Scripts/python.exe) - 持久 profile:上面
PROFILE_DIR指向的目录,其中可能含目标站点的 cookie 与保存的密码,别随手提交或分享 - 残留清理:⚠️ 不要直接
taskkill //IM chrome.exe //F—— 那会连带杀掉用户自己开着的浏览器和全部标签页。杀之前先按命令行区分身份:
powershell Get-CimInstance Win32_Process -Filter "Name='chrome.exe'" | Where-Object { $_.CommandLine -match "<你的 profile 目录标记>" } | ForEach-Object { Stop-Process -Id $_.ProcessId -Force }
更稳的做法是让脚本自己ctx.close()优雅退出(patchright 会关掉它启动的实例,不动别人的)