Camoufox 反侦测浏览器实战:被反爬系统盯上之后如何换一套设备指纹
【免费下载链接】camoufox🦊 Anti-detect browser项目地址: https://gitcode.com/gh_mirrors/ca/camoufox
爬虫跑满一小时就开始返回验证页,换了机房 IP 也没用——网站不只认 IP,它同时比对屏幕分辨率、字体列表、WebGL 渲染器字符串和时区这一整串"指纹",任何一处露馅就标记你。Camoufox 是一款基于 Firefox 打补丁的反侦测浏览器:每次启动自动抽一套内部自洽的设备指纹,这些值在浏览器 C++ 层直接回答,页面用 JavaScript 查不到劫持痕迹;Playwright 的自动化代码则藏在页面看不到的隔离层里,navigator.webdriver返回 false。
谁适合、谁不适合
- 适合:用 Playwright 做采集、AI 代理或自动化测试,且被反爬系统频繁拦截的开发者
- 适合:需要一台机器并行多个互不关联身份的批量任务
- 不适合:
requests就能拿到静态页面的场景,以及把"永不被检测"写成验收标准的需求
10 分钟装好并跑起来
Python 启动器负责三件事:拉浏览器二进制、抽一套指纹、把指纹塞给浏览器。要求 Python 3.10+,两条命令搞定。camoufox fetch提前装好与当前版本配套的浏览器和指纹模型,免得首次启动时现下:
pip install -U "camoufox[geoip]" camoufox fetch然后四行代码出结果:
from camoufox.sync_api import Camoufox with Camoufox(headless=True) as browser: page = browser.new_page() page.goto("https://example.com")Camoufox()返回的是标准 PlaywrightBrowser对象,你现有的 Playwright 代码基本只改导入和启动两行。Node/TypeScript 侧是npm install camoufox playwright-core加npx camoufox fetch,API 与 Python 版一一对应,见 typescript/README.md。
第一个实战:让指纹、出口 IP 和鼠标轨迹都对齐
反爬系统里最先被拆穿的往往不是浏览器本身,而是身份和出口 IP 对不上:指纹说是东京,时区却是 UTC,WebRTC 又泄漏出美国机房地址。把代理和geoip=True一起传进去,启动器会自动查出口 IP,把时区、区域语言、定位坐标和 WebRTC IP 全部对齐到同一个地方:
with Camoufox(proxy={"server": "http://proxy:8080"}, geoip=True) as b: page = b.new_page() page.goto("https://example.com")再往下是三个高频场景,都是改一个参数的量级:
- 多身份并行:
NewContext(browser, os="windows")给每个上下文单独发一套指纹(navigator、屏幕、WebGL、字体、时区),不用多开浏览器进程 - 更像人手:
humanize=True,轨迹来自 2356 段真实人手录制,停顿和过冲都按原样回放,不是贝塞尔曲线拼的 - Linux 服务器:部分站对 headless 更敏感,
headless="virtual"起一个私有 Xvfb 显示,跑有头渲染
它为什么能做到
指纹在 C++ 层回答,不是在页面里改的
给navigator打补丁的 JS 注入方案,等于让演员现场改口:属性描述符和toString()都会露馅,worker 与 iframe 里还经常漏。Camoufox 走的是另一条路——仓库 browser/patches/ 下几十个补丁文件直接改 Firefox 的 C++ 实现,页面读到的是原生值,像换了一本真护照,而不是教演员背新台词。
指纹本身也不是手挑的。启动器从 fpgen(按真实世界流量统计训练的指纹分布模型)里抽设备,比例贴近现实,比如 Linux 桌面只分到很小的一截;再经一致性校验,丢掉现实中不存在的组合,例如声称 Windows 却列出一串 macOS 才有的字体。
自动化代码住在页面看不见的房间里
Playwright 驱动 Chromium 走 CDP,驱动 Firefox 走 Juggler——后者是 Firefox 里的一个独立模块,不是浏览器核心的一部分,所以可以被改动。Camoufox 的 Juggler 把页面代理放进隔离 world:evaluate、选择器、init script 都在那份页面副本上运行,真实页面看不到 getter 被触发、也看不到监听器出现。输入事件走 Firefox 自己的输入管线,被当成真人输入处理。
还有一处反直觉的克制:canvas 像素、文字宽度、音频渲染故意不加噪。原版 Firefox 本来就不加噪,"加了噪"本身就是一种指纹。
别踩的坑
- 它仍可能被检测。成百上千个值必须互相一致,反爬厂商专找那个不一致的。README 给了二分排查法:先在原版 Firefox 上复现,站点同样报错就是 IP 或频率问题,不是浏览器;再逐块加回 Camoufox 的补丁定位到具体那块
camoufox fetch在 CI 上失败。它要通过 GitHub API 读一次发布信息,共享 runner 上设置GITHUB_TOKEN提高限流;另外 fetch 用的用户要和之后跑浏览器的用户一致,构建 Docker 镜像时尤其容易踩- 没挂代理却开着 IPv6。站点可以走 IPv6 摸到你的真实机器;若 IPv6 地址的地理位置和 IPv4 身份对不上,浏览器会按 IPv4-only 网络处理并抛
LeakWarning。看到警告先确认出口一致,别直接屏蔽 - 和 JS 注入、CDP 方案的差别一句话版:值从 C++ 层回答、worker 与 iframe 处处一致、请求头与 navigator 永远匹配、自动化代码不进页面。代价是只呈现 Firefox 系身份——部分 WAF 会专门测 SpiderMonkey 引擎行为,伪装不出 Chromium 特征
- 多身份并行的 canvas 陷阱:画布噪声按浏览器设置而不是按上下文。想让不同
NewContext()各自装作不同 OS,得显式传canvas_noise=True,否则都会声称宿主 OS
文档、源码与贡献入口
- 完整启动选项表:python/README.md,含代理、持久化 profile、多上下文的细节
- 构建浏览器才需要克隆源码,进
browser/目录跑make dir、make bootstrap、make build,冷构建约 40 分钟,装了 ccache 后增量约 5 分钟;构建流程与 Docker 方案见 browser/Makefile - 字体伪装和每上下文补丁的原理分别在 docs/FONTS.md、docs/per-context-patches.md,排查问题前值得翻一遍
- 提代码先读 CONTRIBUTING.md:每个 PR 挂一个 issue,CI 全量跑测试后才合入
写在最后
先拿你最常被拦的那个站,跑一遍上面带geoip的代理示例,把成功率和原版 Playwright 各测一轮,数据比感觉可靠。如果某站识破了它,把站点和检测位置整理成 detection report 提给上游——这是帮项目、也帮自己最快的方式。
【免费下载链接】camoufox🦊 Anti-detect browser项目地址: https://gitcode.com/gh_mirrors/ca/camoufox
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考