Node.js爬取妹子圖-crawler爬蟲的使用

湖工電氣發表於2018-04-04

去年10月份寫過《Node.js 2小時爬取驢媽媽8W+條旅遊資料》。之前做的是使用request 做網路請求和 cheerio做DOM解析。
後來在網上看見了crawler,昨天就把crawler把玩了了一把。感覺使用起來還可以,他的作用和上面的兩個包的作用是一樣的。
這裡寫圖片描述
這次我爬取的是妹子圖
在爬取之前,還是建議先看看crawler怎麼使用。其實它的是有還是很簡單的。這裡不再贅述,請自行查閱文件。
再則就是好好看看妹子圖這個網頁地址的規律,是不是有防刷機制(同一個IP,短期內多次訪問,自定義的概念)。這裡我找到的規律是妹子圖的首頁:http://www.meizitu.comhttp://www.meizitu.com/a/more_1.html開啟的效果是一樣的。而第2個連結地址,直接就可以顯示當前訪問的是第多少頁。
實操步驟:
1.計算總頁數

var c = new Crawler({
        maxConnections : 10,  // 最大連結數 10
        retries: 5,  // 失敗重連5次
        // This will be called for each crawled page
        callback : function (error, res, done) { // 執行下面的回撥,這個回撥不會執行
            if(error){
                console.log(error);
            }else{
                var $ = res.$;
                console.log($("title").text());
            }
            done();
        }
    });

    c.queue([{
        uri: 'http://www.meizitu.com/a/more_1.html',
        jQuery: true,
        callback: function (error, res, done) {
            if(error){
                console.log(error);
            }else{
                var $ = res.$;   // 這就可以想使用jQuery一個解析DOM了
                var total_pag = 0;
                $('#wp_page_numbers li a').each(function(index,item){
                        if ($(item).text() == '末頁') {
                            total_pag = $(item).attr('href');
                            var regexp = /[0-9]+/g;
                            total_pag = total_pag.match(regexp)[0]; // 總頁數
                        }
                })
            }
            done();
        }
    }]);

這一步的操作是先看看這個有多少頁,計算出總頁數。
這裡寫圖片描述
這裡的每一頁顯示的是一個主題,每個主題點進去才是詳情,我做的是先下載主題。
2.下載主題

function downloadContent(i,c){
    var uri = 'http://www.meizitu.com/a/more_' + i + '.html';
    c.queue([{
        uri: uri,
        jQuery: true,
        callback: function (error, res, done) {
            if(error){
                console.log(error);
            }else{
                var $ = res.$;
                var meiziSql = '';
                $('.wp-item .pic a').each(function(index,item){
                        var href = $(item).attr('href'); // 獲取路徑uri
                    var regexp = /[0-9]+/g;
                    var artice_id = href.match(regexp)[0]; // 獲取文章ID
                    var title = $(item).children('img').attr('alt');
                    title = title.replace(/<[^>]+>/g,""); // 去掉 <b></b> 標籤
                    var src = $(item).children('img').attr('src');
                    var create_time = new Date().getTime();
                    if (href == 'http://www.meizitu.com/a/3900.html') {
                        title = title.replace(/'/g,'');  // 這個的標題多了一個 單引號, mysql在插入的時候存在問題,所以這樣處理了一下
                    } 
                    var values = "'" + artice_id + "'" + ',' 
                            + "'" + title + "'" + ',' 
                            +  "'" + href + "',"  
                            + "'" + src + "'" + ',' 
                            + "'" + create_time + "'";
                    meiziSql = meiziSql + 'insert ignore into meizitu_all(artice_id,title,href,src,create_time) VALUES(' + values + ');';
                })
                pool.getConnection(function(err, connection) {
                    if(err){
                        console.log('資料庫連線失敗',i);
                    }
                    connection.query(meiziSql,function (err, results) {
                        connection.release();
                        if (err){
                            console.log(err,i);
                        }else{
                            console.log('插入成功',i);
                        }
                    })
                })
            }
            done();
        }
    }]);
}

這裡寫圖片描述
這樣就可把把每頁的每個主題下載下來了。
這裡寫圖片描述
一共2806個,哈哈,足夠看一年了,(如果你不會審美疲勞)。
看見了這裡function downloadContent(i,c),不知道大家會不會有什麼疑問?為什麼還有兩個引數,引數c好書,那麼其中的i是做什麼的呢?這裡暫且不說他是做什麼,下一篇大家就知道了。
這裡只說crawler。通過程式碼大家也看見了,crawler既可以發起網路請求也可以將DOM轉換成jQuery形式,以便解析。
這裡所說了的爬蟲,加上之前我做的,其實都發起網路請求,獲取網頁的DOM,然後解析DOM節點。下一篇是提高爬取效率的async的使用。

相關文章