1. 程式人生 > >node.js爬蟲之下載圖片,批量下載圖片,控制下載圖片並行上限

node.js爬蟲之下載圖片,批量下載圖片,控制下載圖片並行上限

首先介紹一下爬蟲所需要的的包
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