12 KiB
name, description, version, tags
| name | description | version | tags | |||||
|---|---|---|---|---|---|---|---|---|
| cloakbrowser | CamouFox反检测浏览器(CloakBrowser) — 完美通过所有bot检测,支持Google等强反自动化站点登录。含2FA文件轮询方案、备用验证码使用、常见陷阱。 | 1.0 |
|
CloakBrowser (CamouFox Anti-Detection Browser)
CamouFox是经过反检测改造的Firefox浏览器,在headless模式下完美通过所有bot检测。
Gitea 镜像
- 源码镜像: admin9webs/CamouFox (~8MB, 不含bundle/)
- 上游: github.com/daijro/camoufox (~1.5GB 含bundle二进制)
- Gitea 仓库只含源码(badges/patches/pythonlib/settings/scripts等),不含bundle/目录
Bot检测结果
| 测试 | 结果 |
|---|---|
| navigator.webdriver | ✅ false(最关键) |
| WebDriver 检测 | ✅ passed |
| Chrome runtime | ✅ present |
| Headless 检测 | ✅ 通过 |
| 指纹一致性 | ✅ 5 plugins, Win32 平台 |
Gmail 2FA 登录脚本
仓库中提供了可直接运行的 Gmail 2FA 登录脚本:
- Gitea:
admin9webs/browser-automation-toolkit/scripts/gmail_2fa_login.py - 本地:
~/hermes/skills/browser-automation/cloakbrowser/scripts/gmail_2fa_login.py - 用法:
python3 -u gmail_2fa_login.py后台启动 → 写入/tmp/gmail_code.txt→ 自动完成登录 - 功能:CamouFox 反检测登录 → SMS 接收 → 文件轮询等待验证码 → Cookie 持久化
安装与导入
from camoufox.sync_api import Camoufox
无需额外安装,venv中已有camoufox包。
Python路径: /home/ubuntu/.hermes/hermes-agent/venv/bin/python3
基本启动参数
with Camoufox(headless=True, geoip=True, humanize=True) as browser:
page = browser.new_page()
page.goto("https://example.com", timeout=30000)
headless=True: 无头模式geoip=True: 自动匹配IP地理位置的时区/语言humanize=True: 模拟人类输入延迟
Google登录 + 2FA完整流程
Google是最严格的反自动化站点,普通Playwright Chromium会被拦截到/signin/rejected。
CamouFox可以绕过,但2FA需要特殊处理。
核心陷阱:验证码时效性
每次新登录会话都会使之前的SMS验证码失效! 不能"先登录触发短信 → 等用户给码 → 重新登录输入",因为重新登录=新会话=旧码失效。
解决方案:后台脚本 + 文件轮询
用后台进程保持浏览器会话存活,通过文件传递验证码:
CODE_FILE = "/tmp/gmail_code.txt"
SIGNAL_FILE = "/tmp/gmail_signal.txt"
with Camoufox(headless=True, geoip=True, humanize=True) as browser:
page = browser.new_page()
# Step 1: Email
page.goto("https://accounts.google.com/signin", timeout=30000)
page.wait_for_load_state("networkidle", timeout=15000)
time.sleep(2)
page.query_selector("input[type=email]").fill(email)
time.sleep(1)
page.query_selector("#identifierNext").click()
time.sleep(5)
# Step 2: Password
page.query_selector("input[type=password]").fill(password)
time.sleep(1)
page.query_selector("#passwordNext").click()
time.sleep(6)
# Step 3: 点击SMS验证码选项
page.evaluate("""() => {
const items = document.querySelectorAll("[role=link]");
for (const item of items) {
const t = (item.innerText || "");
if (t.includes("验证码") || t.includes("verification code") || t.includes("••47")) {
item.click(); return;
}
}
}""")
time.sleep(6)
# Step 4: 通知外部就绪,等待验证码文件
with open(SIGNAL_FILE, "w") as f:
f.write("READY")
for i in range(120):
if os.path.exists(CODE_FILE):
with open(CODE_FILE, "r") as f:
code = f.read().strip()
if len(code) == 6 and code.isdigit():
break
time.sleep(1)
# Step 5: 输入验证码(用keyboard.type而非fill)
pin = page.query_selector("#idvPin")
pin.click()
time.sleep(0.5)
page.keyboard.type(code, delay=100) # 逐字符输入,更拟人
time.sleep(1)
# Step 6: 点击下一步
page.evaluate("""() => {
const btns = document.querySelectorAll("button");
for (const b of btns) {
const t = (b.innerText || "").trim();
if (t === "下一步" || t === "Next") { b.click(); return; }
}
}""")
time.sleep(10)
# Step 7: 验证登录
page.goto("https://mail.google.com", timeout=20000)
time.sleep(5)
if "mail.google.com" in page.url:
# 登录成功!保存Cookie
cookies = page.context.cookies()
with open(cookie_path, "w") as f:
json.dump(cookies, f)
前端操作流程
- 启动后台脚本:
terminal(background=true) - 等待信号文件:
while [ ! -f /tmp/gmail_signal.txt ]; do sleep 2; done - 告诉用户"验证码已发送,请查收短信"
- 用户给验证码后:
write_file("/tmp/gmail_code.txt", "123456") - 检查脚本输出:
process(action="poll")
备用验证码方式
如果SMS不可用,Google 2FA选择页会显示"请输入您的其中一个8位数备用验证码"。 选择"试试其他方式"可能触发安全锁定,**不要点!**直接在选择页找到备用验证码选项。
备用验证码格式: 8位数字(无空格),如 74361085
当前备用验证码保存在: /home/ubuntu/.hermes/credentials/accounts.md
与其他浏览器对比
| 方案 | Google登录 | navigator.webdriver | 适用场景 |
|---|---|---|---|
| CamouFox (CloakBrowser) | ✅ 通过 | ✅ false | Google/强反自动化站点 |
| Playwright Chromium | ❌ /signin/rejected | ❌ true | 普通网站 |
| DrissionPage Chromium | ❌ 被拦截 | ❌ true | ERP系统(妙手/通途) |
多IP多指纹并发
CamouFox 原生支持多IP + 多指纹并发,每个实例自动生成独立随机指纹,配合不同 proxy 实现完整账号隔离。
代理(多IP)
proxy 参数接受 dict,支持 HTTP/SOCKS5:
proxy={"server": "http://proxy-host:port", "username": "user", "password": "pass"}
配合 geoip=True 会自动通过代理获取出口IP,然后匹配对应的时区/语言/经纬度/WebRTC IP。
多指纹(每个实例独立)
每次启动 CamouFox 默认生成随机指纹(基于 BrowserForge),包括:User-Agent、屏幕分辨率、WebGL vendor/renderer、Canvas aaOffset、字体列表+spacing seed、插件/Navigator、窗口位置。每个实例 = 全新独立指纹,天然互不相同。
关键指纹控制参数:
| 参数 | 作用 |
|---|---|
os |
指纹OS平台:"windows"/"macos"/"linux" 或列表随机选 |
screen |
约束屏幕分辨率(browserforge.fingerprints.Screen 实例) |
window |
固定窗口大小 (width, height) |
fingerprint |
传入自定义 Fingerprint 对象(可序列化复用) |
webgl_config |
指定 WebGL vendor/renderer (vendor, renderer) |
locale |
指定语言环境 |
fonts |
附加字体列表 |
异步并发示例
from camoufox.async_api import AsyncCamoufox
async def run_account(proxy_server, target_os):
async with AsyncCamoufox(
headless=True, geoip=True, humanize=True,
proxy={"server": proxy_server},
os=target_os, # 不同OS指纹
) as browser:
page = await browser.new_page()
await page.goto("https://example.com")
指纹持久化(跨会话复用同一身份)
CamouFox 不自带指纹持久化,需手动管理:
from camoufox.fingerprints import generate_fingerprint
import json
# 生成并保存
fp = generate_fingerprint(os="windows")
with open("fingerprint_account1.json", "w") as f:
json.dump(fp.__dict__, f)
# 下次复用
from browserforge.fingerprints import Fingerprint
with open("fingerprint_account1.json") as f:
fp = Fingerprint(**json.load(f))
with Camoufox(headless=True, fingerprint=fp, geoip=True, proxy=...) as browser:
...
完整 launch_options 参数速查
| 参数 | 类型 | 说明 |
|---|---|---|
proxy |
Dict[str,str] |
代理 {"server","username","password"} |
os |
str/List[str] |
指纹OS:"windows"/"macos"/"linux" |
geoip |
bool/str |
True=自动查IP;或传IP字符串 |
humanize |
bool/float |
拟人鼠标移动,float=最大秒数 |
headless |
bool/str |
True无头;Linux下"virtual"用Xvfb |
fingerprint |
Fingerprint |
自定义BrowserForge指纹 |
screen |
Screen |
屏幕约束 |
window |
Tuple[int,int] |
固定窗口尺寸 |
locale |
str/List[str] |
语言环境 |
fonts |
List[str] |
附加字体 |
custom_fonts_only |
bool |
仅使用自定义字体 |
addons |
List[str] |
Firefox扩展路径 |
exclude_addons |
List[DefaultAddons] |
排除默认扩展 |
block_images |
bool |
屏蔽图片 |
block_webrtc |
bool |
屏蔽WebRTC |
block_webgl |
bool |
屏蔽WebGL |
webgl_config |
Tuple[str,str] |
指定WebGL (vendor, renderer) |
disable_coop |
bool |
禁用COOP(允许跨域iframe点击) |
enable_cache |
bool |
启用页面/请求缓存(多用内存) |
ff_version |
int |
Firefox版本号 |
main_world_eval |
bool |
允许主世界脚本执行 |
firefox_user_prefs |
Dict |
Firefox偏好设置 |
config |
Dict |
直接传Camoufox属性配置 |
i_know_what_im_doing |
bool |
抑制安全警告 |
反爬两层防御模型
很多网站的反爬系统分两层,必须同时突破才能访问:
| 层级 | 检测内容 | CamouFox能否绕过 | 解决方案 |
|---|---|---|---|
| 第1层:浏览器指纹 | navigator.webdriver, headless检测, Chrome runtime, 插件/字体指纹 | ✅ 天然绕过 | CamouFox本身 |
| 第2层:IP信誉 | 数据中心IP检测, 出口IP地理位置, IP历史行为 | ❌ 无法绕过 | 住宅代理(proxy参数) |
关键判断:如果CamouFox打开网站后仍被拦截(如1688的"Access denied"页面),说明是IP层被封锁,不是指纹层问题。此时唯一方案是配合住宅代理。
常见被IP层封锁的站点:
- 1688.com — 阿里云WAF,数据中心IP直接拒绝,必须用国内住宅代理
- Taobao.com — 同上,阿里云体系
- Google — 指纹+IP双层,但IP层通常只降权不直接拒绝
GFW 绕过
CamouFox 部署在境外服务器(如 HK)时,可以绕过 GFW 访问被墙的国际站点。 此场景下 Desktop(位于中国大陆)无法访问的网站(Imgur、Medium、Reddit 等), 服务器端 CamouFox 可直接加载。
使用模式:
- 服务器用 CamouFox 访问目标站点
- 遇到 CAPTCHA 时截图传给用户手动完成
- 完成后保存 session,后续自动化复用
已被墙站点(从中国 Desktop 无法访问): Imgur、Medium、Flipboard、Steemit CamouFox 能绕过但需 CAPTCHA: Reddit(有时超时)、Quora(Cloudflare Turnstile)、Pinterest(reCAPTCHA)
- fill() vs type(): 验证码输入框可能disabled,用
page.keyboard.type(code, delay=100)代替pin.fill(code) - storage_state无法恢复2FA会话: Google的2FA页面有一次性TL token,保存storage_state后恢复会得到Error 400
- 多次错误验证码 → 安全锁定: 连续3-4次验证码错误后,Google会显示"无法登录",需等待冷却
- 不要点"试试其他方式": 在2FA选择页点击此按钮可能直接触发安全锁定
- geoip=True很关键: 自动匹配IP的时区和语言,否则Google可能检测到不一致
- proxy务必配geoip: 用代理不设geoip会触发LeakWarning,地理位置与时区不一致易被检测
- Python路径: 必须用venv的python:
/home/ubuntu/.hermes/hermes-agent/venv/bin/python3 - IP层封锁诊断: 如果CamouFox打开页面仍被拒(标题含"Access denied"/URL含"punish"/"deny"),说明是IP层问题,需配proxy参数使用住宅代理