簡體   English   中英

如何使用 Puppeteer 獲取頁數?

[英]How to get number of pages using Puppeteer?

我是一個使用 Puppeteer 的爬行初學者。 我成功地抓取了以下站點。 下面是用於從購物中心提取特定產品名稱的代碼。

const express = require('express');
const puppeteer = require('puppeteer');
const app = express();

(async () => {

    const width = 1600, height = 1040;

    const option = { headless: true, slowMo: true, args: [`--window-size=${width},${height}`] };

    const browser = await puppeteer.launch(option);
    const page = await browser.newPage();
    const vp = {width: width, height: height};
    await page.setViewport(vp);

    const navigationPromise = page.waitForNavigation();

    // 네이버 스토어팜
    await page.goto('https://shopping.naver.com/home/p/index.nhn');
    await navigationPromise;
    await page.waitFor(2000);

    const textBoxId = 'co_srh_input';
    await page.type('.' + textBoxId, '양말', {delay: 100});
    await page.keyboard.press('Enter');

    await page.waitFor(5000);
    await page.waitForSelector('ul.goods_list');
    await page.addScriptTag({url: 'https://code.jquery.com/jquery-3.2.1.min.js'});

    const result = await page.evaluate(() => {

        const data = [];

        $('ul.goods_list > li._itemSection').each(function () {

            const title = $.trim($(this).find('div.info > a.tit').text());
            const price = $(this).find('div.info > .price .num').text();
            const image = $(this).find('div.img_area img').attr('src');

            data.push({ title, price, image })

        });

        return data;

    });

    console.log(result);
    await browser.close();

})();

app.listen(3000, () => console.log("Express!!!"));

我有個問題。 如果我想從頁數中獲取信息,我應該怎么做? 例如(1頁,2頁,3頁......)

由於該站點上默認顯示的頁面數量的性質,這是一項困難的任務。 但是請耐心等待:我將向您展示您至少可以通過這個實現什么。

首先,您提供的站點在您可以循環瀏覽的項目列表下方一次列出 10 個頁面。 很抱歉,我不懂它所用的語言,所以我不知道是否有選項可以顯示更多頁面。 因此,當您輸入搜索文本時,它會顯示如下:

列出的前十頁

但是,當您單擊最后一個數字(數字 10)時,頁面列表將更新為如下所示:

動態添加更多頁面

這使得查找整個頁面的數量變得更加困難,因為沒有選項可以“跳”到最后一頁(隨后也沒有選項可以跳回第一頁)。 稍后我將向您展示執行此操作的站點的另一個示例。

我建議你在你的情況下做的是使用一些簡單的數學來確定要列出多少頁。 繼續告訴puppeteer會變得太復雜,例如,“繼續點擊最后一個可用的頁碼直到你到達最后”或類似的。 但是我們可以通過執行幾個簡單的步驟來確定有多少頁。

首先,您需要通過此元素獲取搜索列表中返回的項目總數:

結果總數

您可以通過執行以下代碼來做到這一點:

const totalItems = await page.$eval('._productSet_total', (items) => {
  // Remove the characters before the total number, leaving only the number in isolation
  const child = items.querySelector('em');
  items.removeChild(child);

  // Now remove all commas from the total number
  let finalItems = items.textContent.trim();
  while(finalItems.indexOf(',') > -1) {
    finalItems = finalItems.replace(',', '').trim();
  }
  return finalItems;
});
console.log(totalItems); // Outputs 4337903 (or something similar)

所以現在你有了那個總數。 下一步是確定每頁將顯示多少項。 您可以通過計算當前頁面上顯示的項目數來做到這一點 - 如下:

const itemsPerPage = await page.$$eval('.goods_list li', (items) => {
  return items.length;
});
console.log(itemsPerPage); // Outputs 180 on my machine

所以現在您已經找到了找到的項目總數以及要在每個頁面上顯示的項目數。 下一部分是簡單的數學運算,以確定列出所有這些項目需要多少頁:

const pages = totalItems / itemsPerPage;
console.log(Math.ceil(pages));

就是這樣! 這是一個相當困難的例子,因為網站本身的設計很差(實際上它應該始終有一個直接到第一頁和/或最后一頁的路線)。

例如,如果你點擊 Stack Overflow(這個非常棒的網站)中的puppeteer標簽,它會帶你到: https : //stackoverflow.com/questions/tagged/puppeteer

現在滾動到頁面底部,您將看到如下內容:

在此處輸入圖片說明

這是確定在一個簡單的步驟中列出多少頁的理想選擇,如下所示:

const lastPage = await page.$$eval('div[class*="pager"] > a > span[class*="page-numbers"]', (spans) => {
  return spans[spans.length - 2].textContent;
});
console.log(lastPage); // Outputs 78

希望這里的內容可以幫助您完成木偶操作學習之旅!

使用屬性footerTemplatedisplayHeaderFooter顯示最初使用puppeteer API 的頁面

await page.pdf({
  path: 'hacks.pdf',
  format: 'A4',
  displayHeaderFooter: true,
  footerTemplate: '<div><div class='pageNumber'></div> <div>/</div><div class='totalPages'></div></div>'
});

https://github.com/puppeteer/puppeteer/blob/master/docs/api.md#pagepdfoptions

// footerTemplate打印頁腳的 HTML 模板。

// 應該是有效的 HTML 標記,具有以下用於將打印值注入其中的CSS 類

// -日期格式的打印日期

// -標題文檔標題

// - url文檔位置

// - pageNumber當前頁碼

// - totalPages文檔中的總頁數

  if (!this.browser) {
    this.browser = await puppeteer.launch(this.OPT)
    const pages: puppeteer.Page[] = await this.browser.pages()

    // close chromium by catching 'targetdestryed'
    this.browser.on('targetdestroyed', async () => {
      if (this.browser) {
        const pages: puppeteer.Page[] = await this.browser.pages()
        if (pages.length === 0) {
          process.exit(0)
        }
      }
    })
  }

上面是我用 Typescript 寫的代碼。 您可以從browser.pages()獲取 Page(=Tab) 數組,並且 Puppeteer 第一次絕對有 1 個選項卡。

暫無
暫無

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

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