node.js爬蟲之下載圖片,批量下載圖片,控制下載圖片並行上限
阿新 • • 發佈:2019-02-14
首先介紹一下爬蟲所需要的的包
require(“request”); –get post請求頁面
require(“cheerio”) –解析文字物件為DOM物件 也就是說將string 裝換為 js操作的 $() 這種選擇器
require(‘fs’); – 儲存檔案到本地
require(“async”) –流程控制 主要是控制抓取時間間隔
require(‘mkdirp’); –建立資料夾
require(‘iconv-lite’); GBK UTF-8 轉碼
require(‘url’) –解析url成各種物件
require(‘path’); –處理檔案路徑
接下來是抓取圖片的流程了
首先定義配置
var options = {
uri: 'http://www.xxxxxx.com/',
dir: './output/', //儲存目錄
downLimit: 2//圖片並行下載上限
}
然後主程式檢測圖片下載完事件
/**
* 開始下載(程式入口函式)
*/
function start() {
//url地址 如果是的url是規律的分頁 可以看我另外一個[爬鬥魚虎牙主播](http://blog.csdn.net/q3585914/article/details/72058261)
var opts = [
// 'htm_data/7/1705/2423174.html' ,
'htm_data/7/1705/2402955.html',
'htm_data/7/1705/2385537.html',
'htm_data/7/1705/2382263.html'
];
//序列抓取頁面,就是一個一個抓,
async.forEachSeries(opts, function(opt, callback) {
//抓當個頁面
parsePage(options.uri +opt, (err) => {callback()});
},function (err) {
if (err) {
console.log('error: %s'.error, err.message);
} else {
console.log('success: 下載完畢'.info);
}
});
}
//抓單個頁面
function parsePage(url, callback) {
request({url: url, encoding: null}, function (error, response, body) {
if (!error && response.statusCode == 200) {
//由於頁面是GBK 所以使用模組iconv來轉碼
var str = iconv.decode(body, 'gbk');
//將字串裝換為DOM
var $ = cheerio.load(str);
var links = [];
//分析圖片url,由於使用了cheerio模組所以跟頁面js一樣分析
$(".do_not_catch .do_not_catch").find("img").each(function () {
var src = $(this).attr('src');
links.push(src);
});
// 建立目錄
var title = $("title").text()
var newdir =options.dir+title.trim().replace(" - 技術討論區", "");
//建立目錄,一個頁面,一個目錄
mkdir(newdir);
//下載圖片
downImages(newdir,links,callback)
}
});
}
/**
* 建立目錄
*/
function mkdir(title) {
console.log('準備建立目錄:%s', title);
if (fs.existsSync(title)) {
console.log('目錄:%s 已經存在'.error, title);
}else {
mkdirp(title, function (err) {
console.log('title目錄:%s 建立成功'.info, title);
});
}
}
/**
* 下載圖片列表中的圖片
*/
function downImages(dir,links, callback) {
console.log('發現%d張圖片,準備開始下載...', links.length);
//eachLimits 控制下載圖片並行上限 第二個引數 options.downLimit 就是配置
async.eachLimit(links, options.downLimit,function (imgsrc,cb) {
var url = urldm.parse(imgsrc);
//獲取url最後的名字
var fileName = path.basename(url.pathname);
//去掉/
var toPath = path.join(dir, fileName);
console.log('開始下載圖片:%s,儲存到:%s', fileName, dir);
//這個地方要詳細說了
request(encodeURI(imgsrc)).on('error', function(err) {
cb();
}).pipe(fs.createWriteStream(toPath)).on('finish',()=>{
console.log('圖片下載成功:%s', imgsrc);
cb();})
}, callback);
}
下載圖片可以使用
request('http://google.com/doodle.png').pipe(fs.createWriteStream('doodle.png'))
但是如果圖片下載和儲存出錯就會匯出程式報錯終止,所以需要加一個事件來控制
就是來監聽error,他可以解決你儲存時候出錯問題 cb()就是回撥跳過
這哥可以解決批量下載圖片時候出現的異常
request(encodeURI(imgsrc)).on('error', function(err) {
cb();
}).pipe(fs.createWriteStream(toPath)).on('finish',()=>{
console.log('圖片下載成功:%s', imgsrc);
cb();})
歡迎加群一起交流哦!
315552185