【问题标题】:web scraping : iterate through every page of web app using puppeteer网页抓取:使用 puppeteer 遍历网页应用的每一页
【发布时间】:2020-07-10 21:53:39
【问题描述】:

我是javascriptpuppeteer 的初学者,我正在尝试从bulapedia 网站https://en.wikipedia.org/wiki/List_of_generation_I_Pok%C3%A9mon 获取前151 个口袋妖怪描述 在下图中,我复制了单个 pokemon 实例的蓝色标记元素的 XPath,它是我要显示的文本

使用下面的代码,我可以成功抓取元素并以json 值显示文本,但我一次只能手动处理一个口袋妖怪。我想要的是使用puppeteer 遍历每个页面并为前 151 个口袋妖怪执行此操作
我的代码:

const puppeteer = require('puppeteer');

async function getDesc(url){

    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    await page.goto(url);
    //xpath of the selected text above in the pic 
    const [el] = await page.$x('//*[@id="mw-content-text"]/table[5]/tbody/tr[1]/td/table/tbody/tr[2]/td/table/tbody/tr[1]/td');
    const text = await el.getProperty('textContent');
    srcTxt = await text.jsonValue();

    console.log({srcTxt});

    browser.close();

}



//give url for a specific pokemon as input 
getDesc('https://bulbapedia.bulbagarden.net/wiki/Bulbasaur_(Pok%C3%A9mon)');

我相信为每个 pokemon 实例遍历每个 url 的 for 循环是解决方案。但是我不知道如何使用 puppeteer 来实现这一点,我将不胜感激。提前谢谢你。

【问题讨论】:

  • 我已经在 npm 上的一个库中完成了这项工作,但是您可能需要获取每个访问页面上的每个锚点/链接,存储这些链接确保不重复并跟踪哪些链接已经访问过,递归导航到页面/链接并执行所需的逻辑,直到用完链接。
  • @AlexanderStaroselsky 感谢您的回复。有没有更好的办法?
  • 更好的方法是什么意思?如果您询问 puppeteer 是否有一个内置的方法来自动和递归地完成您正在尝试的自定义逻辑,它没有。您需要创建逻辑来确定它应该访问哪些页面,然后为每个页面执行访问和逻辑。但有人可能已经找到了更有效的方法。
  • @KresimirPendic 我使用 FETCH API 来获取它们。我采取了完全不同的方法。

标签: javascript web-scraping puppeteer


【解决方案1】:

如果你有一个 URL 数组,你可以试试这样:

'use strict';

const puppeteer = require('puppeteer');

(async function main() {
  try {
    const browser = await puppeteer.launch();
    const [page] = await browser.pages();

    const urls = ['https://example.org/1', 'https://example.org/2'];
    const allData = [];

    for (const url of urls) {
      await page.goto(url);

      const data = await page.evaluate(() => {
        return document.querySelector('a').innerText;
      });

      allData.push(data);
    }

    console.log(allData);

    await browser.close();
  } catch (err) {
    console.error(err);
  }
})();

【讨论】:

  • 感谢您的回复。但是,一页中可能有很多“a”,我想获得一个特定的“a”,那么 const data = await page.evaluate(() => { return document.querySelector('a').innerText; } );工作 ?也许这里有我不明白的地方
  • 它只是一个占位符。您可以在 page.evaluate() 中抓取任何元素并构建任何复杂数据,以将其返回到 puppeteer 上下文并收集。
  • 但是我仍然需要手动抓取每个元素,对吧?这是我要避免的
  • 好吧,puppeteer 只是 Node.js 和浏览器世界之间 DevTools 协议交互的促进者。您需要自己实现所有逻辑。也许有一些库有更多的抽象(比如给出一个 URL 和选择器列表并获取一个文本列表等),但我不知道,抱歉。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-14
  • 1970-01-01
  • 2022-11-28
  • 1970-01-01
  • 2020-06-18
  • 1970-01-01
相关资源
最近更新 更多