node.js爬虫初探
我们经常会听说爬虫这个词语,但是却从来没有见过这个'虫子',在我们日常生活中,每天使用的百度,谷歌,搜狗,360等搜索引擎的背后,都是无数的爬虫在支持,相信很多人都听过SEO,其实,SEO就是一门如何让爬虫更快更好的爬取到你的网站的技术,当然,如果你有钱,完全可以搞个竞价排名!
其实很多语言都能写爬虫,最著名的应该是Python,它是一门强大的语言,建议有精力的人学一学,以后大数据,深度学习肯定是大方向。当然,除了Python还有很多语言能写爬虫,比如今天我们要讲的Node.js。
简单的介绍一下Node.js,它可以在服务端运行js,做过前端开发的程序员肯定很熟悉,js是一门弱语言,但现在发展很迅速,茁长成长,在Nodejs出现以后,使得js不光能写前端的动态效果,交互效果,还能写web服务器,我们甚至能用Nodejs去打包桌面端程序,从此,前端工程师的触角向后延伸了一大块。
对于前端工程师来说有时候可能想爬取点简单的页面,那么Nodejs将是我们的好帮手,当然了,闲来无事的时候,你也可以爬取一点福利站之类的,你懂得:)
开发环境&工具
Nodejs
VS Code
Nodejs环境搭建
下载地址:https://nodejs.org/en/download/
这个是node中文网http://nodejs.cn/download/
Windows和Mac直接下载安装包,双击打开安装就好了。
下面重点来说一下linux系统下的安装,主要原因是目前大多数服务器环境是Linux,如果我们将来将node的程序部署的服务器上,那这是很有用的。
Linux参照这个去安装,https://nodejs.org/en/download/package-manager/。这个网址有时候会上不了,我在这贴出几个常用的服务器系统的安装方式。
安装完成后后,可以执行node -v和npm -v确认是否安装成功。
Debian and Ubuntu
curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -sudo apt-get install -y nodejs
RHEL, CentOS or Fedora
curl --silent --location https://rpm.nodesource.com/setup_8.x | sudo bash -sudo yum -y install nodejs
爬虫简介
话不多说,直奔主题,下面来讲解一下爬虫是啥。
说了半天,爬虫是什么呢?其实爬虫就是你,说的具体点,当你坐在电脑前面打开这篇博客,你就充当了一个爬虫的角色,那我们来分解一下你打开这篇博客的行为:
输入固定的网址---->点击回车---->看到这篇博文
"爬虫就是模拟人类打开网址,浏览内容的过程"。我们来分析一下整个过程,首先,你输入了网址,浏览器发起请求,服务器返回数据,浏览器渲染成你看到的页面(这个过程其实很复杂,不做过多介绍)。
从这里就可以看出,我们大致可将爬虫分为两个部分:
请求---->解析&数据处理
其实不然,一个完整的爬虫还需要有保存数据的能力,即
请求---->解析&处理数据---->保存处理好的数据
其实还能向下再去细分
请求---->解析&处理数据---->数据去重---->保存数据
今天我们以保存处理好的数据为例,让大家对爬虫有个初步的了解。
Node模块
对于爬虫,在node中我们可以使用这些模块去完成操作:
请求 request模块
解析&数据处理 cheerio模块
保存数据 fs模块
从0到1,开始代码
首先说一下,今天我们爬取的是花瓣美素网址http://www.meisupic.com/。里面有大量的图片供我们做设计使用.当我们拿到想要爬取的网址时,首先要分析这个网站的url。
http://www.meisupic.com/ 这个网址相当与主站地址,下面的为分页地址
http://www.meisupic.com/topic.php?topic_id=5
http://www.meisupic.com/topic.php?topic_id=20
http://www.meisupic.com/topic.php?topic_id=1
打开美素网的页面,F12查看,我们会发现其实有多种方法爬取这个网站。
第一种:我们可以看到其实每个url有大部分是相同的,只有结尾的id是不同的,那也就是说,我们只需要改变结尾的id数就能获取全部的url链接
第二种:我们不难发现,其实在这个a标签里是包含有我们链接的后半部分的,我们也可以在这个主站页面将所有的子站页面链接全部爬取出来.
下面列举了第二种方式的代码:
代码说明:
1. 在桌面上简历一个文件夹huaban // 建议英文名,中英混合会报错
2. cd huaban // cd到这个文件夹 这个应该都会!
3. npm init // 初始化项目,如果不想更改,依次回车即可
4. touch app.js // 创建一个app.js文件,这里可以手动新建,名字叫什么都行
5. mkdir data // 新建data文件夹,用来存储csv文件,如果不新建,后期会报错
5. npm install request --save // 安装request模块
6. npm install cheerio --save // 安装cheerio模块
7. fs模块是node自带的不需要安装
8. 将文件夹在vscode里面打开,开始编写代码
以下是正式代码:
const request = require('request');
const cheerio = require('cheerio');
const fs = require('fs');
// 上面三行代码是导入我们所需的三个模块
// 主站地址
let Url = 'http://www.meisupic.com/topic.php'
// request 负责请求
request({url : Url}, function (err, res, body) {
if (err) {
console.log(err)
} else {
/*
cheerio模块负责html的解析,有兴趣的可以直接在上面打印body,这里只需要把 返回的body load进去就可以进行解析了. cheerio的用法很简单,和JQuery一样,使用时只需要使用jq的语法就可以解析html了
*/
let $ = cheerio.load(body)
let href = $('.album_page .glide .slide dl a')
/*
简单的使用方法是 $('class名称'),只需要定位到网页中你需要的元素即可 上面的代码是将dl下所有的a标签全部选出来,放到一个叫href的数组里
*/
for(let i = 0; i<href.length;i++){ //这里是对href这个数组做简单的循环简历
let picUrl = href[1].attribs.href //这里是选出a标签中的href属性
let reUrl ='http://www.meisupic.com/' +picUrl //你可以在这里将picUrl打印出来,它并不是完整的url,所以我们要做拼接
/*
此处做了简单的header伪装,但header伪装还有很多参数我没有写上,比如说有些网址是有防盗链的,那我们就要伪造一个referer来破解防盗链
*/
request({
url:reUrl,
method: 'GET',
headers: {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36'}
}, function (err, response, body) {
let $ = cheerio.load(body)
let pichref = $('.imgList .imgItem a img')
let picname = $('.ui_cover dl')
for(let j=0;j<pichref.length;j++){
let downpichref = pichref[j].attribs['data-original']
let downpicname = picname[j].attribs.title
save(downpicname, downpichref)
/* 以下代码是调用下载程序的,不建议调用,会给网站造成很多流量浪费.
downloadImg(downpichref, downpicname, function () {
console.log(downpicname + 'upload 完成'); });
*/
}
})
}
} })
/*
下面的代码是使用fs去保存文本,我并没有真正的去下载这些图片, 考虑到版权以及下载图片会增加花瓣网站的流量, 我只是简单的将链接保存在了一个csv文件里 还可以使用mongoose链接上mongoDB,存数据库里. 那如果我们要下载要怎么写呢?可以用pipe通道,或者是使用专用的下载模块去下载, 毕竟node的模块这么多
*/
let k = 0function save(x, y) {
let line;
name = x;
src = y;
line = `${name.replace(/\n/g, '')},${src}`;
fs.appendFile('./data/url.csv', `${line}\n`, 'utf8', (err) => {
if (err) {
console.log(err)
} else {
console.log('已成功爬取'+ k + '条')
k = k + 1
} }); }
/*
此处为保存url的代码,只需要在上面的函数中调用就可以了
*/
function downloadImg(url, filename, callback) {
var stream = fs.createWriteStream('./images/' + filename);
request({url:url}).on('error',function(){
console.log('done no');
}).pipe(stream).on('close', callback);
}
本文参考文献如下:
讲解request的文章: http://blog.csdn.net/sbt0198/article/details/66479510
cheerio中文api: https://cnodejs.org/topic/5203a71844e76d216a727d2e
讲解fs的文章: http://www.jianshu.com/p/5683c8a93511
- 点赞
- 收藏
- 关注作者
评论(0)