如何使用Puppeteer设置代理

如何使用Puppeteer设置代理?

Puppeteer 每周有数百万次下载,是最受欢迎的 Node.js 无头浏览器。虽然它可以抓取动态站点,但您的脚本仍可能被识别为机器人并且您的 IP 被阻止。了解如何使用 Puppeteer 代理来避免这种情况!

什么是 Puppeteer 代理

代理充当客户端和服务器之间的中介。当客户端通过代理发出请求时,代理会将其转发给服务器。然后目标站点会将请求视为来自代理服务器,而不是原始客户端。结果,该机制保证了客户端的匿名性。

大多数发出 Web 请求的工具都支持它,包括无头浏览器。在访问运行 Node.js 脚本的站点时,Puppeteer 代理会保护客户端的 IP。此外,它还提供了绕过区块和地理限制的解决方案。

继续阅读以了解如何在 Puppeteer 中设置代理以进行网络抓取

准备工作

如果您的机器上没有安装 Node.js,请下载最新的 LTS 版本。双击安装程序并按照向导进行操作。

验证 Node.js 是否正常工作:

node -v

它应该打印这样的东西:

v18.16.0

接下来,初始化一个 Node.js 项目并将puppeteernpm 包添加到其依赖项中:

npm install puppeteer

使用 Puppeteer 通过以下代码片段控制 Chrome。它导入抓取库,初始化无头浏览器实例,并指示它访问示例目标页面。

const puppeteer = require('puppeteer')

async function scrapeData() {
    // launch a browser instance
    const browser = await puppeteer.launch()
    // open a new page in the current browser context
    const page = await browser.newPage()

    // visit the target page in the browser
    await page.goto('https://developer.chrome.com/')

    // scraping logic...
    
    await browser.close()
}

scrapeData()

如何向 Puppeteer 添加代理?

要在 Puppeteer 中设置代理,请执行以下操作:

  1. 获取有效的代理服务器 URL。
  2. 在 Chrome 标志中指定它--proxy-server
  3. 连接到目标页面。

让我们逐步完成整个过程。

首先,从Free Proxy List中检索代理服务器的 URL 。然后,配置 Puppeteer 以使用以下--proxy-server选项启动 Chrome:

// free proxy server URL
const proxyURL = `http://64.225.8.82:9995`

// launch a browser instance with the
// --proxy-server flag enabled
const browser = await puppeteer.launch({
     args: [`--proxy-server=${proxyURL}`]
})

受控的 Chrome 实例将通过标志中设置的代理服务器运行所有请求。

为确保代理有效,请用作http://httpbin.org/ip目标页面:

await page.goto('https://httpbin.org/ip')

该站点返回调用者的 IP。

提取目标网页的文本内容并将其打印为 JSON 值:

const body = await page.waitForSelector('body')
const ip = await body.getProperty('textContent')
console.log(await ip.jsonValue())

把它们放在一起:

const puppeteer = require('puppeteer')

async function scrapeData() {
    // free proxy server URL
    const proxyURL = 'http://64.225.8.82:9995'

    // launch a browser instance with the
    // --proxy-server flag enabled
    const browser = await puppeteer.launch({
         args: [`--proxy-server=${proxyURL}`]
    })
    // open a new page in the current browser context
    const page = await browser.newPage()

    // visit the target page
    await page.goto('https://httpbin.org/ip')

    // extract the IP the request comes from
    // and print it
    const body = await page.waitForSelector('body')
    const ip = await body.getProperty('textContent')
    console.log(await ip.jsonValue())

    await browser.close()
}

scrapeData()

以下是此脚本将打印的内容:

{ “origin”: “64.225.8.82” }

这是代理服务器的相同 IP,证明 Puppeteer 正在根据需要通过指定的代理访问页面。🎉

极好的!您现在了解了使用 Node.js Puppeteer 代理的基础知识。让我们深入了解更高级的概念!

Puppeteer 代理身份验证:用户名和密码

商业和高级代理服务通常会强制对 Puppeteer 代理进行身份验证。这样,只有拥有有效凭据的用户才能连接到他们的服务器。

这是包含用户名和密码的经过身份验证的代理的 URL 的样子:

<PROXY_PROTOCOL>://<USERNAME>:<PASSWORD>@<PROXY_IP_ADDRESS>:<PROXY_PORT>

问题是 Chrome 不支持这种语法,因为默认情况下它会忽略用户名和密码。出于这个原因,Puppeteer 引入了这种authenticate()方法。

它接受一对凭据并使用它们执行基本的 HTTP 身份验证:

await page.authenticate({ username, password })

使用该特殊方法在 Puppeteer 中处理代理身份验证,如下所示:

const puppeteer = require('puppeteer')

async function scrapeData() {
    // authenticated proxy server info
    const proxyURL = 'http://138.91.159.185:8080'
    const proxyUsername = 'jlkrtcxui'
    const proxyPassword = 'dna8103ns7ahdb390dn'

    // launch a browser instance with the
    // --proxy-server flag enabled
    const browser = await puppeteer.launch({
        args: [`--proxy-server=${proxyURL}`]
    })
    // open a new page in the current browser context
    const page = await browser.newPage()

    // specify the proxy credentials before
    // visiting the page
    await page.authenticate({
        username: proxyUsername,
        password: proxyPassword,
    })
    
    // visit the target page
    await page.goto('https://httpbin.org/ip')

    // extract the IP the request comes from
    // and print it
    const body = await page.waitForSelector('body')
    const ip = await body.getProperty('textContent')
    console.log(await ip.jsonValue()) // { "origin": "138.91.159.185" }

    await browser.close()
}

scrapeData()

在 Puppeteer 中使用 NodeJS 的旋转代理

如果您快速发出太多请求,服务器可能会将您的脚本标记为威胁并禁止您的 IP。您可以使用轮换代理方法来防止这种情况发生,该方法涉及在指定时间或一定数量的请求后更改代理。

你的终端IP会不断变化,导致服务器无法追踪到你。这就是 Puppeteer 代理旋转器的全部意义所在!

让我们学习如何在 Puppeteer 中实现代理轮换。

首先,你需要一桶代理来提取。在此示例中,我们将依赖免费代理列表:

const proxies = [
    'http://45.84.227.55:1000',
    'http://66.70.178.214:9300',
    // ...
    'http://104.248.90.212:80'
]

接下来,创建一个函数来提取随机代理并使用它来启动新的 Chrome 实例:

const puppeteer = require('puppeteer')

// the proxies to rotate on 
const proxies = [
    'http://19.151.94.248:88',
    'http://149.169.197.151:80',
    // ...
    'http://212.76.118.242:97'
]

async function launchBrowserWithProxy() {
    // extract a random proxy from the list of proxies
    const randomProxy = proxies[Math.floor(Math.random() * proxies.length)]
    const browser = await puppeteer.launch({
        args: [`--proxy-server=${randomProxy}`]
    })

    return browser
}

使用launchBrowserWithProxy()而不是launch()Puppeteer 中的方法:

// launchBrowserWithProxy() definition...

async function scrapeSpecificPage() {
  const browser = await launchBrowserWithProxy()
  const page = await browser.newPage()
  
  // visit the target page
  await page.goto('https://example.com/page-to-scrape')
  
  // scrape data...
  
  await browser.close()
}

scrapeSpecificPage()

每次需要抓取新页面时重复此逻辑。

您的 Puppeteer 旋转代理脚本现已准备就绪。

然而,这个解决方案的问题是它需要为每个要抓取的页面实例化一个新的浏览器。不必要的资源浪费!从好的方面来说,有一个更有效的选择。

使用 puppeteer-page-proxy 每页自定义 IP

puppeteer-page-proxy扩展 Puppeteer 以允许按页面或请求设置代理。

这个 Node.js 包还支持 HTTP/HTTPS 和 SOCKS 代理和身份验证。

它允许通过同一浏览器中的不同代理并行抓取多个页面。这使其成为在 Puppeteer 中构建可扩展代理旋转器的完美工具。

切换代理服务器只需puppeteer-page-proxy三步:

  1. 使用以下命令安装它:
npm install puppeteer-page-proxy
  1. 接下来,导入它:
const useProxy = require('puppeteer-page-proxy')
  1. 最后,使用该useProxy()函数,设置用于当前页面的代理:
await useProxy(page, proxy)

在下面的代码片段中查看它的实际效果:

const puppeteer = require('puppeteer')
const useProxy = require('puppeteer-page-proxy')

const proxies = [
    'http://19.151.94.248:88',
    'http://149.169.197.151:80',
    // ...
    'http://212.76.118.242:97'
]

async function scrapeData() {
    const browser = await puppeteer.launch()
    const page = await browser.newPage()

    // get a random proxy
    const proxy = proxies[Math.floor(Math.random() * proxies.length)]

    // specify a per-page proxy
    await useProxy(page, proxy)
    await page.goto('https://httpbin.org/ip')

    const body = await page.waitForSelector('body')
    const ip = await body.getProperty('textContent')
    console.log(await ip.jsonValue())

    await browser.close()
}

scrapeData()

每次运行此脚本时,您都会看到不同的 IP。在调用之前重复此逻辑page.goto()以实现 Puppeteer代理旋转器

要使用经过身份验证的代理,您必须按以下格式指定它:

const proxy = 'protocol://username:password@host:port'

这是一个例子:

const proxy = "http://jlkrtcxui:[email protected]:8080"

如果目标页面进行 AJAX 调用,并且您想让它们通过代理运行,请使用:

await page.setRequestInterception(true)
page.on('request', async (request) => {
    const proxy = proxies[Math.floor(Math.random() * proxies.length)]
    await useProxy(request, proxy)
})

现在您知道了在 Puppeteer 中完成代理轮换的另一种方法!

什么代理最适合 Puppeteer

是时候针对真实目标测试之前构建的旋转代理了。假设您想对 Microsoft Teams 的 G2 评论页面中包含的数据进行屏幕截图:https://www.g2.com/products/microsoft-teams/reviews

你可以使用这个脚本:

const puppeteer = require('puppeteer')
const useProxy = require('puppeteer-page-proxy')

const proxies = [
    'http://19.151.94.248:88',
    'http://149.169.197.151:80',
    // ...
    'http://212.76.118.242:97'
]

async function scrapeData() {
    const browser = await puppeteer.launch()
    const page = await browser.newPage()
    
    // specify the page viewport to
    // get a screenshot in the desired format
    await page.setViewport({
        width: 1200,
        height: 800,
    })

    const proxy = proxies[Math.floor(Math.random() * proxies.length)]
    await useProxy(page, proxy)
    await page.goto('https://www.g2.com/products/microsoft-teams/reviews')
    
    // take a screenshot of the reviews on the page
    await page.screenshot({ 'path': 'reviews.png' })

    await browser.close()
}

scrapeData()

这就是你会得到的:

medium_G2_access_denied

目标站点将您的脚本检测为机器人,并以403 Unauthorized错误响应。

这在依赖免费代理时很常见,因为它们大部分时间都会让您受阻。我们用它们来展示基础知识,但你永远不应该在真实世界的脚本中采用它们。相反,请查看我们的最佳抓取代理类型列表。

如何克服这个限制?使用高级代理!

无头浏览器可帮助您避免在配置为抓取并与高级代理一起使用时被阻止。查看我们的指南,获取有关如何在 Puppeteer 中防止机器人检测的一些提示。但即使使用自定义和正确的代理,您仍然有可能被阻止。原因?由于 Puppeteer 的自动化特性,反抓取系统可以检测并阻止它。

避免阻塞的更好选择是 ZenRows。此抓取 API 提供与 Puppeteer 类似的功能,但成功率要高得多。其功能齐全的工具包可以绕过所有反抓取措施。

创建帐户后,到达 Request Builder 页面。粘贴目标 URL 并选中“JavaScript Rendering”、“Premium Proxy”和“Anti-bot”,然后等待 .l2 CSS 选择器。

选择“Node.js”作为语言,选择右侧的“Proxy”模式,最后点击“Copy to clipboard”按钮。

medium_Zen_Rows_dashboard

你会得到这个代码

const axios = require("axios");
const HttpProxyAgent = require("http-proxy-agent");
const HttpsProxyAgent = require("https-proxy-agent");

const url = "https://www.g2.com/products/microsoft-teams/reviews";
const proxy = "http://<YOUR_ZENROWS_API_KEY>:js_render=true&antibot=true&wait_for=.l2&premium_proxy=true@proxy.zenrows.com:8001";
const httpAgent = new HttpProxyAgent(proxy);
const httpsAgent = new HttpsProxyAgent(proxy);
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
axios({
        url,
        httpAgent,
        httpsAgent,
        method: 'GET',
})
    .then(response => console.log(response.data))
    .catch(error => console.log(error));

安装新的依赖项:

npm install axios http-proxy-agent https-proxy-agent 

运行脚本,您将可以轻松访问所需的数据。再见,再见,错误403

现在您有了一个具有 Puppeteer 功能的代理抓取解决方案,但效率更高!

结论

本分步教程解释了如何在 Puppeteer 中配置代理。您从基础开始,已成为 Puppeteer Node.js 代理忍者!

现在你知道了:

  • 什么是 Puppeteer 代理。
  • 在 Puppeteer 中使用代理的基础知识。
  • 如何在 Puppeteer 中处理经过身份验证的代理。
  • 如何构建轮换代理以及为什么此机制不适用于免费代理。

在 Puppeteer 中使用代理有助于避免 IP 封锁。但是,请记住,某些反抓取技术仍然可以阻止您。

类似文章