NodeJS 中寻找可用的 HTMLParser
原文地址:http://huangx.in/2012/5/nodejs_for_available_htmlparser.html
简介
项目中需要实现对一个HTML页面解析的情况,开发环境是MacOSX lion,NodeJS v0.6.14。
本次实践,分别对**libxmljs, libxmljs-easy, jsdom, node-htmlparser, node-jquery,Apricot** 五类框架进行测试,最终采用node-jquery实现了对不规范的HTML文档的兼容,能够正常解析。
试错
最初延续Python中的经验,找libxml相关的类库,因为libxml支持XPath,可以很方便的解析HTML。
在node modules wiki页面中,找到了有两款,libxml和libxml-easy,后者是对前者API的一个再封装。使用npm安装后,发现无法解析页面,报错Error: Start tag expected, '<' not found
,发现页面不是标准的HTML。
于是尝试jsdom,采用Javascript原生实现的W3C DOM操作类库。使用时发现他对抓取页面的逻辑封装还是挺到位的,能够直接通过网址抓取,不过使用中还是报错 SyntaxError: Unexpected token ILLEGAL
。仍然无法解析。
再找到一个对HTML格式很"宽容"的解析器html-parser,编译一番API调用后,发现能够解析,虽然API很不友好,都是围绕DOM的属性进行操作,没有提供CSS selector,如果要检索页面内容会很麻烦,于是找到基于html-parser和jsdom的封装Apricout,部署一会儿部署不上,要求x86系统以及macos系统,感觉是作者粗心,将源码clone下来后,发现版本较老,一些系统类库都改名了,于是手工修改,改动如下:
diff --git a/lib/apricot.js b/lib/apricot.js
index 9e0251c..5cc3546 100644
--- a/lib/apricot.js
+++ b/lib/apricot.js
@@ -4,7 +4,7 @@ var http = require('http'),
url = require('url');
exports.Apricot = Apricot;
-sys = require('sys');
+sys = require('util');
function Apricot(content,live) {
diff --git a/package.json b/package.json
index 18cbdbd..fd8790b 100644
--- a/package.json
+++ b/package.json
@@ -31,16 +31,18 @@
}
],
"dependencies": {
- "jsdom": "= 0.1.2",
- "htmlparser": "= 1.6.2"
+ "jsdom": ">= 0.1.2",
+ "htmlparser": ">= 1.6.2"
},
"os": [
"linux",
"macos",
+ "darwin",
"win"
],
"cpu": [
"x86",
+ "x64",
"ppc",
"x86_64"
],
安装成功后,测试的时候发现报错innerHTML
无法写入。查看源码后发现是Apricout调用sizzle构造DOM时,报错,没有正常返回document,所以找不到innherHTML,于是再去找其他类库。
最终使用node-jquery,简单的例子一下就返回了如预期的结果(CoffeeScript):
dom = jquery(body)
for i in dom.find(".targetCssName")
console.log i.innerHTML
思考
数据挖掘中,一般有一个数据格式化的过程,这个步骤就包含了上述的内容,针对各个平台可能使用的方法有所差异,不过大体都是对互联网上未经处理的HTML内容,进行格式化处理。而处理的方式又有多种,下面列举一些常见的HTML格式化信息方法,以及他们的优缺点:
-
进行前后边界查找后,定位内容区域,进行字符串的检索。优点:速度快,缺点:面对复杂的HTML可能需要很繁重的边界定位工作,我是指完成编码时的人工定位。
-
正则表达式,属于上面的加强版,不过采用了更容易描述的正则表达式,不过也有人持不同的观点。优点:速度不慢,缺点:构造表达式很耗时。
-
构造DOM然后采用CSS selector或者XPath进行检索。优点:检索方便,能够避免DOM顺序调整之类的页面变动,缺点:速度慢,开销大,需要构造DOM
对于发展中的nodeJS生态圈表示仍然很乐观,因为本文也从一个侧面反映了基于Javascript的开发环境,基础框架层出不穷,很容易找到契合自己业务相关的实现,而且有一个活跃的社区,从事相关开发是一个不错的选择。