pol*_*.ph 29 html javascript xpath node.js phantomjs
我正在使用Node.js进行一些网络抓取.我想使用XPath,因为我可以使用几种GUI半自动生成它.问题是我找不到有效地做到这一点的方法.
jsdom
非常慢.它在一分钟左右的时间内解析了500KiB文件,并且CPU负载全部,内存占用空间很大.cheerio
)既不支持XPath,也不暴露符合W3C的DOM.phantom
或casper
将是一个选项,但那些需要以特殊方式运行,而不仅仅是node <script>
.我不能依赖这种变化所暗示的风险.例如,找到如何运行node-inspector
起来要困难得多phantom
.Spooky
是一个选项,但它足够多,所以它在我的机器上根本没有运行.那么用XPath解析HTML页面的正确方法是什么?
小智 35
您可以通过几个步骤完成此操作.
parse5
.坏的部分是结果不是DOM.虽然它足够快和W3C兼容.xmlserializer
并接受类似DOM的parse5
输入结构.xmldom
.现在你终于拥有了那个DOM.xpath
库基于xmldom
,允许您运行XPath查询.请注意,XHTML有自己的命名空间,而查询//a
不起作用.最后你得到这样的东西.
const fs = require('mz/fs');
const xpath = require('xpath');
const parse5 = require('parse5');
const xmlser = require('xmlserializer');
const dom = require('xmldom').DOMParser;
(async () => {
const html = await fs.readFile('./test.htm');
const document = parse5.parse(html.toString());
const xhtml = xmlser.serializeToString(document);
const doc = new dom().parseFromString(xhtml);
const select = xpath.useNamespaces({"x": "http://www.w3.org/1999/xhtml"});
const nodes = select("//x:a/@href", doc);
console.log(nodes);
})();
Run Code Online (Sandbox Code Playgroud)
mb2*_*b21 14
Libxmljs目前是最快的实现(类似于基准测试),因为它只绑定到支持XPath 1.0查询的LibXML C库:
var libxmljs = require("libxmljs");
var xmlDoc = libxmljs.parseXml(xml);
// xpath queries
var gchild = xmlDoc.get('//grandchild');
Run Code Online (Sandbox Code Playgroud)
但是,您需要首先清理HTML并将其转换为正确的XML.为此你可以使用HTMLTidy命令行实用程序(tidy -q -asxml input.html
),或者如果你想让它保持仅节点,像xmlserializer这样的东西就可以了.
归档时间: |
|
查看次数: |
16362 次 |
最近记录: |