【问题标题】:Web scraping with cheerio not working with some elements使用 Cheerio 进行 Web 抓取无法使用某些元素
【发布时间】:2021-11-27 22:08:14
【问题描述】:

我刚开始学习网络抓取,我发现了这个教程: https://www.mundojs.com.br/2020/05/25/criando-um-web-scraper-com-nodejs/

它工作正常,但我试图从同一个网页获取不同的元素:https://ge.globo.com/futebol/brasileirao-serie-a/

对于本教程的类组,它将所有元素与所选类一起带来,但对于其他类则不起作用:

可以看出,ranking-item-wrapper 类的所有 50 个元素都被返回,但如果我选择 lista-jogos__jogo 类的元素,它不会返回任何东西:

我不明白为什么会出现此错误,因为我正在做与教程中所做的完全相同的事情。

这是代码的简短版本:

const axios = require('axios');
const cheerio = require('cheerio');
const url = 'https://ge.globo.com/futebol/brasileirao-serie-a/';

axios(url).then(response => {
  const html = response.data;
  const $ = cheerio.load(html);
  console.log($('.ranking-item-wrapper')) // => tutorial class
  console.log('***')
  console.log($('.lista-jogos__jogo')) // => class that I'm using
}).catch(console.error);

【问题讨论】:

    标签: javascript node.js axios web-crawler cheerio


    【解决方案1】:

    我从@Bradley 那里看到了答案,虽然它解释了正在发生的事情,但它没有提供解决方案。他说元素被附加了Javascript是正确的。有几种方法可以处理此问题以获取相同的数据。

    我看到您关于等待元素加载的回复,这可以使用 JSDOM/Puppeteer 之类的东西,但它完全是矫枉过正,很可能会导致不支持的 JS 和/或大量 CPU/内存开销与类似 Cheerio。

    通常,根据我的经验,元素被附加到 Javascript 的原因是数据是从 API 外部提取的,这是一个简单的修复,因为您只需检查网络工具要查看获取数据的 XHR 请求,通常它也采用更易于解析的格式,因为它是从 API (JSON) 中提取的。这在当今所有客户端渐进式 Web 应用程序中都很常见。

    另一种方法是将数据硬编码在站点脚本中,该脚本可以拆分为可解析的格式。您可能会在利用服务器端渲染来获得 SEO 优势的渐进式 Web 应用程序中看到这一点。

    我发现数据来自返回 JSON 数据的外部 API。网址是:

    https://api.globoesporte.globo.com/tabela/d1a37fa4-e948-43a6-ba53-ab24ab3a45b1/fase/fase-unica-campeonato-brasileiro-2021/rodada/38/jogos/

    您将需要请求此 URL 并解析 JSON 响应以获取您需要的数据,而不是使用 Cheerio。

    【讨论】:

    • 感谢您的回答。这正是我一直在寻找的。我已经尝试过 JSDOM,但它没有按我需要的方式工作。 Puppeteer 是我的第一次尝试,甚至在 Cheerio 之前,它有点工作,但有很多小问题。您的回答让我的工作轻松了很多。
    【解决方案2】:

    看起来这些元素是在页面加载时使用 JavaScript 添加的。

    如果您在禁用 JavaScript 的浏览器中检查页面,您会发现这些元素不存在,因此当您使用 Cheerio 下拉页面时它们也不会存在。

    【讨论】:

    • 是的,我一直在挖掘并弄清楚这一点,所以我选择了另一个网站来获取我需要的信息。但是有没有办法可以强制cheerio 等待这些元素被插入到DOM 中?我考虑过 setTimeout,但也许有更可靠的方法来做到这一点。
    • 我不认为这是可能的,这是来自Cheerio website 的引用:“Cheerio 解析标记并提供用于遍历/操作结果数据结构的 API。它不会解释结果“但是,它确实建议使用 PuppeteerJSDom 之类的东西来实现这种功能。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-18
    • 1970-01-01
    • 2016-10-17
    • 2019-03-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多