如何将 puppeteer 插件与 puppeteer 集群结合使用?

How do I combine puppeteer plugins with puppeteer clusters?

我有一个需要从使用 React 的网站上抓取的 url 列表,因此我正在使用 Puppeteer。 我不想被反机器人服务器阻止,为此我添加了 puppeteer-extra-plugin-stealth 我想阻止广告加载到页面上,所以我使用 puppeteer-extra-plugin-adblocker 来阻止广告 我也想防止我的 IP 地址被列入黑名单,所以我使用 TOR nodes 来拥有不同的 IP 地址。 下面是我的代码的简化版本,设置工作 TOR_portwebUrl 是动态分配的,但为了简化我的问题,我将其分配为变量) 。 但是有一个问题:

const puppeteer = require('puppeteer-extra');
const _StealthPlugin = require('puppeteer-extra-plugin-stealth');
const _AdblockerPlugin = require('puppeteer-extra-plugin-adblocker');

puppeteer.use(_StealthPlugin());
puppeteer.use(_AdblockerPlugin());

var TOR_port = 13931;
var webUrl ='https://www.zillow.com/homedetails/2861-Bass-Haven-Ln-Saint-Augustine-FL-32092/47739703_zpid/';


const browser = await puppeteer.launch({
    dumpio: false,
    headless: false,
    args: [
        `--proxy-server=socks5://127.0.0.1:${TOR_port}`,
        `--no-sandbox`,
    ],
    ignoreHTTPSErrors: true,
});

try {
    const page = await browser.newPage();
    await page.setViewport({ width: 1280, height: 720 });
    await page.goto(webUrl, {
        waitUntil: 'load',
        timeout: 30000,
    });

    page
    .waitForSelector('.price')
    .then(() => {
        console.log('The price is available');
        await browser.close();
    })
    .catch(() => {
        // close this since it is clearly not a zillow website
        throw new Error('This is not the zillow website');
    });
} catch (e) {
    await browser.close();
}

上述设置有效但非常不可靠,我最近了解到 Puppeteer-Cluster。我需要它来帮助我管理抓取多个页面,跟踪我的抓取任务。

所以,我的问题是如何使用上述设置实现 Puppeteer-Cluster。我知道库提供了一个 example(https://github.com/thomasdondorf/puppeteer-cluster/blob/master/examples/different-puppeteer-library.js) 来展示如何实现插件,但是太简单了以至于我不太明白它。

如何使用上述 TOR、AdBlocker 和 Stealth 配置实施 Puppeteer-Cluster?

您可以像下面这样交出您的 puppeteer 实例:

const puppeteer = require('puppeteer-extra');
const _StealthPlugin = require('puppeteer-extra-plugin-stealth');
const _AdblockerPlugin = require('puppeteer-extra-plugin-adblocker');

puppeteer.use(_StealthPlugin());
puppeteer.use(_AdblockerPlugin());

const browser = await puppeteer.launch({
    puppeteer,
});

来源:https://github.com/thomasdondorf/puppeteer-cluster#clusterlaunchoptions

要将 puppeteer 与插件结合使用,您必须首先需要 puppeteer-extra、您的插件和 puppeteer-cluster。

puppeteer-extra 有一个 addExtra() 函数,它接受一个现有的或新的 puppeteer 实例。

puppeteer-extra .use() 函数接受插件作为参数。

将 puppeteer 实例作为对象中的第一个 属性 插入,然后进入 puppeteer-cluster 的 Cluster.launch() 函数。

要为 puppeteer 实例添加选项,请创建一个包含所有 puppeteerOptions 的对象。将其作为第二个 属性 插入到 Cluster.launch() 函数的对象中。在下面的第二个 link 中查看有关添加 puppeteerOptions 的更多信息。

在 puppeteer-extra 的“更多示例 > 与 puppeteer-cluster 一起使用”部分下阅读更多关于将 puppeteer 与 puppeteer-cluster 结合使用的信息,或在下面第一个 link 的 puppeteer-cluster 文档中阅读。

来源:https://www.npmjs.com/package/puppeteer-extra
资料来源:https://www.npmjs.com/package/puppeteer-cluster#clusterlaunchoptions

const { addExtra } = require("puppeteer-extra");
const vanillaPuppeteer = require("puppeteer");
const StealthPlugin = require("puppeteer-extra-plugin-stealth");
const RecaptchaPlugin = require("puppeteer-extra-plugin-recaptcha");
const { Cluster } = require("puppeteer-cluster");

(async () => {
  const puppeteer = addExtra(vanillaPuppeteer);
  puppeteer.use(StealthPlugin());
  puppeteer.use(RecaptchaPlugin());

  const cluster = await Cluster.launch({
    puppeteer,
    // puppeteerOptions go here, i.e., userDataDir, args (proxy server, 
    // etc..
    // puppeteerOptions, 
    concurrency: Cluster.CONCURRENCY_CONTEXT,
    maxConcurrency: 2,
  });

  let i = 0; // screenshot counter for filename
  await cluster.task(async ({ page, data: url }) => {
    await page.goto(url);
    const screen = await page.screenshot({
      path: `${"screenshot" + i++ + ".png"}`,
      fullPage: true,
    });
  });

  cluster.queue("http://www.google.com/");
  cluster.queue("http://www.wikipedia.org/");

  await cluster.idle();
  await cluster.close();
  console.log("Program is finished\nBye!");
})();