网页抓取数据百度百科(利用Python/.NET语言实现一个糗事百科的爬虫)
优采云 发布时间: 2021-12-22 20:04网页抓取数据百度百科(利用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 请求。而我喜欢使用request对象的具体方法如下:
req.get({
url: 'http://www.baidu.com'
},(err, res, body) => {
if (!err && res.statusCode == 200) {
console.log(body)
}
});
但是,很多情况下,直接请求从网站获取的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(),
最后,我将总结一些比较常用的方法。
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、 在项目目录下新建Spliter.js文件,分析尴尬百科的网页代码,提取自己需要的信息,通过改变url的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);
在获取尴尬百科网页的信息时,首先在浏览器中分析源码,定位到你需要的标签,然后提取标签的文本或属性值,从而完成对网页的分析。
Splider.js 文件的入口是spliter 方法。首先根据传入的方法的索引构造尴尬百科的url,然后获取该url的网页源代码,最后将获取的源代码传递给getQBJok方法进行分析。本文仅分析各文字笑话的作者、内容、喜好。
直接运行Spliter.js文件,抓取第一页的笑话信息。然后你可以改变spliter方法的参数来抓取不同页面的信息。
在上述代码的基础上,使用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.js 中有几种方法可以实现异步控制。关于具体的方法和原则,有时间我再总结一下。