方法1. IP/代理轮换 大多数机器人检测器的主要检测方式是通过检查IP。Web服务器可以通过维护每个请求的日志来推导IP地址的模式。
他们使用Web应用防火墙(WAF)跟踪和阻止IP地址活动,并将可疑IP列入黑名单。重复和编程的请求会损害IP信誉并导致永久封锁。
要避免机器人检测,您可以使用IP轮换或Puppeteer设置代理:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 const puppeteer = require('puppeteer'); (async () => { const browser = await puppeteer.launch({ args: [ '--proxy-server=http://your_proxy_ip:your_proxy_port', // Add any other Chrome flags you need ], }); const page = await browser.newPage(); // Now Puppeteer will use the proxy specified above await page.goto('https://example.com'); // Continue with your automation tasks await browser.close(); })();
方法2.旋转HTTP头信息和User-Agent 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 const puppeteer = require('puppeteer'); // 准备多个 User-Agent 和请求头配置 const userAgents = [ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36", "Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Mobile/15E148 Safari/604.1", // 更多 User-Agent ]; const headersList = [ { "Accept-Language": "en-US,en;q=0.9", "Referer": "https://example.com", "Connection": "keep-alive", }, { "Accept-Language": "zh-CN,zh;q=0.9", "Referer": "https://example.com", "Connection": "keep-alive", }, // 更多头部配置 ]; // 随机选择 User-Agent 和 Headers function getRandomConfig() { const userAgent = userAgents[Math.floor(Math.random() * userAgents.length)]; const headers = headersList[Math.floor(Math.random() * headersList.length)]; return { userAgent, headers }; } // 使用 Puppeteer 进行请求 (async () => { const browser = await puppeteer.launch({ headless: true }); const page = await browser.newPage(); // 获取随机的 User-Agent 和 Headers const { userAgent, headers } = getRandomConfig(); // 设置 User-Agent await page.setUserAgent(userAgent); // 设置额外的 HTTP 头 await page.setExtraHTTPHeaders(headers); // 打开页面 await page.goto('https://example.com', { waitUntil: 'networkidle2' }); // 执行其他操作... await browser.close(); })();
方法3. 禁用navigator.webdriver 默认情况下,Puppeteer将navigator.webdriver属性设置为true。这暴露了自动化工具的存在。通过禁用或修改此属性,您可以减少被检测的机会。
1 2 3 await page.evaluateOnNewDocument(() => { Object.defineProperty(navigator, 'webdriver', { get: () => false }); });
方法4. 使用stealth插件 要使用 puppeteer-extra-plugin-stealth,需要安装 puppeteer-extra 及其插件 puppeteer-extra-plugin-stealth。
1 npm install puppeteer puppeteer-extra puppeteer-extra-plugin-stealth
1. 如何在代码中使用 stealth 插件 puppeteer-extra-plugin-stealth 配置非常简单。通过引入 puppeteer-extra 并加载 stealth 插件,可以让 Puppeteer 自动隐藏其脚本痕迹。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 const puppeteer = require ('puppeteer-extra' );const StealthPlugin = require ('puppeteer-extra-plugin-stealth' );puppeteer.use (StealthPlugin ()); (async () => { const browser = await puppeteer.launch ({ headless : false }); const page = await browser.newPage (); await page.goto ('https://example.com' ); await browser.close (); })();
2. stealth 插件的工作原理 puppeteer-extra-plugin-stealth 通过多种方法来隐藏 Puppeteer 的痕迹:
隐藏 navigator.webdriver 属性,这一属性如果为 true,通常表明浏览器是自动化控制的。
模拟真实用户的 User-Agent 和屏幕分辨率。
修改浏览器的 webgl 和 canvas 参数,以避免被检测到伪造的指纹。
隐藏 chrome 属性中的特定方法,减少 Puppeteer 相关特征的暴露。
覆写 console.debug 和 console.info 等方法,减少暴露的 Puppeteer 日志信息。
方法5. 使用Cookie 1. 基本设置 Cookies 可以使用 page.setCookie() 方法在访问页面之前手动设置 Cookies,确保请求包含这些 Cookies。
示例代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 const puppeteer = require ('puppeteer' );(async () => { const browser = await puppeteer.launch ({ headless : false }); const page = await browser.newPage (); const cookies = [ { name : 'example_cookie' , value : 'cookie_value' , domain : 'example.com' , path : '/' , httpOnly : true , secure : true , expires : (Date .now () / 1000 ) + 3600 } ]; await page.setCookie (...cookies); await page.goto ('https://example.com' ); await browser.close (); })();
2. 从已登录页面提取并重用 Cookies 如果你有一个需要登录的页面,可以通过 Puppeteer 从已登录页面中提取 Cookies 并保存,之后可以在其他页面或会话中使用这些 Cookies。
示例代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 const puppeteer = require ('puppeteer' );const fs = require ('fs' );(async () => { const browser = await puppeteer.launch ({ headless : false }); const page = await browser.newPage (); await page.goto ('https://example.com/login' ); const cookies = await page.cookies (); fs.writeFileSync ('cookies.json' , JSON .stringify (cookies, null , 2 )); await browser.close (); })();
重新加载 Cookies 并访问页面 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 const puppeteer = require ('puppeteer' );const fs = require ('fs' );(async () => { const browser = await puppeteer.launch ({ headless : false }); const page = await browser.newPage (); const cookies = JSON .parse (fs.readFileSync ('cookies.json' , 'utf-8' )); await page.setCookie (...cookies); await page.goto ('https://example.com' ); await browser.close (); })();
3. 删除指定的 Cookies 可以使用 page.deleteCookie() 删除页面的指定 Cookies,以便在同一会话中模拟不同的用户状态。
1 await page.deleteCookie ({ name : 'example_cookie' , domain : 'example.com' });
4. 获取当前页面的所有 Cookies 使用 page.cookies() 方法可以获取当前页面的所有 Cookies 信息,以便进一步处理。
1 2 const currentCookies = await page.cookies ();console .log (currentCookies);
方法6. 使用CAPTCHA解答服务 CAPTCHA(”Completely Automated Public Turing test to tell Computers and Humans Apart”)是一种用来区分真实用户和自动化脚本的验证机制。为了在自动化脚本(如 Puppeteer)中处理 CAPTCHA,有几个常见的方式。
1. 绕过 CAPTCHA 有些简单的网站的 CAPTCHA 可能只会在可疑流量出现时触发。在 Puppeteer 中可以用以下方法减少 CAPTCHA 触发频率:
使用随机 User-Agent :在每次请求时使用不同的 User-Agent,可以参考上面的方式实现。
加入延迟和模拟真实用户行为 :可以设置适当的 page.waitForTimeout() 延迟,模拟真实用户的访问行为。
2. 手动解决 CAPTCHA 如果是个别 CAPTCHA,不需要自动化解决,可以通过 Puppeteer 将 CAPTCHA 页面暂停,人工完成验证,然后继续执行脚本。
1 2 3 4 await page.goto ('https://example.com/captcha-page' );await page.waitForSelector ('#captcha-solved-element' ); console .log ('CAPTCHA solved, continuing script...' );
3. 使用第三方 CAPTCHA 解决服务 一些服务提供 CAPTCHA 解决方案(如 2Captcha、Anti-Captcha 和 DeathByCaptcha),通常收费,通过 API 将 CAPTCHA 图像发送给人工或 AI 进行解析。
示例代码(以 2Captcha 为例) :
使用 axios 请求 CAPTCHA API
将结果应用到 Puppeteer 脚本
安装 axios:
解决 CAPTCHA 的步骤 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 const puppeteer = require ('puppeteer' );const axios = require ('axios' );(async () => { const browser = await puppeteer.launch ({ headless : false }); const page = await browser.newPage (); await page.goto ('https://example.com/captcha-page' ); const captchaImage = await page.$('img#captcha' ); const captchaBase64 = await captchaImage.screenshot ({ encoding : "base64" }); const response = await axios.post (`http://2captcha.com/in.php` , { method : 'base64' , key : 'YOUR_2CAPTCHA_API_KEY' , body : captchaBase64, json : 1 }); const requestId = response.data .request ; let solvedCaptcha = null ; while (!solvedCaptcha) { await new Promise (resolve => setTimeout (resolve, 5000 )); const result = await axios.get (`http://2captcha.com/res.php?key=YOUR_2CAPTCHA_API_KEY&action=get&id=${requestId} &json=1` ); if (result.data .status === 1 ) { solvedCaptcha = result.data .request ; } } await page.type ('#captcha-input' , solvedCaptcha); await page.click ('#captcha-submit-button' ); await browser.close (); })();
4. reCAPTCHA 解决方法 一些服务(如 2Captcha、Anti-Captcha)支持 reCAPTCHA v2 和 v3。与传统 CAPTCHA 不同,reCAPTCHA 需要解析 sitekey 并调用 Google 的接口来生成 token。
示例(针对 reCAPTCHA v2 的 sitekey):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 await page.goto ('https://example.com/recaptcha-page' );const sitekey = await page.$eval('.g-recaptcha' , el => el.getAttribute ('data-sitekey' ));const tokenResponse = await axios.get (`http://2captcha.com/in.php?key=YOUR_API_KEY&method=userrecaptcha&googlekey=${sitekey} &pageurl=https://example.com/recaptcha-page` );const tokenRequestId = tokenResponse.data .request ;let token = null ;while (!token) { await new Promise (resolve => setTimeout (resolve, 5000 )); const tokenResult = await axios.get (`http://2captcha.com/res.php?key=YOUR_API_KEY&action=get&id=${tokenRequestId} ` ); if (tokenResult.data .status === 1 ) { token = tokenResult.data .request ; } } await page.evaluate (token => { document .querySelector ('#g-recaptcha-response' ).value = token; }, token); await page.click ('#captcha-submit-button' );
5. 使用 Puppeteer Cluster 自动处理 CAPTCHA puppeteer-cluster 是 Puppeteer 的高级库,提供并发和任务队列管理。结合 puppeteer-extra-plugin-stealth,可以创建任务集群,自动处理请求中的 CAPTCHA,提升效率。
方法7. 延迟输入和随机化 真实用户无法在一分钟内发出500个请求!
真实用户也无法有固定的浏览习惯和程序!
因此,为了防止被反机器人系统轻易检测到,我们需要在使用Puppeteer时,为自动化程序设置延迟输入和一些随机化操作。这样可以模拟真实用户,从而在一定程度上降低被检测的风险。
1 await page.type('input[name=username]', 'myUsername', { delay: 100 }); await page.type('input[name=password]', 'myPassword', { delay: 100 });
1 2 await page.mouse.move(100, 100); await page.mouse.click(100, 100);
方法8. 使用浏览器扩展 在 Puppeteer 中使用浏览器扩展可以通过 --load-extension 参数来加载指定的 Chrome 扩展。这对于使用一些特定功能的扩展(如广告拦截、代理插件等)非常有用。以下是如何在 Puppeteer 中加载和使用浏览器扩展的步骤。
1. 准备扩展文件
如果扩展来自于 Chrome Web Store,可以通过下载 .crx 文件后解压缩来获得扩展的文件夹,或者直接使用已解压的扩展。
将扩展文件夹放置在项目中某个路径,记住该路径以便稍后使用。
2. 使用 Puppeteer 加载扩展 使用 Puppeteer 的 launch 方法加载扩展:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 const puppeteer = require ('puppeteer' );(async () => { const browser = await puppeteer.launch ({ headless : false , args : [ `--load-extension=/path/to/extension` , `--disable-extensions-except=/path/to/extension` ] }); const page = await browser.newPage (); await page.goto ('https://example.com' ); await browser.close (); })();
3. 与扩展进行交互
4. 扩展加载调试 在扩展出现加载问题时,可以检查:
确认路径正确无误。
headless 设置为 false,因为在无头模式下大多数扩展无法运行。