如何用Cheerio保留网页文本删除线样式(适配Discord嵌入)
解决方案
修改后的代码
const cheerio = require("cheerio"); const fetch = (...args) => import('node-fetch').then(({default: fetch}) => fetch(...args)); async function scrapeInformation() { const response = await fetch('https://scp-wiki.wikidot.com/personnel-and-character-dossier'); const body = await response.text(); const $ = cheerio.load(body); const titleList = []; const wikiTab = $('#wiki-tab-0-6 > p'); wikiTab.each((i, title) => { let formattedText = ''; // 遍历当前p标签下的所有子节点(含文本节点和元素节点) $(title).contents().each((_, node) => { if (node.nodeType === 3) { // 文本节点直接追加内容 formattedText += node.nodeValue.trim(); } else if (node.nodeType === 1) { const $node = $(node); // 判断是否是带删除线样式的span标签 if ($node.is('span') && $node.attr('style')?.includes('text-decoration: line-through')) { // 用Discord支持的~~包裹删除线文本 formattedText += `~~${$node.text().trim()}~~`; } else { // 其他元素节点直接提取文本 formattedText += $node.text().trim(); } } }); titleList.push(formattedText); console.log(formattedText); // 测试输出格式化后的文本 }); } scrapeInformation();
核心逻辑说明
- 替换原有的
text()方法:原方法会直接忽略所有标签结构,提取纯文本,导致删除线格式丢失。改用.contents()遍历所有子节点,保留结构信息。 - 区分节点类型:通过
nodeType判断是文本节点(值为3)还是元素节点(值为1),分别处理。 - 识别删除线元素:针对带有
text-decoration: line-through样式的span标签,将其文本内容用~~包裹,适配Discord的删除线格式。
相关学习点
- Cheerio的
.contents()方法:用于获取元素下的所有子节点(包括文本、注释、元素等),是处理混合文本与元素结构的关键方法。 - DOM节点类型:
nodeType是标准DOM属性,Cheerio节点对象完全支持,可用来区分不同类型的节点。 - 属性检查:使用
.attr()获取元素的属性值,配合字符串判断实现特定样式元素的识别。
内容的提问来源于stack exchange,提问作者powaidan
相关产品推荐
相关产品推荐

