Puppeteer设置浏览器代理的三种思路

本文探讨了在使用Puppeteer框架操作浏览器时设置代理的三种主要方法:通过启动参数直接设置、通过自定义代理服务器控制逻辑以及利用拦截器与第三方库实现动态代理更换。这些方法适用于不同场景,如大规模系统中的统一代理管理和小规模系统中的灵活代理切换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

0 背景

Puppeteer是google推出的操作浏览器的框架。当我们通过框架操作浏览器去访问页面通常需要设置代理。本文简要总结设置代理的方式。

1 通过启动参数设置代理

我们通过puppeteer启动浏览通常可以指定参数,通过–proxy-server参数[1]指定代理。http及https请求的将通过代理服务器访问。若每次需要更换代理就需要重新通过launch方法来启动浏览器。

    const browser = await puppeteer.launch({
        args: [
            '--disable-setuid-sandbox',
            '--no-sandbox',
            '--proxy-server=10.24.51.125:8411',
            '--ignore-certificate-errors',
            '--window-size=375,812',
            '--remote-debugging-port=9222'
        ],
        ignoreHTTPSErrors: true,
        headless: false,
        executablePath: "/chrome-mac/Chromium.app/Contents/MacOS/Chromium",
    });

这种方式启动后,默认会有一个打开的page,因此不用再重新打开page对象。用默认的page进行后续访问即可。

const [page] = await browser.pages();

2 通过代理服务器控制代理逻辑

可以看到–proxy-server设置了代理后,如果ip是一个固定的目标代理地址那么需要重新启动浏览器才能更换。如果我们自己开发了一个代理服务,与实际代理机器交互的逻辑都集中在这个服务上,那么实际代理机器的访问通过我们的代理服务控制,这样我们每次启动浏览器后就固定一个地址即可。

图1

3 通过拦截器与第三方库实现设置代理功能

1中介绍的方式需要每次重新调用launch方法启动浏览器更换IP。但我们知道现在很多http库都可以设置代理。例如在Java中可以通过okhttp,unirest等库来设置代理。同理nodejs中也有这样的库。我们不再通过–proxy-server指定地址,而是通过puppeteer的拦截器功能,将请求拦截,随后改写请求。再通过第三方的http库设置上代理信息。这样就可以达到不通过launch重启浏览器而是直接在一个page中设置代理的目的。每次有新请求来了也可以达到动态变化的目标。不过这样处理逻辑还是比较复杂,涉及改写请求,响应结果缓存处理等问题。这篇讨论[2]已经给出了处理方式,可以参考。

4 总结

如果在上规模的系统中代理控制一般统一由统一的代理服务来管理,使用时通过proy-server指定代理信息即可。如果是小规模系统,都是集中式控制可以考虑使用1,3的方式处理。

5 参考资料

[1]chrome命令行参数,https://peter.sh/experiments/chromium-command-line-switches/
[2]代理设置的几种方法讨论,https://github.com/GoogleChrome/puppeteer/issues/678

### 如何使用 Puppeteer 设置浏览器默认下载路径 在 Puppeteer 中,默认情况下无法直接通过 API 配置文件的下载路径,因为 Chromium 的设计不支持直接修改下载目录。然而,可以通过设置实验性的 Chrome 标志 `--download-path` 或者监听页面事件并手动处理下载行为来间接实现这一目标。 以下是具体实现方式: #### 使用实验性标志配置下载路径 可以尝试通过启动选项中的 `args` 参数指定自定义的命令行标志来更改下载路径。虽然这种方法并非完全可靠,但在某些场景下可能有效。 ```javascript const puppeteer = require('puppeteer'); (async () => { const downloadPath = '/custom/path/to/downloads'; // 自定义下载路径 const browser = await puppeteer.launch({ headless: false, args: [ `--download-path=${downloadPath}` // 尝试设置下载路径 ] }); const page = await browser.newPage(); await page.goto('https://example.com/file-to-download'); console.log(`File will be downloaded to ${downloadPath}`); await browser.close(); })(); ``` 需要注意的是,上述方法依赖于特定版本的 Chromium 支持,并且不一定适用于所有环境[^1]。 --- #### 手动捕获下载链接并保存到指定位置 更可靠的解决方案是拦截下载请求并将文件保存到期望的位置。这通常涉及以下几个步骤: 1. 捕获页面上的点击或其他触发下载的行为。 2. 获取下载 URL 并通过 Node.js 文件系统模块 (`fs`) 下载文件。 3. 将文件存储至指定路径。 下面是一个完整的示例代码: ```javascript const fs = require('fs'); const axios = require('axios'); // 用于发起 HTTP 请求 const puppeteer = require('puppeteer'); (async () => { const customDownloadDir = './downloads'; if (!fs.existsSync(customDownloadDir)) { fs.mkdirSync(customDownloadDir); } const browser = await puppeteer.launch({ headless: true }); const page = await browser.newPage(); // 跳转到包含下载按钮的目标网页 await page.goto('https://example.com/page-with-file-link'); // 监听 "response" 事件以检测下载资源 page.on('response', async response => { const url = response.url(); // 判断是否为要下载的内容(可以根据 MIME 类型判断) if (url.includes('.pdf') || url.includes('.zip')) { // 假设我们要下载 PDF 和 ZIP 文件 try { const fileStream = fs.createWriteStream(`${customDownloadDir}/${new Date().getTime()}-${url.split('/').pop()}`); const writer = new Promise((resolve, reject) => { fileStream.on('finish', resolve); fileStream.on('error', reject); }); const responsePromise = axios({ method: 'GET', url, responseType: 'stream' }).then(response => { response.data.pipe(fileStream); return response; }); await Promise.all([writer, responsePromise]); console.log(`File saved successfully at: ${fileStream.path}`); } catch (err) { console.error('Error downloading the file:', err.message); } } }); // 触发下载操作(例如模拟点击某个按钮) await page.click('#downloadButton'); await new Promise(resolve => setTimeout(resolve, 5000)); // 等待几秒确保完成下载 await browser.close(); })(); ``` 在此示例中,通过监听响应事件以及结合 Axios 库实现了对文件的手动管理[^4]。 --- ### 注意事项 - 如果需要更高的兼容性和稳定性,建议采用第二种方案(即手动控制下载流程),因为它不受制于底层浏览器的具体实现细节。 - 对于生产环境中运行的任务,请务必验证所使用的 Chromium 版本及其特性支持情况[^2]。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值