Headless Chrome 运行时没有可见窗口 - 快速、轻量级,非常适合服务器。但验证码系统会主动检测无头模式。以下是如何选择正确的模式并解决两种模式中的验证码问题。
快速比较
| 因素 | headless 模式 | headed 模式 |
|---|---|---|
| 速度 | 快速(无渲染开销) | 速度较慢(呈现 UI) |
| 记忆 | 〜100-200 MB | 〜300-500 MB |
| 服务器部署 | 本国的 | 需要虚拟显示 |
| 验证码检测 | 高(可检测信号) | 低(看起来像真实用户) |
| reCAPTCHA v3 分数 | 0.1-0.3(机器人范围) | 0.7-0.9(人类范围) |
| 调试 | 更难(无视觉) | 简单(见页面) |
| 缩放 | 优秀(资源少) | 资源密集型 |
验证码如何检测 Headless Chrome
检测信号
// Tests that CAPTCHA systems run
// 1. WebDriver flag (biggest tell)
navigator.userAgent // true in headless, undefined in real browser
// 2. Chrome object completeness
window.chrome // Missing or incomplete in headless
// 3. Plugins
navigator.plugins.length // 0 in headless, 3+ in headed
// 4. WebGL renderer
// Headless: "SwiftShader Renderer"
// Headed: "ANGLE (NVIDIA GeForce GTX 1080...)"
// 5. User-Agent contains "Headless"
navigator.userAgent.includes("Headless") // Old Chrome versions
// 6. Screen dimensions
screen.width === 0 // Some headless configs
// 7. Notification permission
Notification.permission // "denied" in headless without override
检测结果
Signal Headed Headless New Headless (v112+)
─────────────────────────────────────────────────────────────
webdriver false true true
chrome object full partial improved
plugins 5 0 0
WebGL renderer ANGLE Swift Swift
screen.width 1920 800 800
UA "HeadlessChrome" no yes no (removed)
Chrome 的“新 Headless”模式 (v112+)
Chrome 112+ 引入了 --headless=new,它使用与 Chrome 相同的代码库:
from selenium import webdriver
# Old headless (more detectable)
options = webdriver.ChromeOptions()
options.add_argument("--headless") # Legacy mode
# New headless (less detectable)
options = webdriver.ChromeOptions()
options.add_argument("--headless=new") # Shares headed rendering
driver = webdriver.Chrome(options=options)
新的无头模式修复了一些检测向量,但仍然暴露 navigator.userAgent 并且没有插件。
无头 + CaptchaAI (Python)
CaptchaAI 在无头模式下同样工作得很好,因为它在服务器端解决验证码 - 浏览器模式不会影响解决 API:
import requests
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
API_KEY = "YOUR_API_KEY"
API_URL = "https://ocr.captchaai.com"
def create_headless_driver():
options = webdriver.ChromeOptions()
options.add_argument("--headless=new")
options.add_argument("--no-sandbox")
options.add_argument("--no-sandbox")
options.add_argument("--window-size=1920,1080")
options.add_argument(
"--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36"
)
return webdriver.Chrome(options=options)
def solve_captcha(site_url, sitekey):
resp = requests.post(f"{API_URL}/in.php", data={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": site_url,
"json": 1,
})
task_id = resp.json()["request"]
for _ in range(60):
time.sleep(5)
resp = requests.get(f"{API_URL}/res.php", params={
"key": API_KEY, "action": "get",
"id": task_id, "json": 1,
})
data = resp.json()
if data["request"] != "CAPCHA_NOT_READY":
return data["request"]
raise TimeoutError("Solve timeout")
# Full headless workflow
driver = create_headless_driver()
try:
driver.get("https://example.com/form")
time.sleep(2)
sitekey = driver.execute_script(
"return document.querySelector('[data-sitekey]')?.getAttribute('data-sitekey')"
)
if sitekey:
token = solve_captcha(driver.current_url, sitekey)
driver.execute_script(f"""
document.querySelector('#g-recaptcha-response').value = '{token}';
""")
driver.find_element(By.CSS_SELECTOR, "form").submit()
finally:
driver.quit()
面向服务器(虚拟显示)
使用 Xvfb 在无头服务器上运行有头 Chrome:
Linux 与 Xvfb
# Install
sudo apt-get install xvfb
# Run with virtual display
xvfb-run --auto-servernum --server-args="-screen 0 1920x1080x24" python script.py
Python 与 PyVirtualDisplay
from pyvirtualdisplay import Display
from selenium import webdriver
display = Display(visible=0, size=(1920, 1080))
display.start()
options = webdriver.ChromeOptions()
# No --headless flag = headed mode in virtual display
options.add_argument("--no-sandbox")
options.add_argument("--window-size=1920,1080")
driver = webdriver.Chrome(options=options)
# Now runs headed Chrome with real rendering, but no physical display
Docker 与 Xvfb
FROM python:3.12-slim
RUN apt-get update && apt-get install -y \
xvfb \
chromium \
chromium-driver \
&& rm -rf /var/lib/apt/lists/*
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . /app
WORKDIR /app
CMD ["xvfb-run", "--auto-servernum", "python", "main.py"]
无头 + 标准补丁 (Node.js)
const puppeteer = require("puppeteer-extra");
const StealthPlugin = require("puppeteer (默认配置)");
puppeteer.use(StealthPlugin());
async function headlessStealth() {
const browser = await puppeteer.launch({
headless: "new",
args: [
"--no-sandbox",
"--window-size=1920,1080",
"--no-sandbox",
],
});
const page = await browser.newPage();
await page.setViewport({ width: 1920, height: 1080 });
// Additional QA patches
await page.evaluateOnNewDocument(() => {
Object.defineProperty(navigator, "webdriver", {
get: () => undefined,
});
Object.defineProperty(navigator, "plugins", {
get: () => [1, 2, 3, 4, 5],
});
});
await page.goto("https://example.com/form");
// Detect and solve CAPTCHA with CaptchaAI
const sitekey = await page.evaluate(() =>
document.querySelector("[data-sitekey]")?.getAttribute("data-sitekey")
);
if (sitekey) {
// Call CaptchaAI API (see other guides for full implementation)
const token = await solveCaptchaAI(page.url(), sitekey);
await page.evaluate((t) => {
document.querySelector("#g-recaptcha-response").value = t;
}, token);
}
await browser.close();
}
何时使用每种模式
在以下情况下使用 Headless:
- 在服务器上运行/CI而不显示
- 扩展到 50+ 并发会话
- 内存有限
- CaptchaAI 处理所有验证码解决(浏览器模式无关)
在以下情况下使用标题:
- 直观地调试验证码流
- reCAPTCHA v3 scores matter (higher scores in headed)
- 目标站点专门阻止无头
- 在带有显示屏的机器上运行
在以下情况下使用标题 + 虚拟显示:
- 服务器上需要高级检测阻力
- reCAPTCHA v3 在 headless 中给出低分
- 预算允许额外的内存(每个会话约 2 倍)
性能基准
| 设想 | 无头 | 为首 | 标题 + Xvfb |
|---|---|---|---|
| 启动时间 | 〜1秒 | 〜2秒 | ~2.5秒 |
| 每个选项卡的内存 | 100-200MB | 300-500MB | 300-500MB |
| 页面加载(平均) | 1.5秒 | 2.5秒 | 2.5秒 |
| reCAPTCHA v3 分数 | 0.1-0.3 | 0.7-0.9 | 0.5-0.8 |
| 最大并发数 (8GB) | 30-40 | 10-15日 | 10-15日 |
| 验证码解决率 | 相同(API) | 相同(API) | 相同(API) |
关键见解: 无论浏览器模式如何,CaptchaAI 解决率都是相同的。该模式仅影响验证码出现的频率和 reCAPTCHA v3 分数。
故障排除
| 问题 | 原因 | 处理方式 |
|---|---|---|
| 检测到无头 | navigator.userAgent 标志 |
使用隐形插件或 CDP 补丁 |
| headless 中 v3 分数低 | 缺少渲染信号 | 切换到 Headed + Xvfb |
| Xvfb 崩溃 | 显示号码冲突 | 使用--auto-servernum |
| 头部记忆力高 | GPU进程 | 添加 --disable-gpu 标志 |
| 无头时截图空白 | 视口错误 | 设置 --window-size=1920,1080 |
常问问题
CaptchaAI 关心我使用无头还是有头吗?
不会。CaptchaAI 使用 sitekey 和 URL 在服务器端解析验证码。浏览器模式不影响求解。
新的无头模式 (--headless=new) 是否不会被检测到?
它比旧的无头更好,但仍然可以检测到。检查 navigator.userAgent 或插件计数的站点仍会对其进行标记。
我可以在 Headless 中获得高于 0.7 的 reCAPTCHA v3 分数吗?
很少。无头模式产生类似机器人的信号。使用 head + Xvfb 获得更高分数,或使用 CaptchaAI 的 v3 求解返回高分标记。
我应该投资标准补丁还是只使用 CaptchaAI?
两个都。隐形降低了验证码频率(更少的解决=更低的成本)。 CaptchaAI 处理仍然出现的验证码。
相关指南
- 浏览器QA 配置和验证码
- Puppeteer隐身 + CaptchaAI
- Chrome DevTools 协议 + CaptchaAI
为您的验证码工作流程选择正确的浏览器模式 -获取您的 CaptchaAI 密钥并在任何配置中解决验证码。