Files

303 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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(有时超时)、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参数使用住宅代理