之前寫了個小爬蟲,用來爬噹噹的圖書資訊用的,挺好玩,分享一下吧。整個爬蟲非常簡單,主要是使用request庫+cheerio解析,實現非常粗糙,今天正好理一下思路。
首先,準備工作,就是各種庫的安裝以及其他前置工作的準備,比如頁面分析。
整個流程實際上比較簡單,適合像我這樣的菜鳥觀看。
準備工作
npm install request
npm install cheerio
npm install iconv-lite複製程式碼
request是用來請求頁面的庫,也是本次爬蟲最核心的庫;cheerio是用於解析的庫,將頁面轉化成DOM來簡化資料的解析;iconv-lite是解碼庫,因為噹噹網用的不是utf8編碼,這點倒是讓我吃了不少苦頭。
分析清單
下載完需要的庫就可以開始擼了,不過擼之前需要先分析頁面結構,我列一下分析清單:
- 頁面結構:分析資料在哪些結構中
- 資料形式:圖片,文字還是數字
- 爬取深度:抓取的資料在當前頁面還是需要進入連結(比如商品列表與商品詳情,我們需要的資料在詳情頁,但我們只能通過列表頁去爬,這時候深度就是2)
- 儲存位置:資料儲存在哪:檔案or資料庫
- 編碼格式:編碼不對資料就全是亂碼了,這樣的資料要了也沒用
分析完需要分析的東西就可以接著往下了
初步使用
request({
encoding:null,
url:`http://book.dangdang.com/list/newRelease_C01.54.htm`
},function(err,response,body){
if(err){console.log(err)}
else{
//處理資料
console.log(body)
}
})複製程式碼
這裡解釋一下,encoding:null
是取消編碼,因為預設會按照utf8編碼,但頁面本身是gb2312的,所以解析了也沒用。不寫會出問題,因為以gb2312解碼的時候資料都被utf8編碼過,簡直是災難。
response
是伺服器端的響應,比如各種頭資訊啊之類的,這裡用不到它。body
是頁面主體,也就是整個html,是我們需要處理的主角。
但之前也提到了,頁面編碼是gb2312,因此在解析資料之前先要解碼。
var decodeBuffer=iconv.decode(body,"gb2312");//將body以gb2312解析轉化成buffer(unicode)
var html=decodeBuffer.toString();
var $=cheerio.load(html);複製程式碼
這時候html是原gb2312解碼後又被編碼成utf8的字串,如果列印出來就能發現,裡邊的中文不再是亂碼了。這時候就輪到cheerio登場了:cheerio提供的api和JQuery基本相同,在這裡可以直接當成JQuery,因此為了更加靠近JQuery,我們將解析後的資料儲存到$
這個變數中。
var $=cheerio.load(html);
$(".tushu").each(function(index,ele){
var bookName=$(ele).find(".name").text();
console.log(bookName);
})複製程式碼
這時候書名就被列印出來了,是不是很方便。圖片我們就用src吧,當然,如果想把圖片儲存下來也是可以的,用上fs模組就行了
var fs = require("fs");
var path=require("path");
$(".tushu").each(function(index,ele){
var src=$(ele).find(".cover img").attr("src");
var srcParse=path.parse(src);
var srcStore="img/"+srcParse.base;
request(src).pipe(fs.createWriteStream(srcStore));
})複製程式碼
完整程式碼
至此,整個爬蟲差不多了,因為噹噹把下一頁的連結寫在了a標籤裡,因此同樣可以使用選擇器這種方式去獲取href,以此得知下一頁的路徑。因此封裝一下:
var request=require("request");
var cheerio=require("cheerio");
var iconv=require("iconv-lite");
var path=require("path");
var fs=require("fs");
var main="http://book.dangdang.com";
function spider(url){
request({
encoding:null,
url:url
},function (err, res, body) {
var decodeBuffer=iconv.decode(body,"gb2312");
var result=decodeBuffer.toString();
var $=cheerio.load(result);
$(`.tushu`).each(function(index,ele){
var src=$(ele).find(".cover img").attr("src");
var srcpath=path.parse(src);
var srcStore="img/"+srcpath.base;
request(src).pipe(fs.createWriteStream(srcStore));
});
var next=$(`.fanye_bottom > span:nth-child(1) > a:last-child`).attr("href");
var nextUrl=main+next;
spider(nextUrl);
})
}複製程式碼
這時候再呼叫一下spider函式,就可以一頁一頁往下了。同時我也把詳細文章寫在了自己部落格上,防止下次寫的時候忘了怎麼用,可以點選訪問
小結
當然,這個爬蟲很簡單,基本上糊弄一下沒有任何限制的網站還行。之後要寫一個同城租房的畢設專案,準備爬58租房資訊。58對ip作了限制,因此訪問量太大會出驗證碼或者封ip,所以需要加上代理等進一步偽裝一下。代理的確非常頭疼,因為可用率非常低,還記得當初隨便找了一個網站,爬了1w多條ip,結果前幾個還能用,後面的測試一下基本不可用,最後在篩選的時候就篩選出7-8條,真的心累。後來找到了快代理,可用率還不錯,基本能達到12%左右,可以說是非常高的可用率了,畢竟免費。當然有更好的免費代理可以和我說說呀。
第一次寫文章,有什麼不對的地方歡迎看官指正。