邊作邊學效率更高,爬蟲是node的適用場景之一,關於爬蟲的另外一篇文章
爲了驗證「簡書上,經驗總結、資料歸集類技術文章更容易上熱榜」的猜測,能夠作一個爬蟲:爬取簡書程序員專題熱門文章前999篇,統計每篇文章的代碼塊數量(爲何是統計代碼塊數量,對於人來講,經過一篇文章的標題內容來判斷文章的類型是一件垂手可得的事,然而對於計算機來講,這倒是一件困難的事情,這已經屬於人工智能的範疇了。然而獲取文章的代碼塊數量對於計算機來講就容易得多了,能夠認爲,代碼塊爲0或者較少的文章,屬於經驗類文章,代碼塊數量較多的文章若是不是資料歸集的話,多半就屬於談源碼實現的了)javascript
ajax請求,須要使用chrome dev tools,拉到底部還能加載更多:java
//order_by=likes_count 表示按照熱門進行排序
//page是分頁參數,每頁9條,咱們能夠經過改變page=0~100來拉取900篇文章
http://www.jianshu.com/collections/16/notes?order_by=likes_count&page=2複製代碼
下一步經過這個連接拉取列表數據node
/** - 建立promise */
Seek.prototype.createPromise = function(i) {
var options = {
url: 'http://www.jianshu.com/collections/16/notes?order_by=likes_count&page=' + i,
type: 'get'
}
return new Promise(function(resolve, reject) {
options.callback = function(data, _setCookie) {
resolve(data);
}
request(options, null);
});
}複製代碼
能夠建立一個promise對象來發起request請求(request的封裝就不貼出來了,實驗證實,代碼塊太多的文章不容易上熱榜~~)jquery
起初個人作法是同時建立拉取1~100頁數據的100個promise對象,同時異步的發起100個request請求,然而這樣的作法會有幾十個請求請求失敗(興許是簡書那邊作了限制),因此,仍是耐心點,每次發起5個請求,直到100頁都請求成功git
/** * 遞歸的請求,每次併發的請求5個 */
Seek.prototype.seek = function(callback) {
var self = this;
times++;
var ot = times;
var promise = Promise.all([
self.createPromise(times),
self.createPromise(++times),
self.createPromise(++times),
self.createPromise(++times),
self.createPromise(++times)
]);
promise.then(function(result) {
console.log("seekList totals:" + times);
pages = pages.concat(result);
if (times < totalPage) {
self.seek(callback);
} else {
callback(pages);
}
});
}複製代碼
拿到全部的列表數據以後,就能夠使用cheerio庫來分析列表頁面,抓取文章詳情連接(在這一步以前你一樣須要使用chrome dev tools工具分析頁面結構)程序員
/** * 使用cheerio載入列表頁面 */
Analyse.prototype.load = function(data, i) {
return new Promise(function(resolve, reject) {
var $ = cheerio.load(data);
var pages = [];
var els = $('.article-list li');
if(els.length === 0) {
console.warn('load error page:' + i );
resolve([]);
}
els.each(function(index) {
if ($(this).attr('class') === 'have-img') {
pages.push($(this).children('a').attr('href'));
} else {
pages.push($(this).children('div').children('.title').children('a').attr('href'));
}
if(index === els.length - 1) {
resolve(pages);
}
});
});
}複製代碼
<code></code>
標籤,統計此標籤出現的數量就能夠了
/** * 建立promise */
Seek.prototype.createPromise = function(url) {
var options = {
url: 'http://www.jianshu.com' + url,
type: 'get'
}
return new Promise(function(resolve, reject) {
options.callback = function(data, _setCookie) {
var $ = cheerio.load(data);
//頁面標題
var title = $('h1.title').text();
//代碼塊數量
var codes = $('code').length;
if(codes === 0) {//代碼塊爲0的總數
zeroCount++;
} else if(codes <= 10) {//代碼塊爲<=10的總數
oneToTen++;
} else if(codes <= 20) {//代碼塊<=20的總數
elToTwo++;
} else {//代碼塊>20的總數
beyondTwo++;
}
resolve({
title: title,
codes: codes
});
}
request(options, null);
});
}複製代碼
下一篇文章講 Node 爬蟲進階,敬請關注github
補充說明:代碼大半年前些的,簡書的接口和頁面結構已經作了改版,可能抓取不到想要的結果,若是感興趣,能夠按照思路和步驟改造如今的代碼,本身動手豐衣足食ajax