使用 cheerio 进行网页抓取不适用于某些元素

Web scraping with cheerio not working with some elements

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

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

对于本教程的 classes 组,它将所有元素与 selected class 一起使用,但对于其他 classes 则不会工作:

可以看出所有带有 class ranking-item-wrapper 的五十个元素都是 returned,但是如果我 select 带有 class 的元素 lista-jogos__jogo 它没有 return 任何东西:

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

这是代码的简短版本:

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 添加的。

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

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

我看到了您关于等待元素加载的回复,这可以使用 JSDOM/Puppeteer 之类的东西,但这完全是矫枉过正,很可能会导致来自不受支持的 JS and/or 的错误 [= =29=] 与 Cheerio 之类的东西相比的开销。

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

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

我发现数据来自外部 API,它正在返回 JSON 数据。 URL 是:

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

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