人机行为模拟:用 humanize=True 骗过行为检测
鼠标贝塞尔曲线、逐字输入、滚动加速——humanize=True 如何让爬虫操作通过 BrowserScan、deviceandbrowserinfo.com 等行为分析。
行为检测:指纹检测之后第二道防线
浏览器指纹能判断"你是什么设备",但无法判断"你是不是人"。行为检测补上了这一点——它分析鼠标移动、键盘输入、滚动操作的模式。
| 行为维度 | 机器人特征 | 人类特征 |
|---|---|---|
| 鼠标移动 | 瞬移(从 A 点到 B 点无中间轨迹) | 贝塞尔曲线路径,带加减速和轻微过冲 |
| 点击位置 | 完美命中按钮中心 | 分散在按钮区域内,有微小偏移 |
| 键盘输入 | 所有字符以相同间隔瞬时输入 | 逐字输入,速度不均,偶尔打错并修正 |
| 滚动 | 瞬间跳转 | 加速→巡航→减速的微步 |
| 操作间停顿 | 无停顿 | 有思考间隙,偶有无目的微移动 |
BrowserScan、DataDome、deviceandbrowserinfo.com 等检测服务专门分析这些行为特征。即使指纹完美伪装,行为模式仍然会暴露爬虫身份。
humanize=True:一个参数解决
CloakBrowser 的 humanize=True 拦截所有 Playwright 交互调用,自动替换为人类化版本:
from cloakbrowser import launch
browser = launch(humanize=True)
page = browser.new_page()
page.goto("https://example.com")
# 以下操作自动加入人类行为
page.locator("#email").fill("user@example.com") # 逐字输入,含思考停顿
page.locator("button[type=submit]").click() # 贝塞尔曲线路径
import { launch } from 'cloakbrowser';
const browser = await launch({ humanize: true });
鼠标行为的变化
| 交互 | 默认 Playwright | humanize=True |
|---|---|---|
| 鼠标移动 | 瞬间传送 | 贝塞尔曲线,带 easing 和轻微过冲 |
| 点击 | 瞬时 | 目标区域随机偏移点 + 按下保持时长 |
| fill() | 瞬间赋值 | 逐字输入,带思考停顿 |
| 滚动 | 跳转 | 加速→巡航→减速微步 |
| 键盘 | 瞬间填充 | 每字符独立 timing,偶尔打错并自行修正 |
实际检测效果
deviceandbrowserinfo.com 的行为检测有 24 项信号,CloakBrowser + humanize=True 全部通过:
from cloakbrowser import launch
browser = launch(headless=False, humanize=True)
page = browser.new_page()
# 访问行为检测测试页
page.goto("https://example.com")
# 无需额外操作,humanize 控制所有行为
page.wait_for_timeout(5000)
# 结果:行为检测 24/24 项通过,显示 "You are human!"
browser.close()
| 检测服务 | Stock Playwright | CloakBrowser + humanize |
|---|---|---|
| deviceandbrowserinfo.com | ❌ 标记为机器人 | ✅ You are human! |
| bot.incolumitas.com | 13 项失败 | 仅 WEBDRIVER 规范 1 项 |
| BrowserScan 行为分析 | 检测到自动化 | 正常 |
| reCAPTCHA v3 交互评分 | 0.1(明显降低) | 0.9(人类水平) |
预设与自定义配置
预设模式
# 默认模式——正常速度
browser = launch(humanize=True)
# 谨慎模式——更慢、更慎重
browser = launch(humanize=True, human_preset="careful")
careful 预设会让所有操作更慢,适合目标站特别严格的行为检测场景。
自定义参数
browser = launch(humanize=True, human_config={
"mistype_chance": 0.05, # 5% 打字错误率(含自动修正)
"typing_delay": 100, # 打字延迟(ms/字符)
"idle_between_actions": True, # 操作间空闲微移动
"idle_between_duration": [0.3, 0.8], # 空闲时长范围(秒)
})
const browser = await launch({
humanize: true,
humanConfig: {
mistype_chance: 0.05,
typing_delay: 100,
idle_between_actions: true,
idle_between_duration: [0.3, 0.8],
}
});
参数说明
| 参数 | 默认值 | 作用 |
|---|---|---|
mistype_chance | 0.02 | 打字错误概率(0-1),错误后自动回退修正 |
typing_delay | 50-200ms | 每字符击键间隔(可设固定值或范围) |
idle_between_actions | false | 两次操作间是否产生微移动 |
idle_between_duration | [0.5, 1.5] | 空闲微移动的时长范围(秒) |
重要限制
不是所有的 Playwright 方法都能被 humanize 拦截。以下规则需要注意:
✅ 被 humanize 覆盖的方法
page.click(selector)、page.type(selector, text)、page.hover(selector)page.fill(selector, text)、page.select_option()page.mouse.*、page.keyboard.*page.locator(selector).click()、.fill()、.type()、.hover()等page.evaluate()不受影响(保持原始行为)
❌ 不被 humanize 覆盖的方法
page.query_selector() 返回的 ElementHandle 对象绕过所有 humanize 补丁:
# ❌ 不推荐——ElementHandle 跳过 humanize
element = page.query_selector("#email")
element.click() # 瞬间移动,无贝塞尔曲线
element.type("text") # 瞬间输入,无逐字节奏
# ✅ 推荐——使用 Locator API,经过 humanize
page.locator("#email").click() # 贝塞尔曲线
page.locator("#email").fill("text") # 逐字输入
任何时候优先使用
locator而不是query_selector。 前者经过完整的人机模拟管道,后者返回的 ElementHandle 绕过所有补丁。
需要原始速度的场景
如果某个特定操作不需要 humanize(如批量数据导出),可以访问原始页面对象:
page._original.click("#export-button") # 跳过 humanize
与代理和行为检测的协同
行为检测不仅分析鼠标键盘,还会结合网络特征:
- 请求间隔是否均匀(机器定期请求 vs 人类随机浏览)
- 页面停留时间是否合理
合理配置后,CloakBrowser + humanize + 亿牛云住宅代理构成三层防御:
from cloakbrowser import launch
browser = launch(
proxy="http://user:pass@proxy.16yun.cn:8888",
geoip=True,
headless=False,
humanize=True,
human_preset="careful",
)
page = browser.new_page()
page.goto("https://example.com")
page.locator("#search").fill("data scraping")
page.locator(".search-btn").click()
page.wait_for_timeout(2000)
# 人类在浏览结果前会有 1-3 秒"阅读时间"
page.locator(".result-item").first().click()
采集时注意在请求之间加入随机化的等待时间,而不是固定间隔,进一步模拟人类浏览行为。
需要企业代理方案?
我们可根据目标站点、并发规模与稳定性目标提供定制方案。