From 4e79943d2772a7944e6d0df5e2a36bfa0cb78c19 Mon Sep 17 00:00:00 2001 From: admin9webs Date: Fri, 10 Jul 2026 16:12:01 +0800 Subject: [PATCH] Add browser-automation/cloakbrowser --- .../browser-automation/cloakbrowser/SKILL.md | 302 ++++++++++++++++++ 1 file changed, 302 insertions(+) create mode 100644 skills/browser-automation/cloakbrowser/SKILL.md diff --git a/skills/browser-automation/cloakbrowser/SKILL.md b/skills/browser-automation/cloakbrowser/SKILL.md new file mode 100644 index 0000000..d82fd1f --- /dev/null +++ b/skills/browser-automation/cloakbrowser/SKILL.md @@ -0,0 +1,302 @@ +--- +name: cloakbrowser +description: CamouFox反检测浏览器(CloakBrowser) — 完美通过所有bot检测,支持Google等强反自动化站点登录。含2FA文件轮询方案、备用验证码使用、常见陷阱。 +version: 1.0 +tags: [camoufox, anti-detection, google, 2fa, bot-detection] +--- + +# CloakBrowser (CamouFox Anti-Detection Browser) + +CamouFox是经过反检测改造的Firefox浏览器,在headless模式下完美通过所有bot检测。 + +## Gitea 镜像 + +- **源码镜像**: [admin9webs/CamouFox](https://gitea9webs.sh3.ikuai7.com/admin9webs/CamouFox) (~8MB, 不含bundle/) +- **上游**: [github.com/daijro/camoufox](https://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 持久化 + +## 安装与导入 + +```python +from camoufox.sync_api import Camoufox +``` + +无需额外安装,venv中已有camoufox包。 +Python路径: `/home/ubuntu/.hermes/hermes-agent/venv/bin/python3` + +## 基本启动参数 + +```python +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验证码失效!** +不能"先登录触发短信 → 等用户给码 → 重新登录输入",因为重新登录=新会话=旧码失效。 + +### 解决方案:后台脚本 + 文件轮询 + +用后台进程保持浏览器会话存活,通过文件传递验证码: + +```python +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: + +```python +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` | 附加字体列表 | + +### 异步并发示例 + +```python +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 不自带指纹持久化,需手动管理: + +```python +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(有时超时)、Quora(Cloudflare Turnstile)、Pinterest(reCAPTCHA) + +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参数使用住宅代理