前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一日一技:Puppeteer 不重启如何更换代理 IP

一日一技:Puppeteer 不重启如何更换代理 IP

作者头像
青南
发布2021-12-21 18:16:55
3K0
发布2021-12-21 18:16:55
举报
文章被收录于专栏:未闻Code未闻Code

我们知道,在写爬虫的过程中,如果总是使用同一个 IP,很容易就会被网站识别并封禁,所以需要使用代理 IP 并经常更换。

但如果你在网上搜索 Puppeteer 如何更换代理 IP,你会发现,网上的解决方案一般是这样写的:

代码语言:javascript
复制
const puppeteer = require('puppeteer');

(async() => {
  const browser = await puppeteer.launch({
    args: [ '--proxy-server=123.45.67.89:8888' ]
  });
  const page = await browser.newPage();
  await page.goto('http://httpbin.org/ip');
  await browser.close();
})();

这种写法有一个问题,如果你要更换 IP,必须重启爬虫。那么有没有办法不重启爬虫也能更换代理 IP 呢?

方法有,并且有两个。

隧道代理

对一些网站来说,只要每次访问的 IP 不一样就可以避免被封禁,那么我们可以使用隧道代理。隧道代理供应商会给我们提供一个唯一的域名和端口。我们把它设置为爬虫的代理就可以了。代理供应商会在后端自动给每一次请求更换 IP,不用我们来操心。

我们使用青果云[1]的隧道代理来做演示。它可以免费试用2小时。我获取到的代理 IP 地址为:http://D5A913AF:B1DE2C46D321@tunnel.qg.net:11151。于是,我可以修改上面的 Puppeteer 代码中的 IP 地址:

代码语言:javascript
复制
const puppeteer = require('puppeteer-core');

(async() => {
  const browser = await puppeteer.launch({
    args: [ '--proxy-server=tunnel.qg.net:11151' ], headless: false, executablePath: '/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge'});
  const page = await browser.newPage();
  await page.authenticate({username: '账号', password: '密码'});  // 如果代理没有权限验证,可以移除这一行
  response = await page.goto('http://httpbin.org/ip');
  console.log('第一次访问: ', await response.text());
  response = await page.goto('http://httpbin.org/ip');
  console.log('第二次访问: ', await response.text());
})()

运行效果如下图所示:

动态按需修改代理 IP

IP 并不是换得越频繁越好。如果网站需要登录,那么你登录以后每一次请求都更换 IP,这反而会弄巧成拙,让网站更加怀疑你是不是爬虫。还有一些网站,例如淘宝,当你访问一个页面的时候,它会自动301跳转多次。在这几次跳转的时候,你必须保持 IP 一致,否则它就会屏蔽你。

我们有时候需要实现按需更换代理 IP——让开发者在需要更换 IP 的时候,再来更换。

为了让 Puppeteer 实现这个目标,我们可以安装一个第三方模块:puppeteer-page-proxy

代码语言:javascript
复制
npm i puppeteer-page-proxy

安装完成以后,我们来使用看看:

代码语言:javascript
复制
const puppeteer = require('puppeteer-core')
const useProxy = require('puppeteer-page-proxy')


puppeteer.launch({headless: false, executablePath: '/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge'}).then(
    async browser => {
        console.log('start...')
        const page = await browser.newPage()

        await useProxy(page, 'http://账号:密码@119.5.228.105:21477')
        console.log('change proxy success, start to visit url')
        resp = await page.goto('http://httpbin.org/ip')
        console.log(await resp.text())

        await useProxy(page, 'http://账号:密码@119.41.199.19:56214')
        console.log('change proxy success, start to visit url')
        resp = await page.goto('http://httpbin.org/ip')
        console.log(await resp.text())
        }
)

运行效果如下图所示:

当我们需要更换 IP 的时候,只需要在代码里面执行await useProxy(page, 'http://账号:密码@IP:端口'),就可以更换新的 IP 了。如果你的代理 IP 没有账号密码,那么可以把代码改成:await useProxy(page, 'http://IP:端口')

可能有人会问,你上面的示例代码中,你是直接把代理填写到代码里面的。如果我需要访问某个 URL 来获取新的代理怎么办呢?其实这也很简单,你可以再安装一个第三方模块:axios用来发起网络请求获取新的代理 IP,然后再替换:

代码语言:javascript
复制
npm i axios

还是以青果云的短效代理 IP 为例,它可以提供一个接口,访问接口后,你能得到一个有效期5-15分钟的短效 IP,如下图所示:

开通试用账号以后,你可以获得一个提取代理的 URL,类似于下面这样:

代码语言:javascript
复制
https://proxy.qg.net/extract?Key=ABCDEFGH&Num=1&AreaId=&Isp=&DataFormat=txt&DataSeparator=%5Cn&Detail=0

访问以后就能拿到代理IP,如下图所示:

现在,我们要在 Puppeteer 里面,先访问这个 URL 获取代理,再把代理IP 设置到 Puppeteer 中,然后再访问目标网页。对应的代码如下:

代码语言:javascript
复制
const puppeteer = require('puppeteer-extra')
const useProxy = require('puppeteer-page-proxy')
const axios = require('axios')

async function set_proxy(page){
    resp = await axios.get('https://proxy.qg.net/extract?Key=ABCDEFG&Num=1&AreaId=&Isp=&DataFormat=txt&DataSeparator=%5Cn&Detail=0')
    proxy = 'http://账号:密码@' + resp.data
    console.log('获取到的代理 IP 为:', proxy)
    await useProxy(page, proxy)
}

puppeteer.launch({headless: false, executablePath: '/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge'}).then(
    async browser => {
        console.log('start...')
        const [page] = await browser.pages()
        await set_proxy(page)

        console.log('change proxy success, start to visit url')
        resp = await page.goto('http://httpbin.org/ip')
        console.log(await resp.text())
}
)

运行效果如下图所示:

参考文献

[1] 青果云: https://www.qg.net/business/proxyip/42.html

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-12-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 未闻Code 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 隧道代理
  • 动态按需修改代理 IP
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档