如何用Node写页面爬虫的工具集?
一、准备工作
-
安装Node.js环境。
-
安装Node.js的包管理器npm,安装方法为在终端中输入
npm install npm -g
。 -
安装request、cheerio、iconv-lite等Node模块,这些模块用于发起网络请求、解析HTML页面内容和处理编码问题,命令行方式为
npm install request cheerio iconv-lite -S
。
二、基础知识
- HTTP请求
Node.js中发起HTTP请求的方式比较简单,利用request模块实现对目标网页的请求。下面是一个最简单的request请求:
const request = require('request');
request('http://www.baidu.com', function (error, response, body) {
console.log('error:', error); // 输出可能出现的错误信息
console.log('statusCode:', response && response.statusCode); // 输出响应的状态码
console.log('body:', body); // 输出响应的内容
});
- HTML解析
Node.js中有很多解析HTML的模块,其中比较常用的是cheerio模块。cheerio模块拥有和jQuery类似的API,操作起来比较简单。使用方式如下:
const cheerio = require('cheerio');
const html = '<div class="container"><h1>标题</h1><ul><li>条目1</li><li>条目2</li></ul></div>';
const $ = cheerio.load(html);
console.log($('h1').text()); // 输出“标题”
console.log($('li').text()); // 输出“条目1 条目2”
此外,对于每个节点可以使用attr方法获取它的属性值,例如:
console.log($('div').attr('class')); // 输出“container”
- 编码处理
有些页面可能会出现编码问题,比如HTML页面的编码是gbk,但是我们在Node.js中获取响应内容时却是utf-8的格式,因此需要使用iconv-lite模块将其中一个编码格式转成另一个编码格式,代码如下:
const iconv = require('iconv-lite');
const content = '<meta charset="gbk"><div class="container">容器</div>';
const buffer = iconv.encode(content, 'gbk'); // 将内容按照gbk编码转成buffer对象
const decodedContent = iconv.decode(buffer, 'utf-8'); // 将buffer对象按照utf-8编码转成字符串
console.log(decodedContent); // 输出“容器”
三、编写页面爬虫的工具集
在了解了Node.js的基础知识之后,我们可以开始编写页面爬虫的工具集。
下面是一个最简单的爬虫程序,作用是获取目标网页的所有文本内容:
const request = require('request');
const cheerio = require('cheerio');
const iconv = require('iconv-lite');
function getHtmlText(url, encoding, callback) {
request({
url,
encoding: null, // 需要设置为null,才能获取到buffer对象
}, (error, response, body) => {
if (error || response.statusCode !== 200) {
callback(error);
return;
}
const decodedBody = iconv.decode(body, encoding || 'utf-8');
const $ = cheerio.load(decodedBody);
callback(null, $('body').text());
});
}
上述代码中的getHtmlText函数包含三个参数:目标网页的URL、目标网页的编码和回调函数,其中回调函数的参数是error和text,表示请求过程中的错误信息和目标网页的文本内容。
我们可以扩展该工具集,添加一些有用的功能,比如获取页面中的所有链接,代码如下:
const request = require('request');
const cheerio = require('cheerio');
const iconv = require('iconv-lite');
function getHtmlLinks(url, encoding, callback) {
request({
url,
encoding: null, // 需要设置为null,才能获取到buffer对象
}, (error, response, body) => {
if (error || response.statusCode !== 200) {
callback(error);
return;
}
const decodedBody = iconv.decode(body, encoding || 'utf-8');
const $ = cheerio.load(decodedBody);
const links = [];
$('a').each((index, element) => {
links.push({
text: $(element).text(),
href: $(element).attr('href'),
});
});
callback(null, links);
});
}
上述代码中的getHtmlLinks函数通过遍历HTML页面中所有的a标签,获取它们的文本内容和href属性,最终返回一个包含所有链接的数组。
四、示例说明
下面是使用上述工具集编写的两个示例:
- 获取《百年孤独》的内容概要
const url = 'http://book.douban.com/subject/6082808/';
getHtmlText(url, 'utf-8', (error, text) => {
if (error) {
console.error(error);
return;
}
const content = text.replace(/\n|\s/g, '');
const re = /<h2>《百年孤独》内容简介<\/h2>(.*?)<divclass="clear">/i; // 获取书本简介的正则表达式
const match = content.match(re);
if (!match) {
console.error('没有找到书本简介');
return;
}
const summary = match[1].replace(/<[^<>]+?>/g, '').replace(/\s+/g, '');
console.log(summary);
});
上述代码中的正则表达式是从豆瓣读书网站的HTML页面中手动整理出来的,通过正则匹配可以获取到《百年孤独》一书的内容概要。
- 获取百度搜索结果的所有链接
const query = 'Node.js';
const url = `http://www.baidu.com/s?wd=${query}`;
getHtmlLinks(url, 'utf-8', (error, links) => {
if (error) {
console.error(error);
return;
}
links.forEach(link => console.log(link.href));
});
上述代码中的query变量表示搜索的关键词,通过请求百度搜索页面并解析所有a标签,最终可以获取到所有搜索结果的链接。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:如何用Node写页面爬虫的工具集 - Python技术站