使用 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 是:
您将需要改为请求此 URL 并解析 JSON 响应以获取您需要的数据,而不是使用 Cheerio。
我刚开始学习网络抓取,我发现了这个教程: 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 是:
您将需要改为请求此 URL 并解析 JSON 响应以获取您需要的数据,而不是使用 Cheerio。