Files

12 KiB
Raw Permalink Blame History

name, description, version, tags
name description version tags
cloakbrowser CamouFox反检测浏览器(CloakBrowser) — 完美通过所有bot检测,支持Google等强反自动化站点登录。含2FA文件轮询方案、备用验证码使用、常见陷阱。 1.0
camoufox
anti-detection
google
2fa
bot-detection

CloakBrowser (CamouFox Anti-Detection Browser)

CamouFox是经过反检测改造的Firefox浏览器,在headless模式下完美通过所有bot检测。

Gitea 镜像

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)

前端操作流程

  1. 启动后台脚本: terminal(background=true)
  2. 等待信号文件: while [ ! -f /tmp/gmail_signal.txt ]; do sleep 2; done
  3. 告诉用户"验证码已发送,请查收短信"
  4. 用户给验证码后: write_file("/tmp/gmail_code.txt", "123456")
  5. 检查脚本输出: 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 可直接加载。

使用模式:

  1. 服务器用 CamouFox 访问目标站点
  2. 遇到 CAPTCHA 时截图传给用户手动完成
  3. 完成后保存 session,后续自动化复用

已被墙站点(从中国 Desktop 无法访问): Imgur、Medium、Flipboard、Steemit CamouFox 能绕过但需 CAPTCHA Reddit(有时超时)、QuoraCloudflare Turnstile)、PinterestreCAPTCHA

  1. fill() vs type(): 验证码输入框可能disabled,用page.keyboard.type(code, delay=100)代替pin.fill(code)
  2. storage_state无法恢复2FA会话: Google的2FA页面有一次性TL token,保存storage_state后恢复会得到Error 400
  3. 多次错误验证码 → 安全锁定: 连续3-4次验证码错误后,Google会显示"无法登录",需等待冷却
  4. 不要点"试试其他方式": 在2FA选择页点击此按钮可能直接触发安全锁定
  5. geoip=True很关键: 自动匹配IP的时区和语言,否则Google可能检测到不一致
  6. proxy务必配geoip: 用代理不设geoip会触发LeakWarning,地理位置与时区不一致易被检测
  7. Python路径: 必须用venv的python: /home/ubuntu/.hermes/hermes-agent/venv/bin/python3
  8. IP层封锁诊断: 如果CamouFox打开页面仍被拒(标题含"Access denied"/URL含"punish"/"deny"),说明是IP层问题,需配proxy参数使用住宅代理