NodeJS制作爬蟲全過程(續(xù))
書接上回,我們需要修改程序以達(dá)到連續(xù)抓取40個頁面的內(nèi)容。也就是說我們需要輸出每篇文章的標(biāo)題、鏈接、第一條評論、評論用戶和論壇積分。
如圖所示,$('.reply_author').eq(0).text().trim();得到的值即為正確的第一條評論的用戶。
{<1>}

在eventproxy獲取評論及用戶名內(nèi)容后,我們需要通過用戶名跳到用戶界面繼續(xù)抓取該用戶積分
var $ = cheerio.load(topicHtml);
//此URL為下一步抓取目標(biāo)URL
var user + $('.reply_author').eq(0).attr('href');
userHref = url.resolve(tUrl, userHref);
var title = $('.topic_full_title').text().trim().replace(/\n/g,"");;
var href = topicUrl;
var comment1 = $('.reply_content').eq(0).text().trim();
var author1 = $('.reply_author').eq(0).text().trim();
//傳遞參數(shù)到下一次并發(fā)抓取
ep.emit('user_html', [userHref, title, href, comment1, author1]);
在eventproxy這一次中,我們要找到score是放在哪里(class="big")。
{<2>}

找到classname就好辦了,我們先試著把結(jié)果輸出一下
var outcome = superagent.get(userUrl)
.end(function (err, res) {
if (err) {
return console.error(err);
}
var $ = cheerio.load(res.text);
var score = $('.big').text().trim();
console.log(user[1]);
console.log(user[2]);
console.log(user[3]);
console.log(user[4]);
console.log($('.big').text().trim());
return ({
title: user[1],
href: user[2],
comment1: user[3],
author1: user[4],
score1: score
});
});
});
運行程序,這段代碼得到的結(jié)果。
{<3>}

但是問題來了,我們在.end()的回調(diào)函數(shù)中能正確輸出結(jié)果,但是不能正確的輸出outcome。仔細(xì)一看,需要輸出的outcome是一個Request對象。這是因為粗心犯的錯的,.end()函數(shù)并不會傳遞返回值給Request對象,需要將結(jié)果返回到上一層(users)。
//find userDetails
ep.after('user_html', topicUrls.length, function(users){
users = users.map(function(user){
var userUrl = user[0];
var score;
superagent.get(userUrl)
.end(function (err, res) {
if (err) {
return console.error(err);
}
//console.log(res.text);
var $ = cheerio.load(res.text);
score = $('.big').text().trim();
});
return ({
title: user[1],
href: user[2],
comment1: user[3],
author1: user[4],
score1: score
});
});
把users好好地輸出發(fā)現(xiàn)除了score1其他是正確值。仔細(xì)調(diào)試發(fā)現(xiàn),程序是先進(jìn)行了console.log(),然后再進(jìn)行.map()。更準(zhǔn)確地說,在.map()函數(shù)內(nèi),.get()的回調(diào)函數(shù)并沒有執(zhí)行完賦值score,return 返回值就進(jìn)行了。這就是回調(diào)函數(shù)的異步,而外層的同步操作是不會等待回調(diào)函數(shù)做完操作的。
{<4>}

我的做法就是eventproxy再emit一層消息,伴隨著消息把需要的數(shù)據(jù)一起傳遞給接收消息操作.after(),只有當(dāng)消息全部接收完畢,再打印出傳遞的參數(shù)(結(jié)果)。
score = $('.big')text().trim();
//新添加
ep.emit('got_score', [user[1], user[2], user[3], user[4], score]);
.....
ep.after('got_score', 10, function(users){
console.log(users);
});
{<6>}

這個問題解決了,但score1的數(shù)值好像太大了點吧。再一看,原來class='big'有兩個,用戶的話題收藏也是屬于這個class。我們得通過cheerio的.slice( start, [end] )來切取第一個元素,即將score 修改為 score = $('.big').slice(0).eq(0).text().trim();。正確結(jié)果如圖。
{<7>}

相關(guān)文章
nodejs中art-template模板語法的引入及沖突解決方案
本篇文章主要介紹了nodejs中art-template模板語法的引入及沖突解決方案,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-11-11
基于Node-red的在線評語系統(tǒng)(可視化編程,公網(wǎng)訪問)
Node-Red是IBM公司開發(fā)的一個可視化的編程工具,在網(wǎng)頁內(nèi)編程,主要是拖拽控件,代碼量很小,這篇文章主要介紹了基于Node-red的在線評語系統(tǒng)(可視化編程,公網(wǎng)訪問),需要的朋友可以參考下2022-01-01
npm?install安裝報錯:gyp?info?it?worked?if?it?ends?with?
今天新啟動一個項目,在 npm install 安裝依賴項時出現(xiàn)報錯,所以下面這篇文章主要給大家介紹了關(guān)于npm?install安裝報錯:gyp?info?it?worked?if?it?ends?with?ok的解決方法,需要的朋友可以參考下2022-07-07
Node.js的MongoDB驅(qū)動Mongoose基本使用教程
這篇文章主要介紹了Node.js的MongoDB驅(qū)動Mongoose的基本使用教程,前端js+后端Node.js+數(shù)據(jù)庫MongoDB是當(dāng)下流行的JavaScript全棧開發(fā)方案,需要的朋友可以參考下2016-03-03
從零開始學(xué)習(xí)Node.js系列教程之設(shè)置HTTP頭的方法示例
這篇文章主要介紹了Node.js設(shè)置HTTP頭的方法,詳細(xì)分析了常見HTTP頭的功能、原理及相關(guān)設(shè)置操作技巧,需要的朋友可以參考下2017-04-04

