nodejs 爬蟲相關模塊小整合

AnyaUJVI 8年前發布 | 13K 次閱讀 Node.js Node.js 開發

爬蟲關鍵步驟都圍繞在于 請求 、 獲取數據 、 處理數據 ,當然還有應對一些反爬蟲的策略,比如偽造headers,ip代理等等,下文就主要圍繞nodejs我常用的模塊和經驗談起

請求和獲取數據模塊

superagent

名字就叫做超級代理,是一個非常實用的http請求模塊,常用于 get 、 post 等請求,對于nodejs爬蟲我主要就用它來實現請求操作,還有一些表單post操作,模擬ajax請求等,z支持鏈式調用

superagent.post(url)
    .set(headers) //設置請求頭
    .set('Cookie', cookie) // 設置cookie
    .type('form')
    .send({
        //表單數據
    })
    .end(function(err, res) {
        //數據與錯誤處理
})

中文文檔: https://cnodejs.org/topic/5378720ed6e2d16149fa16bd

superagent-charset

這個是上面那個模塊的拓展,因為 superagent 只支持 UTF-8 ,用了這個庫可以指定編碼,當你用 superagent 爬出亂碼時可以使用它

superagent.get(url)
    .set(headers) 
    .charset('gbk') //指定編碼
    .end(function(err, res) {
        if (err) {
            return console.err(err);
        }
    })

superagent-retry

當你遇到以下錯誤的時候,可以使用它,之前我用了它確實錯誤問題就解決了

  • ECONNRESET
  • ECONNREFUSED
  • ETIMEDOUT
  • EADDRINFO
  • ESOCKETTIMEDOUT
  • superagent client timeouts
  • bad gateway errors (502, 503, 504 statuses)
  • Internal Server Error (500 status)
var superagent = require('superagent');
require('./superagent-retry')(superagent);
superagent.get(url)
    .set(headers_visit)
    .retry(2) //在響應前請求兩次
    .end(function(err, res) {
        if (err) {
            return console.err(err);
        }
     })

處理數據模塊

cheerio

這是一個非常好用的處理模塊,是jQuery的子集,可以使用大量jQuery的語法來獲取你爬蟲請求到的數據,用正則真是太不友好~

superagent.get(url)
    .set(headers)
    .end(function(err, res) {
        if (err) {
            return console.err(err);
        }
        $ = cheerio.load(res.text);
        // $(".XXX")選中class
        // $("#XXX")選中id
        // ...
        })

中文文檔: https://cnodejs.org/topic/5203a71844e76d216a727d2e

fs

它雖然是一個模塊,但并不需要從npm下載(npm里的那個就一句話 console.log("I'm fs modules"); ),是nodejs自帶的文件系統模塊,直接引入即可,提供了nodejs本地讀寫的能力,可以寫入讀取本地文件,我們爬蟲如果不需要寫入數據庫,寫入本地的話,就必須得用到它了

var fs = require('fs');
// 讀取文件
fs.readFile('input.txt', function (err, data) {
  if (err) {
     return console.error(err);
  }
});
// 寫入文件
fs.writeFile('input.txt', 'XXX',  function(err) {
   if (err) {
       return console.error(err);
   }
});

中文教程: http://www.runoob.com/nodejs/nodejs-fs.html

excel相關

最近爬的數據需要爬入excel,然而fs模塊并不能直接寫入xlsx,就得用別的途徑

node-xlsx

這個模塊挺簡單上手的,我只試過導出excel,也可以讀取,覺得挺方便,具體其他可以直接看docs

var xlsx = require('node-xlsx');
var fs = require('fs');

var data = [
    [1, 2, 3],
    [true, false, null, 'sheetjs'],
    ['foo', 'bar', new Date('2014-02-19T14:30Z'), '0.3'],
    ['baz', null, 'qux']
];

var buffer = xlsx.build([{
    name: 'mySheet',
    data: data
}]);

fs.writeFile('test.xlsx', buffer, {
        'flag': 'w+'
    }, function(err) {
        if (err) {
            return console.error(err);
        }
        console.log("寫入成功");
    });

tips:不過因為我爬取大量數據,如果一味放數組里也會讓程序崩潰,但是我開啟 a+ 這個fs的追加模式,發現寫入有點問題,所以我最近采用了逗號分割csv的方式

csv

.csv后綴文件可以以純文本存儲表格數據,然后我直接用 fs 寫入,用 , 來分割列,用 \n 來分割行就解決問題了,這個簡單快捷

異步處理模塊

這個我沒去調研各個模塊,,就只介紹我用過的

對于異步這在node爬蟲中是必須去處理的,因為fs寫入文件,superagent請求這些都是異步的,我們可以用 promise 來解決,當然es6出現了 generator 生成器解決回調,還有es7的 async/await 的異步解決方案,這里就暫且不說這些了,我就只介紹下我使用的 async 模塊

async

這是一個異步流程控制模塊,還可以在爬蟲時控制并發數目,通常來說我們爬取一堆url有規律的數據,我通常構造一個數組然后使用它來解決異步

// 我這里對一個有規律的url+urlArr[i]進行爬取
for (var i = 1; i <= 900000; i++) {
    urlArr.push(i);
}
// 這里是分6批執行,每一批并行,批之間按順序
async.eachLimit(urlArr, 6, function(item, callback) {
    spider(item, callback);//爬蟲函數
    // 用callback(null)代表完成
    // 用callback('err')代表錯誤
}, function(err) {
    if (err) {
        return console.log(err);
    }
    console.log("結束");
});

這個模塊就可以解決我的異步問題了,更多用法看這位作者寫的,挺詳細的, https://github.com/alsotang/async_demo

其他模塊

這些模塊就有些針對爬蟲特定需求的

node-tesseract

這是驗證碼識別相關的

node-schedule

當我們的爬蟲需要定時爬取的時候,它就可以發揮巨大作用啦

  • node.js中使用node-schedule實現定時任務實例

node-ssh2sync

之前我爬取教務系統,因為只能校園網訪問,所以我就只能本地爬取上傳服務器,這個不是npm下載的模塊,直接從github下載,作為我簡單的上傳需求,它還是挺好用的

var ssh2sync = require('ssh2sync');

var root_local = ... ; // Grab these from command line arguments?
var root_remote = ...;
var force = true;

ssh2sync.upload(root_local, root_remote, force, {

    //    debug: console.log,
    host: ... remote host name ...,
    port: 22,
    username: ... user name ...,
    privateKey: require('fs').readFileSync('/path/to/users/.ssh/id_dsa')
    // OR password: ... the password ..
});

 

 

來自:http://bupt-hjm.github.io/2016/10/31/nodejs-spider-experience/

 

 本文由用戶 AnyaUJVI 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!