使用Cheerio爬取含MathJax网页:获取内容与MathML数据方法
Cheerio爬取网页内容的问题解决
问题背景
我用Cheerio爬取某网站,需要解决两个问题:
- 如何获取p标签的完整文本?
- 如何获取带有
data-mathml属性的span元素?
另外,对于这类span标签,应该提取文本内容还是data-mathml属性返回给客户端?
相关HTML示例:
<p><strong class="content_question">Đề bài</strong></p> <p style="text-align: justify;">"a. " <span class="MathJax_Preview" style="color: inherit; display: none;"></span> <span id="MathJax-Element-1-Frame" class="mjx-chtml MathJax_CHTML" tabindex="0" style="font-size: 121%; position: relative;" data-mathml="<math xmlns="http://www.w3.org/1998/Math/MathML"><mn>5</mn></math>" role="presentation"><span id="MJXc-Node-1" class="mjx-math" aria-hidden="true"><span id="MJXc-Node-2" class="mjx-mrow"><span id="MJXc-Node-3" class="mjx-mn"><span class="mjx-char MJXc-TeX-main-R" style="padding-top: 0.37em; padding-bottom: 0.37em;">5</span></span></span></span><span class="MJX_Assistive_MathML" role="presentation"><math xmlns="http://www.w3.org/1998/Math/MathML"><mn>5</mn></math></span></span><script type="math/tex" id="MathJax-Element-1">5</script> và <span class="MathJax_Preview" style="color: inherit; display: none;"></span><span id="MathJax-Element-2-Frame" class="mjx-chtml MathJax_CHTML" tabindex="0" style="font-size: 121%; position: relative;" data-mathml="<math xmlns="http://www.w3.org/1998/Math/MathML"><mroot><mn>123</mn><mn>3</mn></mroot></math>" role="presentation"><span id="MJXc-Node-4" class="mjx-math" aria-hidden="true"><span id="MJXc-Node-5" class="mjx-mrow"><span id="MJXc-Node-6" class="mjx-mroot"><span class="mjx-root" style="font-size: 50%; vertical-align: 0.774em; width: 0px;"><span id="MJXc-Node-8" class="mjx-mn" style="padding-left: 0.543em;"><span class="mjx-char MJXc-TeX-main-R" style="padding-top: 0.37em; padding-bottom: 0.37em;">3</span></span></span><span class="mjx-box" style="padding-top: 0.045em;"><span class="mjx-surd"><span class="mjx-char MJXc-TeX-main-R" style="padding-top: 0.507em; padding-bottom: 0.553em;">√</span></span><span class="mjx-box" style="padding-top: 0.119em; border-top: 1.6px solid;"><span id="MJXc-Node-7" class="mjx-mn"><span class="mjx-char MJXc-TeX-main-R" style="padding-top: 0.37em; padding-bottom: 0.37em;">123</span></span></span></span></span></span></span><span class="MJX_Assistive_MathML" role="presentation"><math xmlns="http://www.w3.org/1998/Math/MathML"><mroot><mn>123</mn><mn>3</mn></mroot></math></span></span> <script type="math/tex" id="MathJax-Element-2">\root 3 \of {123} </script> " ;"</p>
当前使用的Cheerio代码:
const html = response.data; const $ = cheerio.load(html); const mathjaxEquations = $("span[data-mathml]"); console.log({ mathjaxEquations });
解决方案
1. 获取p标签的完整文本
直接用Cheerio的text()方法,它会提取标签下所有层级的文本内容,不管元素是否隐藏(比如示例里的MathJax_Preview)。
代码示例:
const html = response.data; const $ = cheerio.load(html); // 获取所有p标签的文本,返回数组 const allPTexts = $('p').map((index, element) => $(element).text()).get(); console.log(allPTexts); // 精准获取第二个p标签的文本 const targetParagraphText = $('p').eq(1).text(); console.log(targetParagraphText);
2. 获取带有data-mathml属性的span元素
你的选择器$("span[data-mathml]")是正确的,但需要遍历提取具体内容:
const html = response.data; const $ = cheerio.load(html); // 获取所有符合条件的span元素 const mathjaxSpans = $('span[data-mathml]'); // 提取每个span的data-mathml属性值,返回数组 const mathmlContents = mathjaxSpans.map((index, element) => $(element).attr('data-mathml')).get(); console.log(mathmlContents); // 提取每个span的文本内容,返回数组 const spanTexts = mathjaxSpans.map((index, element) => $(element).text()).get(); console.log(spanTexts);
3. 提取文本还是data-mathml属性?
根据客户端需求决定:
- 如果客户端只需要纯文本展示,提取span的文本内容即可(比如示例里的"5"、"³√123");
- 如果客户端需要渲染标准的数学公式,优先提取data-mathml属性。因为MathML是W3C标准的数学标记语言,客户端可以用MathJax或浏览器原生支持渲染,能完整保留公式的结构和格式,比纯文本更准确。
内容的提问来源于stack exchange,提问作者Mai Đức Thắng
相关产品推荐
相关产品推荐

