学了NodeJS已经一段时间,所以打算玩一下爬虫练一下手。
首先,我们找到一个自己喜欢的存储位置,新建一个文件夹。这里我在D盘上的test文件夹下的meizi文件夹上进行爬虫。然后在meizi文件夹中新建一个index.js和一个images文件夹。
index.js--------入口文件
images---------图片保存文件夹
结果如下图:
在上图可以看见,多了一个node_modules文件夹和vscode文件夹。在这里不用管vscode文件夹,因为不是必要的。这里的node_modules文件夹是要在cmd上进行的。
首先进入到命令行里面,然后去到你的文件夹,然后就写入如下代码:
npm init;在这个文件夹下面初始化nodejs的工程,创建完项目工程后,就应该载入两个需要用到的插件了。
npm install cheerio –save
npm install request –save
这里面多写了一个-save是因为要保存到到package。json文件上。
这里面的所有基本的环境就配好了,接着就是直接node index.js就可以有一大波美女图片了。
var request = require('request');
var cheerio = require('cheerio');
var path = require('path');
var fs = require('fs');
var requrl1 = "http://jandan.net/ooxx/page-";
var i=1;
//当前爬的网页页数,可以写很多,这里只要爬一页
requrl = requrl1 + i;
//当前的request函数,发起http请求
request(requrl,function(error,response,body){
//没错误取得网页的html代码
if(!error && response.statusCode == 200){
console.log(body);
//进入去爬数据
acquireData(body);
}
});
function acquireData(data){
//cheerio插件相当于jq的功能
var $ = cheerio.load(data);
//看页面可以知道,当前的图片有class=test,将它们当数组存进meizi变量
var meizi = $('.text img').toArray();
console.log(meizi.length);
var len = meizi.length;
for(var i=0;i<len;i++){
//观察src时发现src有问题,有部分的http没有显示,所以要自己写
var imgsrc = 'http:';
//获取html上的图片的src
var imgsrc1 = meizi[i].attribs.src;
imgsrc += imgsrc1;
console.log(imgsrc);
//获取图片的名字
var filename = parseUrlForFileName(imgsrc);
//下载图片
downloadImg(imgsrc,filename,function(){
console.log(filename+' done');
});
}
}
function parseUrlForFileName(address){
//提取出用 ‘/' 隔开的path的最后一部分,即图片名字
var filename = path.basename(address);
return filename;
}
//下载图片函数
var downloadImg = function(uri,filename,callback){
//http请求
request.head(uri,function(err,res,body){
if(err){
console.log('err:'+err);
return false;
}
console.log('res: '+res);
//水管式保存数据,防止未来得及记录数据又开始读取数据而导致数据丢失
request(uri).pipe(fs.createWriteStream('./images/'+filename)).on('close',callback);
});
}
上面的程序在运行的时候如果是要多页的话,使用for控制i变量的话,就会出现一个严重的问题。那就是有些图片会下载下来出错误了。而且程序运行一段时间后就会出现因为服务器的端口用完而导致的报错,所以还是要改为以下的代码才能够完整的爬取,不过因为端口只用一个的话速度相对较慢。
var request = require('request');
var cheerio = require('cheerio');
var path = require('path');
var fs = require('fs');
var http = require('http');
var requrl1 = "http://jandan.net/ooxx/page-";
var i=2;
function fetchPage(x){
startRequest(x);
}
fetchPage("http://jandan.net/ooxx/page-1");
function startRequest(x) {
//采用http模块向服务器发起一次get请求
http.get(x, function (res) {
//用来储存请求的网页整个html内容
var html = '';
var titles = [];
//设置编码格式
res.setEncoding('utf-8');
//监听data事件,每次取一块数据
res.on('data', function (chunk) {
html += chunk;
});
//监听end事件,如果整个网页内容的html都获取完毕,就执行回调函数
res.on('end', function () {
acquireData(html);
//下一篇文章的url
var nextLink = requrl1 + i++;
//控制爬多少篇文章
if (i <= 500) {
console.log('i: '+i);
fetchPage(nextLink);
}
});
}).on('error', function (err) {
console.log(err);
});
}
function acquireData(data){
//cheerio插件相当于jq的功能
var $ = cheerio.load(data);
//看页面可以知道,当前的图片有class=test,将它们当数组存进meizi变量
var meizi = $('.text img').toArray();
console.log(meizi.length);
var len = meizi.length;
for(var i=0;i<len;i++){
//观察src时发现src有问题,有部分的http没有显示,所以要自己写
var imgsrc = 'http:';
//获取html上的图片的src
var imgsrc1 = meizi[i].attribs.src;
imgsrc += imgsrc1;
console.log(imgsrc);
//获取图片的名字
var filename = parseUrlForFileName(imgsrc);
//下载图片
downloadImg(imgsrc,filename,function(){
console.log(filename+' done');
});
}
}
function parseUrlForFileName(address){
//提取出用 ‘/' 隔开的path的最后一部分,即图片名字
var filename = path.basename(address);
return filename;
}
//下载图片函数
var downloadImg = function(uri,filename,callback){
//http请求
request.head(uri,function(err,res,body){
if(err){
console.log('err:'+err);
return false;
}
console.log('res: '+res);
//水管式保存数据,防止未来得及记录数据又开始读取数据而导致数据丢失
request(uri).pipe(fs.createWriteStream('./images/'+filename)).on('close',callback);
});
}