node.js使用jsdom解析HTML抓取网站数据
本文由 小茗同学 发表于 2016-06-25 浏览(9668)
最后修改 2017-04-24 标签:node.js 解析 html 网页 jsdom

前言

解析HTML这事儿本来就是js的强项,以前一直用Java来做,感觉老苦逼了,虽然也有一些插件来辅助,但是用的很蛋疼,node.js的出现简直是一大福音。

虽然如此,但毕竟nodejs没有浏览器,解析html还是需要第三方库支持的。

代码

jsdom_v9

重要说明:jsdom从v10开始又更换了api,fuck!以下代码只对v9有效。

首先准备环境:

npm install -g jquery(这个不用说了)
npm install -g jsdom(这个是辅助获取window对象的)
npm install -g http(这个是下载用的)

我装的版本全部是最新的,如下:

jquery@3.0.0
jsdom@9.2.1

下面以抓取百度首页为例:

var jsdom = require('jsdom');
var window = jsdom.jsdom().defaultView;
var $ = require('jquery')(window);
var http = require('http');
var fs = require('fs');

var options =
{
	host: 'www.baidu.com',
	port: 80,
	path: '/'
};

var html = '';
http.get(options, function(res)
{
	res.on('data', function(data)
	{
		html += data;
	}).on('end', function()
	{
		console.log('html:'+html);
		$('body').append(html); // 将下载的html数据append到body里面去
		var result = $('body').find('#ftCon').html(); // 这里随便抓取一点东西
		fs.writeFile('result.txt', result, function()
		{
			console.log('写入完毕!');
		});
	 });
});

jsdom_v10

以下代码使用的jsdom版本是10.0.0,jquery是3.2.1

const fs = require('fs');
const jsdom = require("jsdom");
const jquery = require('jquery');
const { JSDOM } = jsdom;

var dom = new JSDOM(`<!DOCTYPE html><p>Hello world</p>`);;
var window = dom.window; // 获取 window 对象
var document = dom.window.document; // 获取 document 对象
var $ = jquery(window); // 实例化jquery需要传入window对象
console.log(document.body.innerHTML);
console.log($('body').html());
$('body').append('<p>我勒个去!</p>');
console.log(document.documentElement.outerHTML); // 获取整个html代码
// dom.serialize() 比 document.documentElement.outerHTML 多了DOCTYPE
console.log(dom.serialize());

补充

如果直接使用jQuery会报如下错误:

“jQuery requires a window with a document”

原因是node.js不是浏览器环境,没有window对象,需要jsdom这个插件来模拟。

网上一大推错误或者过时的文章误导人,这里总结并纠正一下:

默认安装jquery时,版本是最新版2.1.0,这个版本没有包括jsdom,需要额外安装一个jsdom,然后这么使用:
var jsdom = require(“jsdom”);
$ = require(“jquery”)(jsdom.jsdom().createWindow());
也可以简单地将jquery卸载掉,安装一个低版本的,如下:
$npm install -g jquery@1.6.3

错误一:新版本的jsdom方法名字改了,不是jsdom.jsdom().createWindow(),而是jsdom.jsdom().defaultView
错误二:仅仅是下载低版本jQuery没用,也不推荐;

还有一种说法是jquery有2个插件,一个是小写的jquery,一个是大写的jQuery,然后我试了下:

> npm install jQuery
npm WARN deprecated jQuery@1.7.4: This is deprecated. Please use 'jquery'

提示jQuery已经过时了,请使用jquery,这里还是要感谢万能的stackoverflow.com,国内的网站搜到的东西经常是互相转载错误又过时的。