反检测浏览器内核实战:ruyipage / DrissionPage / camoufox / CloakBrowser
前言
在 cookie 池架构里,思路是「真浏览器采放行 cookie → curl_cffi 同出口 IP + 同指纹回放」。
浏览器内核负责过质询、拿真实会话,回放侧用 curl_cffi 的 impersonate 复刻内核的 TLS/JA3 指纹。
不同防护(Cloudflare / Akamai / PerimeterX / Imperva 等)对内核的要求差异很大,选错内核直接卡死。
本文把项目里在用的四个内核 —— ruyipage / DrissionPage(dp) / camoufox(官方 + 三方 fork)/ CloakBrowser ——
的原生用法与工程封装用法整理清楚,并给出选型顺序和回放侧指纹对齐表。
环境说明:全部跑在 conda 的
py310环境
(C:/Users/YanchuangJin/miniforge3/envs/py310/python.exe,装了 ruyipage / camoufox / cloakbrowser / curl_cffi / DrissionPage)。
四内核速览
| 内核 | 基座 | 反检测强度 | 典型能解 | 回放 impersonate |
|---|---|---|---|---|
| DrissionPage (dp) | 本机 Chrome | ★★☆☆☆(CDP 可被检测) | 静默 JS 挑战 | chrome150(对齐本机 Chrome 大版本) |
| ruyipage | Firefox 151 | ★★★☆☆ | CF Managed/Turnstile、Fastly、Akamai 部分 | firefox151 |
| camoufox | 反检测 Firefox | ★★★★☆ | CF 自适应 JA3 严格质询(onbuy) | firefox* + 采集时实际 UA |
| CloakBrowser | 隐身 Chromium | ★★★★★(击败 CDP 检测) | Chrome 类站点最硬的一档 | chrome146(免费版) |
升级顺序:Chrome 类站点被拦 → dp → cloak;Firefox 类质询更硬 → ruyipage → camoufox。
工程上四者统一为同一个后端接口(spiders/cookie_pool/backends/):
1 | |
站点接入只需在 SiteConfig 里写 backend="ruyipage" / "camoufox" / …,通常不改实现代码。
1. DrissionPage(dp)—— 驱动本机 Chrome
最轻量:直接驱动本机已安装的 Chrome(实测 Chrome 150.0.7871.47),适合「必须真实本机 Chrome 环境」的静默 JS 挑战。
缺点是走 CDP,指纹上能被检测出自动化(Chrome 类硬站会被 Access Denied,此时升级到 CloakBrowser)。
原生用法
1 | |
DrissionPage 3.x / 4.x 接口差异(项目里用 shim 抹平)
py310 装的是 3.2.30、系统 Python 是 4.1.1.4,两版接口不兼容,工程里在 _dp_core.py 统一:
| 操作 | 3.x | 4.x |
|---|---|---|
| headless | set_headless(on) |
headless(on) |
| 禁图 | set_no_imgs(on) |
no_imgs(on) |
| 取 cookie | page.get_cookies(as_dict=True, all_domains=True) |
page.cookies(all_domains=True)(由 property 变 method) |
| 构造首参 | addr_driver_opts |
addr_or_opts |
- 构造统一用位置参数
ChromiumPage(co);路径统一走set_paths(local_port=, user_data_path=, browser_path=)。 - 认证代理走本机中继
spiders/common/browser_proxy.configure_chromium_proxy
—— Chrome 137+ 不再支持账密代理直连,必须本地起中继。 - 坑:① 控制台 GBK 编码不能
print✓/✗,输出用 ASCII;② 3.x 关浏览器时_recv_loop会打一条JSONDecodeError(CDP websocket 收到空消息),是 teardown 噪音、不影响结果。
工程后端只需:backend="drissionpage"(别名 dp)。
2. ruyipage —— Firefox 151 指纹内核
深度打补丁的 Firefox 151,支持智能指纹(geo 探测 + fpfile 注入 + BiDi 仿真),
静默 JS 挑战(浏览器自动 reload 就过,无验证码)和 CF Managed/Turnstile 都能处理。
查 API 首选本地 METADATA(含完整中文示例,别凭记忆):
.../envs/py310/Lib/site-packages/ruyipage-1.2.43.dist-info/METADATA
与 PyPI 发布页 https://pypi.org/project/ruyipage/。
原生用法(手动 profile + 代理 + fpfile)
1 | |
智能指纹一站式(geo 敏感站必备)
数据中心代理地理不固定时,出口 IP 的国家/时区要和浏览器指纹对齐,否则 Akamai 之类会在搜索页弹挑战。apply_smart_fingerprint 经代理做一次 geo 查询,自动对齐 locale / timezone / geolocation:
1 | |
工程实战里的几个关键坑(_ruyi_core.py)
- 每次采集用独立临时 profile,用完删:ruyipage 自建的临时 profile 「通常」才清理、不保证,长跑会在 C 盘堆积。
- fpfile 必须落在本次唯一 profile 目录内:多分片并行时若共用固定路径,两进程会互相覆盖代理凭据 → 407。
- 强杀 Firefox 进程树:
page.quit()只 terminate 启动器(geckodriver),不杀 Firefox 子进程
—— Windows 杀父不杀子,每次残留一组firefox.exe。用本次唯一 profile 目录名精准定位进程树 kill。 - CF 质询框在跨源独立 context,不在
document.querySelectorAll('iframe')里;必须走browsingContext.getTree(BiDi)检测,再交handle_cloudflare_challenge处理。 - 锁 UA 不抖动:复制包内
fingerprints.json把firefox_minor_jitter锁成[0],
让采集端 UA 恒为 151,和回放curl_cffi firefox151精确对齐。
工程后端:backend="ruyipage"(或 turnstile = ruyipage + CF Managed 处理)。
3. camoufox —— 反检测 Firefox(官方 + 三方 fork)
对 Firefox 深度打补丁、不注入 JS 即可改指纹,比 ruyipage/invisible 更「像真人」。
onbuy 的 Cloudflare 自适应 JA3 严格质询就是靠它解的(ruyipage 被升级成交互式解不出、dp 的 JA3 curl 又回放不了)。
3.1 官方版(pip)
1 | |
1 | |
geoip 三态(关键):
geoip=True:经出口探测api.ipify.org得真实 IP 再本地查地理。出口能自由访问 ipify 时用它。geoip="209.146.101.43":直接对指定 IP 做本地 mmdb 查询,跳过被墙 / 被拦的 ipify(推荐做法)。geoip=False:不做地理对齐(指纹可能不一致,触发风控)。
WebRTC 处理(重要,SOCKS 代理场景防真实 IP 泄漏):
1 | |
实测:SOCKS 只代理 TCP,Firefox 的 WebRTC(UDP) 不走 SOCKS 会泄漏真实 IP、与出口不一致 → 触发 Akamai 行为质询。
block_webrtc=True能消除泄漏;但要 WebRTC 真报代理 IP(PDP 那种更严检测),需整机 TUN 模式(Clash/sing-box)而非浏览器代理。
3.2 ⚠️ playwright 版本必须钉 1.51.0
camoufox(FF135)**必须搭 playwright==1.51.0**:
1 | |
用 1.60 打开会报 JS 错的真实站点会崩:Page.goto: Connection closed while reading from the driver,
stderr 顶部是 Node 崩溃横幅。根因:camoufox FF135 的 juggler 发的 pageerror 事件没有 location 字段,
而 playwright 1.60 的 driver 去读 pageError.location.url → TypeError → 整个 Node driver 崩。
Windows 上跑 camoufox/playwright 前必须
asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy()),否则起子进程NotImplementedError。
3.3 三方 fork(coryking/camoufox)+ 自定义构建
官方内核只到 FF135;要更高版本(FF142 / FF150)的反检测构建,用三方 fork:
1 | |
配合自编译的全隐身内核,用 executable_path 直接指到 camoufox.exe:
1 | |
- 覆盖
camoufox path(AppData\Local\camoufox\camoufox\Cache)成 fork 内核后,需补version.json
(release 落在[beta.19, 1)区间才is_supported)。 - Linux 无 X 环境用
headless="virtual"(自带 Xvfb 真实渲染,无 headless 特征),需先apt install xvfb。
3.4 回放侧的坑:每会话随机 UA
camoufox 每个会话随机 UA,所以回放必须用采集时的实际 UA(不能硬编码):采集后回传navigator.userAgent,消费端 consumer.session 用 entry["ua"] 设 curl_cffi 的请求头,impersonate 用 firefox* 对齐 JA3。
工程后端:backend="camoufox"。
4. CloakBrowser —— 反检测最强的隐身 Chromium
源码级指纹补丁的隐身 Chromium:击败 CDP 检测、无 headless 泄漏、Windows 原生 GPU 直通、过 incognito 检测
(”passes every bot detection test”)。实测反检测强度最高 —— bloomingdales 的 Akamai 上,它是唯一能拿到
真实首页(1.58MB)的内核(dp/普通 Chrome 被 Access Denied、ruyipage/invisible/camoufox 卡 sec-cpt 行为质询)。
1 | |
原生用法
1 | |
- 回放
curl_cffi用 **chrome146**(对齐免费版内核大版本;Pro 版对齐chrome148)。 - 限制:CloakBrowser 也解不了 bloomingdales 深层页(search/PDP)的 Akamai 硬拒 —— 它只放行首页,
这是站点策略层面的(非内核能解)。
工程后端:backend="cloak"(别名 cloakbrowser)。
5. 回放侧指纹对齐(curl_cffi)
内核采完 cookie,回放要用 curl_cffi 复刻同一内核的 TLS/JA3 指纹,否则同 IP 同 cookie 也会被拦:
| 采集内核 | 回放 impersonate |
|---|---|
| ruyipage (FF151) | firefox151 |
| camoufox (FF135/自定义) | firefox* + 采集时实际 UA |
| DrissionPage (本机 Chrome150) | chrome150 |
| CloakBrowser (免费 Chrome146) | chrome146 |
本地装的是 KingJem 自编译的 curl_cffi fork(curl-impersonate + curl_cffi 0.15.5),
含chrome141-150(无 147)/firefox144-153/ brave 等新指纹;标准版curl_cffi没有这些。
部署前先探测目标机器有没有这个 fork,否则回放报ImpersonateError。
6. 选型决策
- 先按防护类型定基座:Chrome 类站点走 dp/cloak;Firefox 更能过的质询走 ruyipage/camoufox。
- 按被拦程度升级:
- Chrome 侧:
dp(本机 Chrome)→ cloak(隐身 Chromium) - Firefox 侧:
ruyipage(FF151)→ camoufox(反检测 FF,含 fork)
- Chrome 侧:
- geo 敏感站:数据中心代理务必开 geoip 对齐(camoufox
geoip=;ruyipageapply_smart_fingerprint)。 - 代理下防 WebRTC 泄漏:camoufox
block_webrtc/ice.proxy_only;要过最严的 PDP 需整机 TUN 路由。 - 回放对齐指纹与 UA:impersonate 对齐内核大版本;camoufox 还要带采集时的实际 UA。
这套内核 + 回放的组合,覆盖了项目里绝大多数受反爬保护的零售站点;剩下极少数(如 bloomingdales 深层页)
是站点策略层面的硬拒,非换内核能解,需换数据源或真人桌面 + 整机 TUN 环境。