nodejs抓取动态网页(利用Python/.NET语言实现一个糗事百科的爬虫)

优采云 发布时间: 2022-04-03 13:14

  nodejs抓取动态网页(利用Python/.NET语言实现一个糗事百科的爬虫)

  1.前言分析

  通常爬虫都是用 Python/.NET 语言实现的,但现在作为前端开发者,自然需要精通 NodeJS。下面我们用NodeJS语言来实现一个尴尬事百科的爬虫。此外,本文中使用的一些代码是 es6 语法。

  实现爬虫所需的依赖库如下。

  request:使用get或post获取网页源代码。Cheerio:解析网页源代码,获取需要的数据。

  本文首先介绍爬虫所需的依赖库及其使用方法,然后利用这些依赖库来实现一个网络爬虫,用于网络爬虫百科。

  2. 请求库

  request 是一个轻量级的 http 库,非常强大且易于使用。可以用来实现Http请求,支持HTTP认证、自定义请求头等。下面介绍请求库中的部分功能。

  安装请求模块如下:

  

npm install request

  安装好请求后,就可以使用了。接下来,使用请求请求百度的网页。

  

const req = require('request');

req('http://www.baidu.com', (error, response, body) => {

if (!error && response.statusCode == 200) {

console.log(body)

}

})

  未设置 options 参数时,请求方法默认为 get 请求。而且我喜欢使用请求对象的具体方法,使用如下:

  

req.get({

url: 'http://www.baidu.com'

},(err, res, body) => {

if (!err && res.statusCode == 200) {

console.log(body)

}

});

  但是在很多情况下,直接请求一个URL获取的html源代码,往往并不能得到我们需要的信息。一般来说,需要考虑请求头和网页编码。

  网页请求头的编码

  下面介绍如何在请求时添加网页请求头并设置正确的编码。

  

req.get({

url : url,

headers: {

"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36",

"Host" : "www.zhihu.com",

"Upgrade-Insecure-Requests" : "1"

},

encoding : 'utf-8'

}, (err, res, body)=>{

if(!err)

console.log(body);

})

  设置options参数,添加headers属性设置请求头;添加 encoding 属性来设置网页的编码。需要注意的是,如果encoding:null,则get请求得到的内容是一个Buffer对象,即body是一个Buffer对象。

  上述功能足以满足以下需求。

  3.cheerio 库

  Cheerio 是一个服务器端的 Jquery,因其轻量、快速和易于学习的特性而受到开发人员的喜爱。掌握了 Jquery 的基础知识之后,学习 Cheerio 库就很容易了。可以快速定位网页中的元素,其规则与jquery定位元素的方法相同;它还可以修改html中元素的内容,并以非常方便的形式获取它们的数据。下面主要介绍cheerio快速定位网页中的元素并获取其内容。

  首先安装cheerio库

  

npm install cheerio

  下面给出一段代码,然后代码说明cheerio库的用法。分析博客园的首页,然后提取每个页面中文章的标题。

  首先,分析博客园的首页。如下所示:

  

  分析完html源码,首先通过.post_item获取所有title,然后分析每个.post_item,并使用a.titlelnk匹配每个title的a标签。代码在下面实现。

  

const req = require('request');

const cheerio = require('cheerio');

req.get({

url: 'https://www.cnblogs.com/'

}, (err, res, body) => {

if (!err && res.statusCode == 200) {

let cnblogHtmlStr = body;

let $ = cheerio.load(cnblogHtmlStr);

$('.post_item').each((index, ele) => {

let title = $(ele).find('a.titlelnk');

let titleText = title.text();

let titletUrl = title.attr('href');

console.log(titleText, titletUrl);

});

}

});

  当然,cheerio 库也支持链式调用,上面的代码也可以改写为:

  

let cnblogHtmlStr = body;

let $ = cheerio.load(cnblogHtmlStr);

let titles = $('.post_item').find('a.titlelnk');

titles.each((index, ele) => {

let titleText = $(ele).text();

let titletUrl = $(ele).attr('href');

console.log(titleText, titletUrl);

  上面的代码很简单,不用文字重复了。下面总结了一些我认为比较重要的点。

  使用find()方法得到的节点集A,如果将A集中的元素作为根节点定位其子节点并获取子元素的内容和属性,则需要执行$(A [i ]) 包装器,如上面的 $(ele) 。上面代码中使用$(ele),其实也可以使用$(this),但是由于我使用的是es6箭头函数,所以我在每个方法中更改了回调函数的this指针,所以我使用了$(ele ); Cheerio 库还支持链式调用,例如上面的 $('.post_item').find('a.titlelnk')。需要注意的是,cheerio 对象 A 调用了 find() 方法。如果 A 是一个集合,那么 A 集合中的每个子元素都会调用 find() 方法并放回一个结果组合。如果 A 调用 text(),那么 A' 中的每个子元素

  最后,我总结了一些比较常用的方法。

  first() last() children([selector]):这个方法和find类似,只是这个方法只搜索子节点,而find搜索整个后代节点。

  4. 尴尬的百科全书爬虫

  通过上面对request和cheerio类库的介绍,下面两个类库是用来爬取尴尬事百科的页面的。

  1、在项目目录下新建httpHelper.js文件,通过url获取尴尬百科的源码。代码如下:

  

//爬虫

const req = require('request');

function getHtml(url){

return new Promise((resolve, reject) => {

req.get({

url : url,

headers: {

"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",

"Referer" : "https://www.qiushibaike.com/"

},

encoding : 'utf-8'

}, (err, res, body)=>{

if(err) reject(err);

else resolve(body);

})

});

}

exports.getHtml = getHtml;

  2、在项目目录下,新建一个Splitter.js文件,分析糗事百科的网页代码,提取你需要的信息,通过改变id建立爬取不同页面数据的逻辑的网址。

  

const cheerio = require('cheerio');

const httpHelper = require('./httpHelper');

function getQBJok(htmlStr){

let $ = cheerio.load(htmlStr);

let jokList = $('#content-left').children('div');

let rst = [];

jokList.each((i, item)=>{

let node = $(item);

let titleNode = node.find('h2');

let title = titleNode ? titleNode.text().trim() : '匿名用户';

let content = node.find('.content span').text().trim();

let likeNumber = node.find('i[class=number]').text().trim();

rst.push({

title : title,

content : content,

likeNumber : likeNumber

});

});

return rst;

}

async function splider(index = 1){

let url = `https://www.qiushibaike.com/8hr/page/${index}/`;

let htmlStr = await httpHelper.getHtml(url);

let rst = getQBJok(htmlStr);

return rst;

}

splider(1);

  在获取尴尬百科网页的信息时,首先在浏览器中分析源码,定位到需要的标签,然后提取标签的文字或属性值,从而完成网页的解析。

  Spliter.js 文件的入口是 spliter 方法。首先根据传入方法的index索引,构造出糗大百科的url,然后得到url的网页源码,最后将得到的源码传入getQBJok方法进行分析。本文只分析每一个文字笑话的作者、内容和点赞数。

  直接运行Slider.js文件,爬取第一页的笑话信息。然后可以改变slider方法的参数来爬取不同页面的信息。

  在上面已有代码的基础上,使用koa和vue2.0搭建一个浏览文本的页面,效果如下:

  

  源代码已经上传到github。下载链接: ;

  项目的运行依赖节点v7.6.0或以上。首先从 Github 克隆整个项目。

  

git clone https://github.com/StartAction/SpliderQB.git

  克隆后,进入项目目录并运行以下命令。

  

node app.js

  5. 总结

  通过实现一个完整的爬虫功能,可以加深对Node的理解,部分实现的语言使用es6语法,这样可以加快es6语法的学习进度。另外,在这个实现中,遇到了Node的异步控制知识。本文使用了 async 和 await 关键字,这也是我最喜欢的。但是,在 Node 中,有几种方法可以实现异步控制。关于具体的方法和原则,有时间再总结。

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线