【问题标题】:Why am I getting duplicated data when scraping?为什么我在抓取时会得到重复的数据?
【发布时间】:2019-08-10 01:12:31
【问题描述】:

我想学习一些网络抓取,我发现了 puppeteer 库。我选择了 puppeteer 而不是其他工具,因为我有一些 JS 的背景。

我还发现了这个website,它的目的是要被刮掉。我已经设法在每一页中获取每本书的信息。这是我所做的:

(async () => {
  const browser = await puppeteer.launch({headless: false});
  const page = await browser.newPage();
  await page.goto(url); // http://books.toscrape.com/

  const json = [];

  let next = await page.$('.pager .next a'); // next button

  while (next) {
    // get all articles
    let articles = await page.$$('.product_pod a');

    // click on each, get data and go back
    for (let index = 0; index < articles.length; index++) {
      await Promise.all([
        page.waitForNavigation(),
        articles[index].click(),
      ]);
      const data = await page.evaluate(getData);
      json.push(data);
      await page.goBack();
      articles = await page.$$('.product_pod a');
    }

    // click the next button
    await Promise.all([
      page.waitForNavigation(),
      page.click('.pager .next a'),
    ]);

    // get the new next button
    next = await page.$('.pager .next a');
  }
  fs.writeFileSync(file, JSON.stringify(json), 'utf8');
  await browser.close();
})();

传递给page.evaluate 的函数getData 返回一个具有所需属性的对象:

function getData() {
  const product = document.querySelector('.product_page');
  return {
    title: product.querySelector('h1').textContent,
    price: product.querySelector('.price_color').textContent,
    description:
      document.querySelector('#product_description ~ p')
        ? document.querySelector('#product_description ~ p').textContent
        : '',
    category:
      document.querySelector('.breadcrumb li:nth-child(3) a')
        ? document.querySelector('.breadcrumb li:nth-child(3) a').textContent
        : '',
    cover:
      location.origin +
      document.querySelector('#product_gallery img')
          .getAttribute('src').slice(5),
  };
}

当我最终执行脚本时,一切都很顺利,除了在最终的json 文件中我有重复的记录。也就是说,每本书在文件中都有两个条目。我知道脚本可能会更好,但您认为这种方法会发生什么?

【问题讨论】:

    标签: javascript node.js web-scraping puppeteer


    【解决方案1】:

    您在这一行中的选择器:

    let articles = await page.$$('.product_pod a');
    

    匹配的数量超出了要求。你得到 40 而不是 20(还包括图像容器的 a 子标签,与 h3 的子 a 相同)

    你想限制在h3 a:

    let articles = await page.$$('.product_pod h3 a');
    

    【讨论】:

    • 从来没有想过除了这些元素之外我匹配了多少元素。在这条道路上还要学习一件事。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2021-12-23
    • 1970-01-01
    • 2018-10-17
    • 1970-01-01
    • 2012-10-27
    • 2019-07-18
    • 2023-01-29
    • 1970-01-01
    相关资源
    最近更新 更多