nodejs 爬蟲相關模塊小整合
爬蟲關鍵步驟都圍繞在于 請求 、 獲取數據 、 處理數據 ,當然還有應對一些反爬蟲的策略,比如偽造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
這是驗證碼識別相關的
- 可以看我的文章 https://bupt-hjm.github.io/2016/05/29/buptclass/
- 還有這位前輩寫的 http://think2011.net/2016/01/31/node-ocr/
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/