版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_39198406/article/details/87173678
引言
最近需要使用node.js
访问网页、解析html
文档进而提取网页上面的数据。
由于使用python
写爬虫的时习惯使用xpath
进行html
文档解析,于是也许搜了一下xpath
解析方式的node.js
实现。
发现了两个第三方库:
分别是xpath.js
和xpath
,xpath
是fork的xpath.js
项目进一步开发的,最后commit时间较原始项目更近,使用方式也更加人性化。
关于xpath
项目,可以在项目主页上看到一些使用示例,也可以看到文档。
我们选用goto100/xpath
进行html
解析。
依赖
npm install xpath
npm install xmldom
作者推荐使用xmldom
作为xml
引擎。
例子
例1
const xpath = require('xpath')
const dom = require('xmldom').DOMParser
let xml = "<book><title>Harry Potter</title></book>"
let doc = new dom().parseFromString(xml)
let nodes = xpath.select("//title", doc)
console.log(nodes[0].localName + ": " + nodes[0].firstChild.data)
console.log("Node: " + nodes[0].toString())
例2
const fs = require('fs');
const xpath = require('xpath');
const dom = require('xmldom').DOMParser;
const util = require('util');
// 打开文件
let content = fs.readFileSync("123.html", {encoding: 'UTF-8'});
// 构造dom
let doc = new dom().parseFromString(content, 'text/xml');
// 抽取指定元素1
let titles = xpath.select("//title", doc);
// 抽取元素长度
console.log(util.format("length: %s", titles.length));
// 遍历
titles.forEach(function (title, index) {
console.log("title: " + title.toString())
});
// 抽取指定元素2
let items = xpath.select("//div[@id='mac-data']/table/tr", doc);
// 抽取元素长度
console.log(util.format("length: %s", items.length));
// 遍历
items.forEach(function (item, index) {
// xpath解析子元素
let field = xpath.select("string(./td[2]/a)", item);
console.log(field);
});
遇到的问题
网址www.chinanpo.gov.cn/search/orgcx.html
的页面是xhtml
标准,导致xpath
会按照xhtml
标准解析。
页面上会有以下元素:
<html xmlns="http://www.w3.org/1999/xhtml">
xpath库会将页面辨认为xhtml
格式。
由于xhtml
标准严格定义html
标签的闭合,而这个页面上面会有两个标签,导致解析失败,无法使用xpath
抽取数据。
当我们把<html xmlns="http://www.w3.org/1999/xhtml">
中的xmlns="http://www.w3.org/1999/xhtml"
去掉之后,可以正常解析。
因此我们写正则,过滤html
标签中的xmlns
属性:
content = content.replace(/<html\s.*?>/g, "<html>");
然后就可以使用xpath
正常解析了。