【node】node.js实现一个简单的爬虫

前言

我们写项目的时候会需要模拟数据,这里教大家使用node去实现一个简单的爬虫,获取目标网站的数据资源。(末尾附完整代码)

思路

首先找到目标网页,爬取整个网页的html内容,查看网页源代码,找到需要爬取内容的DOM结构,根据正则或者使用jquery操作(cheerio)提取相应的内容,然后将结果写入文件。

一、准备

所需要的模块:
1、http:网络通信
2、fs:文件操作
3、cheerio:操作DOM(jquery的node版)

npm i cheerio

4、iconv-lite:解决网页编码问题

npm i iconv-lite
二、实现

首先引入前面的几个模块

const http = require('http');
const fs = require('fs');
const cheerio = require('cheerio')
const iconv = require('iconv-lite');

寻找目标网页(以当当网为例)
以关键词js搜索图书列表
在这里插入图片描述
得到目标网址

var url = 'http://search.dangdang.com/?key=js&act=input';

然后使用httpget模块去请求目标网页
data事件中数据会一节一节的下载

http.get(url,(res) => {
	res.on('data',(work) => {
		console.log(work)
	})
})

打印看一下效果,说明数据可以传输成功
在这里插入图片描述
等待数据下载完成,在end事件中输出,并将数据字节转化成我们看得懂的字符串。

http.get(url,(res) => {
	var ddw = []  //用于存储目标网页的字节码
	var length = 0  //ddw的长度
	res.on('data',(work) => {
		ddw.push(work)
		length += work.length
	})
	res.on('end',() => {	
		var data = Buffer.concat(ddw,length)   //
		var html = data.toString()   //html  网页字节码转成字符串
		console.log(html)			
	})
})

输出效果如下图,说明网页已经下载完成。但是很明显的出现了乱码,实际上是中文显示错误。
在这里插入图片描述
我们翻看网页源代码的头部,可以看到当当网的编码是GB2312,但是node只支持utf8/utf-8,所以就要用插件进行转化。
在这里插入图片描述
使用iconv-lite,修改过后的代码如下:

var data = Buffer.concat(ddw,length)   //
var html = iconv.decode(data,'GB2312').toString();
		 

打印一下html如下图,可以看到中文已经正常显示
在这里插入图片描述
接下来就是查看源代码,看我们需要提取的内容的DOM结构。如下图。查找好内容的格式之后就可以编写正则提取或者使用jquery操作。下面以jquery为例
在这里插入图片描述
不过node里面并不支持jquery,这里可以使用cheerio

cheeriojquery核心功能的一个快速灵活而又简洁的实现,主要是为了用在服务器端需要对DOM进行操作的地方

将参数html传入,即可使用jquery操作html的内容

var $ = cheerio.load(html) 

按照具体内容的结构(这里提取书名价格作者出版社时间)写相应的代码。将获得的内容以对象形式传入一个数组。

var list = []
$('.bigimg').find('li').each((index,item) => {
	var liclass = 'line'+(index+1)	
	//这里每一条数据的li标签的class名为‘line1、line2、line3’以此类推	
	var name = ''  //书名
	var price = ''  //价格
	var author = ''  //作者
	var cbname = ''   //出版社
	var time = ''      //出版时间
	name = $('.'+liclass).find('.pic').attr('title')
	price = $('.'+liclass).find('.search_now_price').text()
	author = $('.'+liclass).find('.search_book_author').find('a').eq(0).text()
	cbname = $('.'+liclass).find('.search_book_author').find('a').eq(1).text()
	time = $('.'+liclass).find('.search_book_author').find('span').eq(1).text()
	list.push({
			name:name,
			price:price,
			author:author,
			cbname:cbname,
			time:time
		})
})

打印list数组,效果如下。这样数据已经提取成功。

这里只是提取第一页,也可以添加参数提取更多页的内容,这里不再叙述。

在这里插入图片描述
下面将数据写入一个文件

fs.writeFileSync('./当当网.js',list)

打开当当网.js发现不显示内容。
在这里插入图片描述
别急,按如下方式写

fs.writeFileSync('./当当网.js',JSON.stringify(list,null,'\t'))

后面那个null是为了显示的时候换行

再次打开该文件,已经再次写入成功
在这里插入图片描述

完整代码


const http = require('http');
const fs = require('fs');
const cheerio = require('cheerio')
const iconv = require('iconv-lite');

var url = 'http://search.dangdang.com/?key=js&act=input';

http.get(url, (res) => {
	var ddw = [];  //存储网页字节码
	var length = 0  //网页字节码长度
	res.on('data',(work) => {
		ddw.push(work)    //将一节一节的字节码work添加到ddw
		length += work.length
	})

	res.on('end',(work) => {
		var list = []  //存储提取的数据对象
		var data = Buffer.concat(ddw,length)  //开辟缓存区存储字节码
		var html = iconv.decode(data,'GB2312');  //将网页的编码GB2312转成utf8
		var $ = cheerio.load(html.toString())  //引入jquery操作网页内容
		
		$('.bigimg').find('li').each((index,item) => {
			var liclass = 'line'+(index+1)  //每条数据的li标签的class名
			
			var name = ''  //书名
			var price = ''  //价格
			var author = ''  //作者
			var cbname = ''   //出版社
			var time = ''      //出版时间
			name = $('.'+liclass).find('.pic').attr('title')
			price = $('.'+liclass).find('.search_now_price').text()
			author = $('.'+liclass).find('.search_book_author').find('a').eq(0).text()
			cbname = $('.'+liclass).find('.search_book_author').find('a').eq(1).text()
			time = $('.'+liclass).find('.search_book_author').find('span').eq(1).text()
			list.push({
				name:name,
				price:price,
				author:author,
				cbname:cbname,
				time:time
			})
		})
	    // console.log(list)
		fs.writeFileSync('./当当网.js',JSON.stringify(list,null,'\t'))
	})
})


结尾

这样一个简单的node爬取当当网数据的例子就完成啦

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值