原文地址:NodeJS網絡爬蟲
網上有不少其餘語言平臺版本的網絡爬蟲,好比Python,Java。那怎麼能少得了咱們無所不能的javascript呢😂?這個和以前給產品狗開發的批量圖片下載配置工具,原理很類似,核心就是調用Node的http模塊。javascript
網絡爬蟲基本就由以下部分組成:html
程序入口能夠用web頁面實現,還能夠在網頁上顯示抓取的數據和分析結果;可是這個我只想把精力花在覈心模塊,頁面和樣式不想花太多精力去弄。因此呢,我就開發個node的命令行工具,這個比較成熟的就是commander了。java
請求模塊方面,我只想抓取百度的頁面,還有知乎的頁面,它們的請求都是https協議的,好在Node的https和http模塊功能幾乎是同樣的,這裏須要作的就是熟悉它的api就行了,也是easy。node
數據解釋模塊,由於抓取出來的頁面內容是字符串,因此能夠用正則表達式去匹配,可是這樣太麻煩了。有沒有更好的方式?抓取回來可都是html內容,用jQuery以操做dom的方式去解析數據不是很方便嘛,剛好有個服務端的jquery庫cheerio。jquery
頁面抓取完,數據也分析出來了,那就很是簡單了,你能夠選擇存入數據庫或者寫入文件保存。接下來就開始實現上面的功能模塊。git
開始配置和初始化commander,具體的使用方式參考官方的文檔:https://www.npmjs.com/package/commander,這裏再也不詳細解釋用法了,下面開始配置commander。
首先要在package.json添加以下節點,表示註冊了一個命令行 "grab"。github
"bin": { "grab": "bin/grab.js" },
接着在grab.js開始定義commander,最後咱們就能夠這樣執行命令行:"grab baidu <內容> ",固然能夠用bd簡寫代替baidu,知乎的定義和百度是同樣,這裏再也不重複介紹了。 web
program // .allowUnknownOption()//不報錯誤 .version('0.0.1') .usage('這是個人網絡爬蟲程序😎' +'\n grap [option]' +'\n bd baidu: baidu search' +'\n zh zhihu: zhihu search'); program .command('baidu <cmd>') .alias('bd') .description('baidu search baidu') .option("-t, --tieba", "baidu tieba") .action(function(cmd, options){ console.log('baidu search "%s":', cmd); request.baiduSearch(cmd); }).on('--help', function() { console.log(' Examples:'); console.log(); console.log(' grab bd <cmd>'); console.log(' grab baidu <cmd>'); console.log(); }); program.parse(process.argv);
https模塊發起請求主要有兩種方式,這裏稍微封裝了下:正則表達式
function get(url,callback) { return https.get(url,function(response) { var body = ''; response.on('data', function(data) { body += data; }); response.on('end', function() { callback(body); }); }); }
function request(options,callback){ // var postData = qs.stringify({}); var body, req = https.request(options, (res) => { console.log('STATUS: ' + res.statusCode); // console.log('HEADERS: ' + JSON.stringify(res.headers)); res.setEncoding('utf8'); res.on('data', function (chunk) { body+=chunk; }); res.on('end',function(){ callback(body) }); }); req.on('error', function(e) { console.log('problem with request: ' + e.message); }); // write data to request body // req.write(postData); req.end(); } function baiduRequset(pageNo,pageSize,keyword){ var path='/s?'+qs.stringify({ ie:'utf-8', f:8, rsv_bp:1, tn:'baidu', rn:pageSize, pn:pageNo*pageSize, wd:keyword }), options = { hostname: 'www.baidu.com', port: 443, path: path, method: 'GET', headers: { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36' } }; request(options,function(body){ saveFile(pageNo,keyword,body); showBaiduResult(pageNo,body); }); }
抓取數據以後,咱們須要作的就是調用cheerio,以jquery獲取dom內容的方式獲取結果,並顯示出來,固然也能夠保存文件或數據庫。數據庫
/** * 顯示結果 * @param {[type]} pageNo [description] * @param {[type]} body [description] * @return {[type]} [description] */ function showBaiduResult(pageNo,body){ var title,summary,link, reg=/<[^<>]+>/g, $ = cheerio.load(body,{decodeEntities: false}); $('#content_left .result').each(function(i,item){ var $a = $(item).find('h3 a'); title = $a.html(); link = $a.attr('href'); summary=$(item).find('.c-abstract').html(); if(title){ console.log(`第${pageNo+1}頁 第${i+1}條`); console.log(`link: ${link}`.green); // console.log(`title: ${title}`); console.log('title: '); ouputColor(title); if(summary){ // console.log(`summary: ${summary}`); console.log('summary: '); ouputColor(summary); } } console.log('------------------------------'); console.log(''); }); } // 知乎 exports.zhihuSearch=function(keyword,cb){ get('https://www.zhihu.com/search?type=content&q='+keyword,function(content){ var title,summary; var $ = cheerio.load(content,{decodeEntities: false}); saveFile(0,keyword,content); $('.list .item').each(function(i,item){ title=$(item).find('.js-title-link').html(); summary=$(item).find('.summary').html(); if(title){ // title=(''+title).replace(/<[^<>]+>/g,''); // summary=(''+summary).replace(/<.+>/g,''); console.log('title: '); ouputColor(title); if(summary){ console.log('summary: '); ouputColor(summary); } } console.log('------------------------------'); console.log(''); }); }); };
功能完成後,先試驗一下抓取知乎的內容
grab zh webgl
抓取到的html文件保存在download文件夾,同時在命令行顯示抓取結果。
若是要執行百度的爬蟲,運行以下命令行便可
grab bd webgl
這裏完成的是最基本的爬蟲功能,代碼請看net_grab