【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';
然后使用http的get模块去请求目标网页
在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
cheerio是jquery核心功能的一个快速灵活而又简洁的实现,主要是为了用在服务器端需要对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添加到ddwlength += work.length})res.on('end',(work) => {var list = [] //存储提取的数据对象var data = Buffer.concat(ddw,length) //开辟缓存区存储字节码var html = iconv.decode(data,'GB2312'); //将网页的编码GB2312转成utf8var $ = 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爬取当当网数据的例子就完成啦
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
