簡體   English   中英

多個單獨的瀏覽器,每個瀏覽器都有一個選項卡 - 與頁面上的元素同時交互(木偶無頭)

[英]Multiple separate browser with one tab each - simultaneous interaction with elements on pages (puppeteer headless)

在 ubuntu 服務器上使用 Node.js、Chrome 和 puppeteer 作為無頭,我正在抓取幾個不同的網站。 偶爾的任務之一是與加載的頁面進行交互(單擊鏈接以打開另一個頁面,然后可能再次單擊以接受條款等)。

我可以很好地完成這一切,但我試圖了解如果我同時打開多個頁面並嘗試同時與不同加載的頁面交互(重疊時間)它將如何工作。

為了形象化這一點,我在想用戶將如何做同樣的工作。 他們將不得不打開多個瀏覽器 windows,打開頁面並在它們之間切換以查看然后單擊鏈接。

但是使用 puppeteer,我們有單獨的瀏覽器 object,我們不需要看到 window 或頁面就知道點擊哪里。 我們可以通過瀏覽器 object 遍歷它,然后在不看(無頭)的情況下單擊所需的元素。

我想我應該能夠同時處理多個頁面,只要我有 CPU 和 memory 可以處理它們。

有沒有人有過 puppeteer 同時與多個網站交互的經驗? 我有什么需要注意的嗎?

這是圖書館puppeteer-cluster (我是作者)正在解決的問題。 它允許您構建一個頁面池(或瀏覽器)以在其中使用和運行任務。

您可以在存儲庫中找到幾個通用代碼示例(以及在stackoverflow上)。 讓我通過一個示例來解決您運行不同任務的特定用例。

代碼示例

以下代碼創建了兩個任務:

  • crawl :打開頁面並提取一個 URL 然后開始第二個任務
  • screenshot : 對提取的 URL 進行截圖

該過程通過將crawl任務與 URL 進行排隊來啟動。

const { Cluster } = require('puppeteer-cluster');

(async () => {
    const cluster = await Cluster.launch({ // use four pages in parallel
        concurrency: Cluster.CONCURRENCY_PAGE,
        maxConcurrency: 4,
    });

    // We define two tasks
    const crawl = async ({ page, data: url }) => {
        await page.goto(url);
        const extractedURL = /* ... */; // extract an URL (or multiple) from the document somehow
        cluster.queue(extractedURL, screenshot);
    };

    const screenshot = async ({ page, data: url }) => {
        await page.goto(url);
        await page.screenshot();
    };

    // Crawl some pages
    cluster.queue('https://www.google.com/', crawl);
    cluster.queue('https://github.com/', crawl);

    // Wait until everything is done and close the cluster
    await cluster.idle();
    await cluster.close();
})();

這是一個最小的例子。 我省略了錯誤處理、監控和設置選項。

我通常可以在 4GB 的服務器上運行 5 個左右的瀏覽器,如果你只是從隊列中彈出 url,這非常簡單:

const puppeteer = require('puppeteer');

let queue = [
  'http://www.amazon.com',
  'http://www.google.com',
  'http://www.fabebook.com',
  'http://www.reddit.com',
]

const doQueue = async () => {
  const browser = await puppeteer.launch()
  const page = await browser.newPage()
  let url
  while(url = queue.shift()){
    await page.goto(url)
    console.log(await page.title())
  }
  await browser.close()
}

[1,2,3].map(() => doQueue())

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM