【问题标题】:puppeteer Get array of href then iterate through each href and the hrefs on that pagepuppeteer 获取 href 数组,然后遍历每个 href 和该页面上的 href
【发布时间】:2020-10-22 15:55:12
【问题描述】:

我正在尝试通过 node.js 中的 puppeteer 抓取数据

目前,我正在寻找编写一个脚本,用于抓取 well.ca 某个部分中的所有数据

现在,这是我尝试通过 node.js 实现的方法/逻辑

1 - 前往网站的医学健康部分

2 - 使用 dom 选择器获取 href 数组 从 .panel-body-content 通过 dom 选择器 panel-body-content a[href] 抓取子部分

3 - 使用 for 循环遍历每个链接(小节)

4 对于每个小节链接,通过.col-lg-5ths col-md-3 col-sm-4 col-xs-6 a[href] 获取值为col-lg-5ths col-md-3 col-sm-4 col-xs-6 的每个类的href,为每个产品获取另一个hrefs 数组

5 - 遍历小节中的每个产品

6 - 为每个产品抓取数据

目前,我已经编写了上述大部分代码:

const puppeteer = require('puppeteer');
const chromeOptions = {
  headless: false,
  defaultViewport: null,
};
(async function main() {
  const browser = await puppeteer.launch(chromeOptions);
  try {
    const page = await browser.newPage();
    await page.goto("https://well.ca/categories/medicine-health_2.html");
    console.log("::::::: OPEN WELL   ::::::::::");

    // href attribute
    const hrefs1 = await page.evaluate(
      () => Array.from(
        document.querySelectorAll('.panel-body-content a[href]'),
       a => a.getAttribute('href')
     )
   );
    
    console.log(hrefs1);

    const urls = hrefs1

    for (let i = 0; i < urls.length; i++) {
      const url = urls[i];
      await page.goto(url);
    }
      const hrefs2 = await page.evaluate(
     () => Array.from(
      document.querySelectorAll('.col-lg-5ths col-md-3 col-sm-4 col-xs-6 a[href]'),
       a => a.getAttribute('href')
     )
    );

当我尝试为每个产品的每个 href 获取一个数组时,我在数组中没有收到任何内容。

如何添加嵌套 for 循环,以获取每个小节中每个产品的所有 href 数组,然后访问每个产品链接?

什么是正确的 dom 选择器,用于获取类 .col-lg-5ths col-md-3 col-sm-4 col-xs-6 中的所有 href,id 为 product_grid_link

如果我想添加一个后续循环以通过每个小节中产品的 href 从每个产品中获取信息,我该如何将其嵌入到代码中?

任何帮助将不胜感激

【问题讨论】:

    标签: javascript html node.js arrays puppeteer


    【解决方案1】:

    似乎有些链接是重复的,所以最好收集最终页面的所有链接,对链接列表进行重复数据删除,然后将最终页面刮掉。 (您也可以将最终页面的链接保存在文件中以供以后使用。)此脚本收集了 5395 个链接(已删除)。

    'use strict';
    
    const puppeteer = require('puppeteer');
    
    (async function main() {
      try {
        const browser = await puppeteer.launch({ headless: false, defaultViewport: null });
        const [page] = await browser.pages();
    
        await page.goto('https://well.ca/categories/medicine-health_2.html');
    
        const hrefsCategoriesDeduped = new Set(await page.evaluate(
          () => Array.from(
            document.querySelectorAll('.panel-body-content a[href]'),
            a => a.href
          )
        ));
    
        const hrefsPages = [];
    
        for (const url of hrefsCategoriesDeduped) {
          await page.goto(url);
          hrefsPages.push(...await page.evaluate(
            () => Array.from(
              document.querySelectorAll('.col-lg-5ths.col-md-3.col-sm-4.col-xs-6 a[href]'),
              a => a.href
            )
          ));
        }
    
        const hrefsPagesDeduped = new Set(hrefsPages);
    
        // hrefsPagesDeduped can be converted back to an array
        // and saved in a JSON file now if needed.
    
        for (const url of hrefsPagesDeduped) {
          await page.goto(url);
    
          // Scrape the page.
        }
    
        await browser.close();
      } catch (err) {
        console.error(err);
      }
    })();
    

    【讨论】:

    • 太好了,效果很好!只是一个简单的问题,.col-lg-5ths.col-md-3.col-sm-4.col-xs-6 a[href]'' 似乎为每个产品产生了两个链接。我怎样才能只从此类product_grid_link 中获取href?非常感谢,vsemozhetbyt。
    • document.querySelectorAll('.col-lg-5ths.col-md-3.col-sm-4.col-xs-6 a[href].product_grid_link')
    • 啊,我想那么多。它就像一个魅力!这确实是解决方案。
    • 是否可以使用 forEach 或 map 代替 for(...of)?
    • @Kongsun 不幸的是,我不这么认为:1)Set 结构没有forEachmap 方法; 2)即使将Set转换为数组,forEachmap也不适合使用await
    猜你喜欢
    • 2020-02-28
    • 1970-01-01
    • 2021-06-04
    • 2019-08-18
    • 2011-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-05
    相关资源
    最近更新 更多