方法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');

// 使用 stealth 插件
puppeteer.use(StealthPlugin());

(async () => {
// 启动浏览器
const browser = await puppeteer.launch({ headless: false });
const page = await browser.newPage();

// 访问目标网站
await page.goto('https://example.com');

// 执行其他操作,比如截图或爬取数据
// await page.screenshot({ path: 'example.png' });

await browser.close();
})();

2. stealth 插件的工作原理

puppeteer-extra-plugin-stealth 通过多种方法来隐藏 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();

// 设置 cookies
const cookies = [
{
name: 'example_cookie',
value: 'cookie_value',
domain: 'example.com',
path: '/',
httpOnly: true,
secure: true,
expires: (Date.now() / 1000) + 3600 // 一小时后过期
}
];

// 打开目标网站之前设置 cookie
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();

// 登录并获取 cookies
await page.goto('https://example.com/login');
// 在这里执行登录步骤,比如输入用户名、密码

// 等待登录完成后获取 cookies
const cookies = await page.cookies();
fs.writeFileSync('cookies.json', JSON.stringify(cookies, null, 2)); // 保存 cookies

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();

// 加载保存的 cookies
const cookies = JSON.parse(fs.readFileSync('cookies.json', 'utf-8'));
await page.setCookie(...cookies);

// 使用 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 触发频率:

2. 手动解决 CAPTCHA

如果是个别 CAPTCHA,不需要自动化解决,可以通过 Puppeteer 将 CAPTCHA 页面暂停,人工完成验证,然后继续执行脚本。

1
2
3
4
await page.goto('https://example.com/captcha-page');
// 手动解决 CAPTCHA 后继续脚本
await page.waitForSelector('#captcha-solved-element'); // 等待 CAPTCHA 完成
console.log('CAPTCHA solved, continuing script...');

3. 使用第三方 CAPTCHA 解决服务

一些服务提供 CAPTCHA 解决方案(如 2CaptchaAnti-CaptchaDeathByCaptcha),通常收费,通过 API 将 CAPTCHA 图像发送给人工或 AI 进行解析。

示例代码(以 2Captcha 为例)

  1. 使用 axios 请求 CAPTCHA API
  2. 将结果应用到 Puppeteer 脚本

安装 axios

1
npm install 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');

// 获取 CAPTCHA 图片的 base64 编码
const captchaImage = await page.$('img#captcha');
const captchaBase64 = await captchaImage.screenshot({ encoding: "base64" });

// 使用 2Captcha API 解决 CAPTCHA
const response = await axios.post(`http://2captcha.com/in.php`, {
method: 'base64',
key: 'YOUR_2CAPTCHA_API_KEY', // 替换为真实 API 密钥
body: captchaBase64,
json: 1
});
const requestId = response.data.request;

// 轮询获取解析结果
let solvedCaptcha = null;
while (!solvedCaptcha) {
await new Promise(resolve => setTimeout(resolve, 5000)); // 等待 5 秒再查询
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;
}
}

// 将结果输入到 CAPTCHA 字段中
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');

// 获取 reCAPTCHA 的 sitekey
const sitekey = await page.$eval('.g-recaptcha', el => el.getAttribute('data-sitekey'));

// 请求第三方服务解决 reCAPTCHA 并获取 token
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;

// 获取 token 并提交
let token = null;
while (!token) {
await new Promise(resolve => setTimeout(resolve, 5000)); // 等待 5 秒再查询
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;
}
}

// 将 token 填入 reCAPTCHA 响应框并提交
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. 准备扩展文件

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, // 扩展在无头模式下不生效,因此这里需要设置为 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. 扩展加载调试

在扩展出现加载问题时,可以检查: