如何使用Node.js解析HTML页面

110

我需要解析(服务端)大量的HTML页面。
我们都认为正则表达式不是解决这个问题的方法。
在我看来,JavaScript 是解析 HTML 页面的本地方式,但这种假设依赖于服务器端代码具有浏览器内 JavaScript 的所有 DOM 能力。

Node.js 是否具备此能力?
是否有更好的方法来解决这个问题,即在服务器端解析 HTML?

6个回答

107
你可以使用 npm 模块 jsdomhtmlparser 在 Node.JS 中创建和解析 DOM。
其他选项包括: 在所有这些选项中,我更喜欢使用 Node.js 选项,因为它使用标准的 W3C DOM 访问器方法,我可以在客户端和服务器上重用代码。我希望 BeautifulSoup 的方法更类似于 W3C dom,并且我认为将 HTML 转换为 XHTML 来编写 XSLT 只是一种残忍的行为。

3
“好”是什么意思?可靠、快速、易用?这两者足够强大,以至于您可以选择在服务器端使用jQuery(如果您愿意的话)。具体见此链接:https://dev59.com/anI-5IYBdhLWcg3wio9k。 - kzh
1
@kzh 对我来说,可靠和易用比过程是否在一小时或一天内结束更重要。 - Itay Moav -Malimovka
我在互联网上搜索了很久,但找不到一个好的HTML解析器教程。 - songyy
我个人认为jsdom更容易。 - Rishav
其他选项,回答中的旧链接,请使用此链接代替:pip install beautifulsoup4 - Robert Rendell
显示剩余3条评论

69

使用Cheerio。它不像jsdom那么严格,而是针对爬取进行了优化。作为奖励,使用您已经熟悉的jQuery选择器。

❤ 熟悉的语法:Cheerio实现了核心jQuery的子集。 Cheerio 从jQuery库中删除了所有DOM不一致性和浏览器垃圾,揭示了其真正华丽的API。

ϟ 极快速度:Cheerio使用非常简单、一致的DOM模型。因此解析、操作和渲染效率非常高。初步端到端基准测试表明,Cheerio比JSDOM快约8倍。

❁ 极度灵活:Cheerio包装@FB55的宽容htmlparser。Cheerio可以解析几乎任何HTML或XML文档。


10
但它不构建DOM,也不支持XPath。jQuery的语法显然是该库的缺点。 - polkovnikov.ph
2
根据我的经验,很少有应用需要完整的DOM解析,而构建DOM与jQuery/Cheerio中快速的“惰性”评估相比非常昂贵。从这个意义上说,jQuery风格的解析是一种优势,但如果您的应用程序需要在服务器端操作DOM,则可能更喜欢尝试jsdom。 - Meekohi
jsdom 对此太慢了 :/ - polkovnikov.ph
2
@MohamedMansour 说实话,我们正在生产中使用Cheerio,并在几秒钟内爬取数千个页面。当然,“快”和“慢”都是相对于您的应用程序和带宽而言。 - Meekohi
非严格模式:+1。jQuery语法:+1。 - Jonas Sourlier

20

2020年11月更新

我搜索了顶级的NodeJS HTML解析库。

由于我的用例不需要拥有很多功能的库,所以我可以专注于稳定性和性能。

通过稳定性,我指的是希望这个库被社区长时间使用以发现错误,并且它仍然会得到维护,并且开放的问题将会被关闭。

很难理解一个开源库的未来,但基于在 openbase 上排名前十的库,我做了一个小结。

我根据最后一次提交将它们分成两组(每组的顺序都按照 Github 星数排序):

最近6个月内有提交记录:

jsdom - 最后一次提交:3 个月前, 开放的问题数目:331, Github 星数:14.9K.

htmlparser2 - 最后一次提交:8 天前, 开放的问题数目:2, Github 星数:2.7K.

parse5 - 最后一次提交:2 个月前, 开放的问题数目:21, Github 星数:2.5K.

swagger-parser - 最近提交:2个月前,开放问题:48个,Github 星数:663

html-parse-stringify - 最近提交:4个月前,开放问题:3个,Github 星数:215

node-html-parser - 最近提交:7天前,开放问题:15个,Github 星数:205

最近提交时间为6个月或以上:

cheerio - 最近提交:1年前,开放问题:174个,Github 星数:22.9K

koa-bodyparser - 最近提交:6个月前,开放问题:9个,Github 星数:1.1K

sax-js - 最近提交:3年前,开放问题:65个,Github 星数:941

draftjs-to-html - 最近提交:1年前,开放问题:27个,Github 星数:233


我选择了 Node-html-parser,因为它似乎非常快速,并且此时非常活跃。

(*) Openbase增加了更多关于每个库的信息,比如贡献者数量(至少+3次提交)、每周下载量、每月提交次数、版本等。

(**) 上面的表格是根据特定时间和日期的快照 - 我会再次检查参考资料,并首先检查最近的活动水平,然后深入了解更细节的内容。


1
我喜欢这个答案,因为它强调了节点开发人员必须经历的不可避免的过程,以审核那些大量可用的几乎重复的模块。这是我在2023年进行的一项调查。唯一不变的是变化。 - moodboom

13

如何获得与此演示中相同的精确输出? - Penguin9

6

Htmlparser2 是由 FB55 开发的一个不错的替代工具。


4
这种返回格式应该怎么处理?需要编写一系列的for循环和树遍历吗? - polkovnikov.ph
您可以注册以打开/关闭标签事件,所以根据您想要的内容,这是一个非常好的选择,我认为。 - Phil
@polkovnikov.ph 同作者还有一个名为 domutils 的包,它可以处理 htmlparser2 返回的格式 - 它有很多方法,其中一些具有与 DOM 方法相同的语法,一些则不同;您不需要手动遍历对象。没有文档,但源代码非常清晰 - 所有内容都按照您的预期工作。 - esp
还没有,但是有什么阻止你扩展它呢?使用它已经拥有的函数并不难。 - esp

2
jsdom对于真正的屏幕抓取操作来说太严格了,但是beautifulsoup不会因为糟糕的标记而出错。 node-soupselect是将Python的beautifulsoup移植到Node.js的端口,它运行得非常好。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接