cheerio 相关问题

专为服务器设计的核心jQuery的快速,灵活和精益实现。 https://github.com/cheeriojs/cheerio

cheeriojs 选择不在另一个指定标签内的标签

考虑以下代码 const Cheerio = require('cheerio'); const xml = `<...

回答 1 投票 0

无法使用 Cheerio 获取图像 src url

目前我正在尝试获取 src= 的值 目前我正试图在src=的中获得价值 <div class="page-break no-gaps"> <img id="image-0" src="https://foo.bar/image.jpg" class="wp-image" alt="Title"> </div> 使用以下代码: getImageSrc(imageObj: Cheerio | undefined): string { let image image = imageObj?.attr('src') console.log(image) } 选择器代码: chapterDetailsSelector = 'div.page-break > img' 但是我得到的都是未定义的 编辑 - 添加更多上下文 查看源 HTML 与 Cheerio 获取的内容不一样。 使用 Cheerio 获取时,图像 URL 似乎位于 attr('data-cfsrc') 而不是 attr('data')。

回答 1 投票 0

使用cheerio进行DOM遍历 - 如何获取所有元素及其对应的文本

所以我使用 Cheerio,这是一个类似于 Node 服务器端 jQuery 的库,它允许您解析 html 文本并遍历它,就像使用 jQuery 一样。我需要获取......的纯文本

回答 2 投票 0

从表格中的每一行获取前三个<td>的文本(cheerio)

我想迭代每个 TR,然后使用 Cheerio (https://cheerio.js.org/) 将特定 TD 中的数据添加到新对象。每行包含名称、时间戳和位置数据。我需要数据

回答 2 投票 0

如何在 NodeJS 中按值获取元素的 CSS 选择器?

我正在使用 Node 编写一个网络抓取工具,并考虑使用像 Cheerio 或 JSDom 这样的模块将 HTML 解析为一组 URL 的 DOM。但是,我有一个必需的特定功能......

回答 2 投票 0

抓取网站时数据为空(cheerio.js)

我正在尝试从 CDC 网站上抓取数据。 我使用 Cheerio.js 来获取数据,并将 HTML 选择器复制到我的代码中,如下所示: const listItems = $('#tab1_content > div > 表 >

回答 1 投票 0

Cheerio - 获取 html 标签被空格替换的文本

今天我们使用 Cheerio 的方法,特别是 .text() 方法从 html 输入中提取文本。 但是当 html 是 作者:约翰·史密斯 今天我们使用 Cheerio's,尤其是 .text() 方法从 html 输入中提取文本。 但是当 html 是 <div> By<div><h2 class="authorh2">John Smith</h2></div> </div> 在页面上,“by”一词后面的 /div 确保有空格或换行符。 但是当应用cheerio text()时,我们得到的结果是错误的: ByJohn smith => 这是错误的,因为我们需要在 By 和 john 之间有一个空格。 一般来说,是否可以以一种特殊的方式获取文本,以便任何 html 标签都被空格替换。 (我可以在之后修剪所有多个空格......) 我们希望得到 John smith 的输出 您可以使用以下正则表达式将所有 HTML 标签替换为空格: /<\/?[a-zA-Z0-9=" ]*>/g 因此,当您用此正则表达式替换 HTML 时,它可能会产生多个空格。在这种情况下,您可以使用 replace(/\s\s+/g, ' ') 将所有空格替换为单个空格。 查看结果: console.log(document.querySelector('div').innerHTML.replaceAll(/<\/?[a-zA-Z0-9=" ]*>/g, ' ').replace(/\s\s+/g, ' ').trim()) <div> By<div><h2 class="authorh2">John Smith</h2></div> </div> 您可以使用纯 JavaScript 来完成此任务。 const parent = document.querySelector('div'); console.log(parent.innerText.replace(/(\r\n|\n|\r)/gm, " ")) <div> By<div><h2 class="authorh2">John Smith</h2></div> </div> 一般来说,是否可以以一种特殊的方式获取文本,以便任何 html 标签都被空格替换。 (我可以在之后修剪所有多个空格......) 只需在所有标签之前和之后添加' ': $("*").each(function (index) { $(this).prepend(' '); $(this).append(' '); }); 然后处理多个空格: $.text().replace(/\s{2,}/g, ' ').trim(); //=> "By John Smith" 由于 cheerio 只是 NodeJS 的 jQuery 实现,您可能会发现 这些答案 也很有用。 工作示例: const cheerio = require('cheerio'); const $ = cheerio.load(` <div> By<div><h2 class="authorh2">John Smith</h2></div> </div> `); $("*").each(function (index) { $(this).prepend(' '); $(this).append(' '); }); let raw = $.text(); //=> " By John Smith" (duplicate spaces) let trimmed = raw.replace(/\s{2,}/g, ' ').trim(); //=> "By John Smith" 您可以使用 cheerio 代替 htmlparser2。它允许您在解析 HTML 时每次遇到开始标记、文本或结束标记时定义回调方法。 此代码会产生您想要的输出字符串: const htmlparser = require('htmlparser2'); let markup = `<div> By<div><h2 class="authorh2">John Smith</h2></div> </div>`; var parts = []; var parser = new htmlparser.Parser({ onopentag: function(name, attributes){ parts.push(' '); }, ontext: function(text){ parts.push(text); }, onclosetag: function(tagName){ // no-op } }, {decodeEntities: true}); parser.write(markup); parser.end(); // Join the parts and replace all occurances of 2 or more // spaces with a single space. const result = parts.join('').replace(/\ {2,}/g, ' '); console.log(result); // By John Smith 这是有关如何使用它的另一个示例:https://runkit.com/jfahrenkrug/htmlparser2-demo/1.0.0 Cheerio的text()方法主要用于抓取干净的文本。正如您已经经历过的,这与将 HTML 页面转换为纯文本略有不同。如果您只需要文本进行索引,则可以使用正则表达式替换来添加空格。对于其他一些场景,例如转换为音频,它并不总是有效,因为您需要区分空格和换行符。 我的建议是使用一个库将 HTML 转换为 Markdown。一种选择是调低。 var TurndownService = require('turndown') var turndownService = new TurndownService() var markdown = turndownService.turndown('<div>\nBy<div><h2>John Smith</h2></div></div>') 这将打印出: 'By\n\nJohn Smith\n----------' 最后一行是因为 H2 标题。 Markdown 更容易清理,您可能只需要删除 URL 和图像。文本显示也更容易被人类阅读。 如果您想要内容的干净文本表示,我建议使用 lynx (由古腾堡计划使用)或 pandoc。两者都可以安装,然后使用 spawn 从节点调用。与运行 puppeteer 和使用 textContent 或 insideText 相比,这些将提供更清晰的文本表示。 您还可以尝试遍历 DOM 并根据节点类型添加新行。 import "./styles.css"; import cheerio from "cheerio"; const NODE_TYPES = { TEXT: "text", ELEMENT: "tag" }; const INLINE_ELEMENTS = [ "a", "abbr", "acronym", "audio", "b", "bdi", "bdo", "big", "br", "button", "canvas", "cite", "code", "data", "datalist", "del", "dfn", "em", "embed", "i", "iframe", "img", "input", "ins", "kbd", "label", "map", "mark", "meter", "noscript", "object", "output", "picture", "progress", "q", "ruby", "s", "samp", "script", "select", "slot", "small", "span", "strong", "sub", "sup", "svg", "template", "textarea", "time", "u", "tt", "var", "video", "wbr" ]; const content = ` <div> By March <div> <h2 class="authorh2">John Smith</h2> <div>line1</div>line2 line3 <ul> <li>test</li> <li>test2</li> <li>test3</li> </ul> </div> </div> `; const isInline = (element) => INLINE_ELEMENTS.includes(element.name); const isBlock = (element) => isInline(element) === false; const walkTree = (node, callback, index = 0, level = 0) => { callback(node, index, level); for (let i = 0; i < (node.children || []).length; i++) { walkTree(node.children[i], callback, i, ++level); level--; } }; const docFragText = []; const cheerioFn = cheerio.load(content); const docFrag = cheerioFn("body")[0]; walkTree(docFrag, (element) => { if (element.name === "body") { return; } if (element.type === NODE_TYPES.TEXT) { const parentElement = element.parent || {}; const previousElement = element.prev || {}; let textContent = element.data .split("\n") .map((nodeText, index) => (/\w/.test(nodeText) ? nodeText + "\n" : "")) .join(""); if (textContent) { if (isInline(parentElement) || isBlock(previousElement)) { textContent = `${textContent}`; } else { textContent = `\n${textContent}`; } docFragText.push(textContent); } } }); console.log(docFragText.join("")); 现有答案使用正则表达式或其他库,但这都不是必要的。在 Cheerio 中处理文本节点的技巧是使用 .content(): const cheerio = require("cheerio"); // 1.0.0-rc.12 const html = ` <div> By<div><h2 class="authorh2">John Smith</h2></div> </div>`; const $ = cheerio.load(html); console.log($("div").contents().first().text().trim()); // => By 如果您不确定文本节点将始终是第一个子节点,您可以按如下方式获取所有子节点中的第一个文本节点: const text = $( [...$("div").contents()].find(e => e.type === "text") ) .text() .trim(); console.log(text); // => By 希望不用说,但是"John Smith"部分是标准的Cheerio: const name = $("div").find("h2").text().trim(); console.log(name); // => John Smith 另请参阅: 如何在 Cheerio 中的单个 <br> 标签后获取文本 使用cheerio在没有孩子的情况下在父母中获取文本 cheerio:获取普通+文本节点 如何在 Cheerio 中获取由不同 HTML 标签分隔的文本 Cheerio - 如何抓取元素后面的文本?

回答 7 投票 0

在嵌套div中获取span的attr

这里是抓取新手。 我的问题非常简单,我试图从跨度类“DFlfde SwHCTb”获取值数据值。但是我得到了未定义的回报。什么迷雾啊……

回答 1 投票 0

在cheerio webscraping中使用正则表达式匹配时出现“TypeError:无法读取null的属性”

我想从这个html中删除括号中的内容: Cekcyn(库亚瓦-波美拉尼亚... 我想从这个 html 中删除括号中的内容: <dl class="ooa-1o0axny ev7e6t84"> <dd class="ooa-16w655c ev7e6t83"> <p class="ooa-gmxnzj">Cekcyn (Kujawsko-pomorskie)</p> </dd> <dd class="ooa-16w655c ev7e6t83"> <p class="ooa-gmxnzj">Some other text</p> </dd> </dl> 所以我正在使用(尝试使用)正则表达式(很少有不同,并不重要)例如: $(item[x]).find('.ooa-gmxnzj:first').text().match(/(?<=\().*(?=\))/)[0] 它正在工作,因为我从括号中获取字符串,但就在我也收到错误之后: $(item[x]).find('.ooa-gmxnzj:first').text().match(/(?<=\().*(?=\))/)[0] ^ TypeError: Cannot read properties of null (reading '0') 我检查了我得到的响应是一个数组,以及相同请求的 console.log,只是没有设置元素数组索引,它看起来像只有一个元素的数组: [ 'Kujawsko-pomorskie', index: 8, input: 'Cekcyn (Kujawsko-pomorskie)', groups: undefined ] 我正在使用axios和cheerio。 有人可以解释一下为什么我从 .match 函数创建的数组中收到有关 null 值的错误吗?? 当我在相同的html代码上使用.slice()时,读取数组的所有元素没有问题,没有任何错误。 这些 CSS 选择器看起来有点动态,所以这里有一个使用普通标签并下拉 32 个结果的方法: const axios = require("axios"); // 1.4.0 const cheerio = require("cheerio"); // 1.0.0-rc.12 const url = "<Your URL>"; axios .get(url) .then(({data: html}) => { const $ = cheerio.load(html); const data = [...$("article dd > p")] .map(e => $(e).text().match(/(.*?) *\((.*)\)/)) .filter(Boolean) .map(e => e.slice(1, 3)); console.log(data); }) .catch(err => console.error(err)); 如果您想要获取的数据不仅仅是这一字段: axios .get(url) .then(({data: html}) => { const $ = cheerio.load(html); const data = [...$("main > div > article")] .map(e => ({ something: $(e).find("dd > p") .text() .match(/(.*?) *\((.*)\)/) .slice(1, 3), price: $(e).find("h3").text().trim(), model: $(e).find("h1").text().trim(), mileage: $(e).find('[data-parameter="mileage"]') .text().trim(), fuelType: $(e).find('[data-parameter="fuel_type"]') .text().trim(), })); console.log(data); }) .catch(err => console.error(err)); 需要明确的是,如果您认为 CSS 选择器稳定,您可以使用它们——基本策略基本相同。首先选择容器,即 <article>,然后深入到子项中以收集该项目的数据。 我使用了something,因为我不知道该字段在英语中的含义。

回答 1 投票 0

在cheerio webscraping中使用匹配正则表达式时出现问题

我想从这个html中删除括号中的内容: Cekcyn(库亚瓦-波美拉尼亚... 我想从这个 html 中删除括号中的内容: <dl class="ooa-1o0axny ev7e6t84"> <dd class="ooa-16w655c ev7e6t83"> <p class="ooa-gmxnzj">Cekcyn (Kujawsko-pomorskie)</p> </dd> <dd class="ooa-16w655c ev7e6t83"> <p class="ooa-gmxnzj">Some other text</p> </dd> </dl> 所以我正在使用(尝试使用)正则表达式(很少有不同,并不重要)例如: $(item[x]).find('.ooa-gmxnzj:first').text().match(/(?<=\().*(?=\))/)[0] 它正在工作,因为我从括号中获取字符串,但就在我也收到错误之后: $(item[x]).find('.ooa-gmxnzj:first').text().match(/(?<=\().*(?=\))/)[0] ^ TypeError: Cannot read properties of null (reading '0') 我检查了我得到的响应是一个数组,以及相同请求的 console.log,只是没有设置元素数组索引,它看起来像只有一个元素的数组: [ 'Kujawsko-pomorskie', index: 8, input: 'Cekcyn (Kujawsko-pomorskie)', groups: undefined ] 我正在使用axios和cheerio。 有人可以解释一下为什么我从 .match 函数创建的数组中收到有关 null 值的错误吗?? 当我在相同的html代码上使用.slice()时,读取数组的所有元素没有问题,没有任何错误。 这些 CSS 选择器看起来有点动态,所以这里有一个使用普通标签并下拉 32 个结果的方法: const axios = require("axios"); // 1.4.0 const cheerio = require("cheerio"); // 1.0.0-rc.12 const url = "<Your URL>"; axios .get(url) .then(({data: html}) => { const $ = cheerio.load(html); const data = [...$("article dd > p")] .map(e => $(e).text().match(/(.*)\((.*)\)/)) .filter(Boolean) .map(e => e.slice(1, 3)); console.log(data); }) .catch(err => console.error(err));

回答 1 投票 0

Cheerio - 如何抓取元素后面的文本?

使用cheerio,我怎样才能抓取一个html元素后面的2个单独的html内容,而不是在特定的html元素内? 我想抓取的是来自: 使用cheerio,我如何抓取一个html元素后面的2个单独的html内容,而不是在特定的html元素内? 我想抓取的是来自: <div> <time> <svg>...<svg/> "first string I want to grab" <svg>...<svg/> "second string I want to grab" </time> </div> $(item).find('div').find('time').find('svg:nth-of-type(2)').text(); const result = [...$(item).find('header').find('div').find('span:nth-of-type(1)').find('time').childNodes] .filter(e => e.nodeType === Node.TEXT_NODE && e.textContent.trim() ) .map(e => e.textContent.trim()); 您的示例不可重现,但如果您修复选择器和/或使用正确的结束标签,</svg>而不是<svg/>,这个答案应该开箱即用: const cheerio = require("cheerio"); // 1.0.0-rc.12 const html = `<div> <time> <svg>...</svg> "first string I want to grab" <svg>...</svg> "second string I want to grab" </time> </div>`; const $ = cheerio.load(html); const result = [...$("div time").contents()] .filter(e => e.type === "text" && $(e).text().trim()) .map(e => $(e).text().trim()); console.log(result); 输出: [ '"first string I want to grab"', '"second string I want to grab"' ] 正如评论中提到的,CSS已经处理后代,所以你可以使用 .find("header div span:nth-of-type(1) time") 而不是 .find('header').find('div').find('span:nth-of-type(1)').find('time') 如果这不起作用,请分享您正在使用的实际网站或完整的 HTML 结构。请注意,Cheerio 仅适用于静态 HTML,因此如果该网站使用 JavaScript 创建这些元素,并且您在开发工具中看到它们,这可能可以解释为什么您找不到它们。确保元素在网站的 view-source: 版本中可见。

回答 1 投票 0

使用Cheerio抓取信息

我正在使用 Nodejs 和 Cheerio 包来收集网站上的信息,在迭代将信息存储到数组中后,我正在努力收集信息。 文字我...

回答 1 投票 0

为什么从特定网站抓取效果不佳?

我想从此网址中删除所有警报详细信息 - https://www.oref.org.il/12481-en/Pakar.aspx 我写了这段代码,但我认为是因为“在过去一周”不活跃,所以找不到...

回答 1 投票 0

使用 Cheerio JS 在对象中存储特定值的数据

我正在使用 Node 和 Cheerio JS 练习网页抓取,我需要帮助。 我有这个示例表,我很困惑如何获取每场比赛的主场赔率和客场赔率 (tr) 并存储...

回答 1 投票 0

从带有多个标签的 cheerio 中的 XML 元素中获取特定文本

使用 cheerio 解析 XML,我试图从标签中仅获取用户可读的描述。 IE。 使用 cheerio 解析 XML,我试图从标签中仅获取用户可读的描述。即 <description><![CDATA[<p><img src="https://www.boxingnews24.com/wp-content/uploads/2023/04/Gervonta-Davis-vs-Ryan-Garcia1-Boxing-Photos.jpg" style="display: block; margin: 1em auto"></p> <p>By <strong>Sam Volz:</strong> *****Eddie Hearn views it as positive if Ryan Garcia teams up with his former trainer Eddy Reynoso to try and pick up***** &#8230; <a href="https://www.boxingnews24.com/2023/05/eddie-hearn-reacts-to-ryan-garcia-possibly-linking-up-with-reynoso/" class="read-more">read full story &#8592; </a></p> <p><a rel="nofollow" href="https://www.boxingnews24.com/2023/05/eddie-hearn-reacts-to-ryan-garcia-possibly-linking-up-with-reynoso/">Eddie Hearn reacts to Ryan Garcia possibly linking up with Reynoso</a> @ <a rel="nofollow" href="https://www.boxingnews24.com">Boxing News 24</a></p> ]]></description> 我用多个“*”包裹了我要检索的文本。没有特定的类属性,我不确定如何获取它,因为还有多个 p 标签。只是想补充一下我是 cheerio 的新手。 为清楚起见,我要检索的文本是“Eddie Hearn 认为如果 Ryan Garcia 与他的前任教练 Eddy Reynoso 合作并尝试接受它是积极的” 此代码针对此特定输入返回您想要的结果,但我不清楚我们是否可以依靠 <strong> 的存在以及您 <p> 中子注释的排序来使其适用于其他情况。在没有描述我们应该如何识别这个文本的一般情况下,我天真地假设我们想要的文本是第三个孩子: const cheerio = require("cheerio"); // ^1.0.0-rc.12 const xml = `<description><![CDATA[<p><img src="https://www.boxingnews24.com/wp-content/uploads/2023/04/Gervonta-Davis-vs-Ryan-Garcia1-Boxing-Photos.jpg" style="display: block; margin: 1em auto"></p> <p>By <strong>Sam Volz:</strong> *****Eddie Hearn views it as positive if Ryan Garcia teams up with his former trainer Eddy Reynoso to try and pick up***** &#8230; <a href="https://www.boxingnews24.com/2023/05/eddie-hearn-reacts-to-ryan-garcia-possibly-linking-up-with-reynoso/" class="read-more">read full story &#8592; </a></p> <p><a rel="nofollow" href="https://www.boxingnews24.com/2023/05/eddie-hearn-reacts-to-ryan-garcia-possibly-linking-up-with-reynoso/">Eddie Hearn reacts to Ryan Garcia possibly linking up with Reynoso</a> @ <a rel="nofollow" href="https://www.boxingnews24.com">Boxing News 24</a></p> ]]></description>`; const $ = cheerio.load(xml, {xmlMode: true}); console.log($([...$.load($("description").text())("p").contents()][3]).text());

回答 1 投票 0

cheerio 与 API 的离子创建

我正在创建一个离子应用程序。我将 Cheerio 与 Node.js 结合使用来抓取网站。我无法将整个数组返回到本地主机,它只返回第一个对象。我怎样才能退回整个...

回答 1 投票 0

Cheeriojs 从选择/选项中检索所有文本和属性

我在网页中有以下代码,我必须从第二个选择中检索所有选项文本和属性以将它们放入变量中。 我这样试过,但没有用,没有

回答 1 投票 0

如何使用 Cheerio 提取大写属性

我有一个日志条目如下: 访问的页面: 我有一个日志条目如下: <Event Timestamp="2017-06-14T10:17:09.313991+10:00" Level="INFO" Identity=""><Message>Accessed Page: </Message></Event> 我想用 Cheerio 提取 Timestamp、Level 等属性。我所做的是这样的: const $ = cheerio.load(line) console.log($("Event").attr('Timestamp')) 但是,我只是在控制台中未定义。你能告诉我问题出在哪里吗? .attr() 是正确的 Cheerio 方法调用,但 HTML(或其他任何内容)很奇怪。在 HTML 中,属性是小写的,所以如果您使用 "timestamp" 和小写的 "t":,您应该会得到正确的结果 const cheerio = require("cheerio"); // 1.0.0-rc.12 const html = ` <Event Timestamp="2017-06-14T10:17:09.313991+10:00" Level="INFO" Identity=""><Message>Accessed Page: </Message></Event> `; const $ = cheerio.load(html); console.log($("Event").attr("timestamp")); // => 2017-06-14T10:17:09.313991+10:00

回答 1 投票 0

使用 Cheerio 和 Nodejs 抓取 ebay 图像缩略图

我可以使用 Nodejs、Axios 和 Cheerio 从 ebay 搜索中获取标题、价格、日期等,但是我无法将 img 缩略图 url 放入我的 items.json 文件中。 这是我的代码...

回答 1 投票 0

如何在没有 API 访问权限的情况下获取 Airbnb 房源数据

是否有任何方法可以通过列表 ID 以编程方式获取有关 Airbnb 列表的数据?比如面积。他们不接受对其 API 的新请求。 Airb 是否有第三方 API...

回答 0 投票 0

© www.soinside.com 2019 - 2024. All rights reserved.