有趣的问题。数据在静态响应中,因此 Cheerio 应该能够找到它。您可以看到它适用于 JSDOM:
const {JSDOM} = require("jsdom"); // 20.0.0
const url = "https://chrome.google.com/webstore/detail/earth-view-from-google-ea/bhloflhklmhfpedakmangadcdofhnnoh";
JSDOM.fromURL(url).then(({window: {document}}) => {
const selector = ".C-b-p-j-D.Ka-Ia-j.C-b-p-j-D-gi";
console.log(document.querySelector(selector).textContent);
});
使用 Python/BeautifulSoup:
import requests
from bs4 import BeautifulSoup
url = "https://chrome.google.com/webstore/detail/earth-view-from-google-ea/bhloflhklmhfpedakmangadcdofhnnoh"
response = requests.get(url)
response.raise_for_status()
soup = BeautifulSoup(response.text, "lxml")
print(soup.select_one('meta[property="og:description"]')["content"])
print("-" * 50)
print(soup.select_one("[itemprop='description']").text)
print("-" * 50)
print(soup.select_one('.C-b-p-j-D.Ka-Ia-j.C-b-p-j-D-gi').text)
将问题最小化后,归结为:
const {load} = require("cheerio"); // 1.0.0-rc.12
const html = `<!DOCTYPE html>
<html>
<body>
<noscript>
<p>foo</p>
</noscript>
</body>
</html>`;
console.dir(load(html)("p").text()); // => ''
console.dir(load(html, {scriptingEnabled: false})("p").text()); // => 'foo'
console.dir(load(html, {xml: true})("p").text()); // => 'foo'
您可以看到 <noscript> 标签是罪魁祸首。添加两个选项之一,scriptingEnabled: false 或 xml: true(或弃用的xmlMode)允许 Cheerio 解析 <noscript> 的内容。详情请见Cheerio issue #1105。
乍一看,我不清楚哪个更可取,但是this comment 表示xmlMode 有副作用,可能导致页面无法解析,所以我暂时选择scriptingEnabled。
回到你的代码。我使用了 fetch,它在最近的 Node 版本中是原生的,但这是一个外观上的变化。您可以使用任何请求库。
const cheerio = require("cheerio"); // 1.0.0-rc.12
const url = "https://chrome.google.com/webstore/detail/earth-view-from-google-ea/bhloflhklmhfpedakmangadcdofhnnoh";
fetch(url)
.then(response => {
if (!response.ok) {
throw Error(response.status);
}
return response.text();
})
.then(html => {
const $ = cheerio.load(html, {scriptingEnabled: false});
console.log($("div.C-b-p-j-D.Ka-Ia-j.C-b-p-j-D-gi").text());
console.log($('div[itemprop="description"]').text());
console.log($("div.C-b-p-j-Pb").text());
});
顺便说一句,一些数据在标头中的标记中可用:
<meta property="og:description" content="Experience a beautiful image from Google Earth every time you open a new tab.">
由于这不在 <noscript> 中,您可以在没有特殊选项的情况下选择它:
const $ = cheerio.load(html); // nothing special
console.log($('meta[property="og:description"]').attr("content"));