Puppeteer访问站点页面加载前被reCAPTCHA拦截问题咨询
问题原因
这类拦截本质是站点的反爬/WAF系统识别到了你用的是自动化浏览器,而非真人操作的普通浏览器,和IP地址没有关系(同IP下手动开Chrome能正常访问就可以排除IP封禁的可能)。常见的检测点包括:
- 默认启动的Puppeteer会在浏览器环境里留下明确的自动化标记,最典型的就是
navigator.webdriver属性值为true,普通用户打开的Chrome里这个值为false/undefined,属于最基础的检测规则。 - 旧版Puppeteer无头模式的浏览器特征和真实Chrome差异极大:缺少Chrome自带的默认插件、
navigator.plugins/navigator.languages等属性返回值不符合真实浏览器逻辑、Canvas/WebGL渲染指纹和真实Chrome不一致、请求头顺序/TLS握手指纹和真实浏览器存在差异,这些特征组合起来很容易被规则命中。 - 默认Puppeteer操作没有人类用户的行为特征:页面打开后没有随机的鼠标移动、滚动、停留,操作间隔固定,很容易被行为分析模型判定为机器人。
解决方案
按优先级从易到难试,大部分场景下前两步就能解决问题:
基础配置优化
- 不要用旧版无头模式,启动时将headless参数设置为
'new',新版Chrome的无头模式对真实浏览器的特征还原度远高于旧版本;调试阶段可以先开有头模式跑,确认访问正常再切无头。 - 启动Puppeteer时去掉默认的自动化标识,参考配置如下:
const browser = await puppeteer.launch({ headless: 'new', executablePath: '你本地正常访问站点的Chrome程序路径', // 优先用本地真实Chrome,不要用Puppeteer自带的阉割版 args: [ '--disable-blink-features=AutomationControlled', '--start-maximized', '--no-sandbox', '--disable-dev-shm-usage' ], ignoreDefaultArgs: ['--enable-automation'], defaultViewport: null })
- 在页面加载前提前注入JS,覆写最容易被检测的环境属性:
await page.evaluateOnNewDocument(() => { Object.defineProperty(navigator, 'webdriver', { get: () => false }) window.chrome = { runtime: {}, loadTimes: () => {}, csi: () => {}, app: {} } Object.defineProperty(navigator, 'plugins', { get: () => [1,2,3,4,5] }) Object.defineProperty(navigator, 'languages', { get: () => ['en-US', 'en'] }) const originalQuery = window.navigator.permissions.query window.navigator.permissions.query = params => params.name === 'notifications' ? Promise.resolve({ state: Notification.permission }) : originalQuery(params) })
成熟反检测方案
自己手写所有特征覆写很容易漏检测点,直接用puppeteer-extra搭配puppeteer-extra-plugin-stealth插件即可,这个插件已经覆盖了目前公开的所有Puppeteer自动化特征点,不需要自己手动写注入逻辑,用法很简单:
const puppeteer = require('puppeteer-extra') const StealthPlugin = require('puppeteer-extra-plugin-stealth') puppeteer.use(StealthPlugin()) // 后续启动浏览器、操作页面的逻辑和原生Puppeteer完全一致
- 操作逻辑里加拟真行为:不要页面刚加载完就立刻提取数据,加0.5-3秒的随机等待,穿插随机的鼠标移动、小幅页面滚动操作,所有操作间隔不要用固定时长,加随机扰动,模拟真人操作的时序特征。
- 控制访问频率,不要短时间内高频请求同一个站点,就算是真人用户一秒内刷新多次页面也会被弹验证码。
强反爬场景适配
如果上面的操作都做完还是被拦截,说明站点做了更深度的指纹校验(比如TLS指纹、鼠标轨迹建模、Canvas指纹追踪),可以直接换用Playwright框架写采集逻辑,它默认的浏览器指纹伪装能力比原生Puppeteer强很多,大部分场景下不需要额外加反检测插件就能绕过基础拦截。
内容的提问来源于stack exchange,提问作者Tanner Helton
相关产品推荐
相关产品推荐

