NodeJS制作爬蟲全過(guò)程(續(xù))
書接上回,我們需要修改程序以達(dá)到連續(xù)抓取40個(gè)頁(yè)面的內(nèi)容。也就是說(shuō)我們需要輸出每篇文章的標(biāo)題、鏈接、第一條評(píng)論、評(píng)論用戶和論壇積分。
如圖所示,$('.reply_author').eq(0).text().trim();
得到的值即為正確的第一條評(píng)論的用戶。
{<1>}
在eventproxy獲取評(píng)論及用戶名內(nèi)容后,我們需要通過(guò)用戶名跳到用戶界面繼續(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
});
});
});
運(yùn)行程序,這段代碼得到的結(jié)果。
{<3>}
但是問(wèn)題來(lái)了,我們?cè)?end()的回調(diào)函數(shù)中能正確輸出結(jié)果,但是不能正確的輸出outcome。仔細(xì)一看,需要輸出的outcome是一個(gè)Request對(duì)象。這是因?yàn)榇中姆傅腻e(cuò)的,.end()函數(shù)并不會(huì)傳遞返回值給Request對(duì)象,需要將結(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)確地說(shuō),在.map()函數(shù)內(nèi),.get()的回調(diào)函數(shù)并沒(méi)有執(zhí)行完賦值score,return 返回值就進(jìn)行了。這就是回調(diào)函數(shù)的異步,而外層的同步操作是不會(huì)等待回調(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>}
這個(gè)問(wèn)題解決了,但score1的數(shù)值好像太大了點(diǎn)吧。再一看,原來(lái)class='big'有兩個(gè),用戶的話題收藏也是屬于這個(gè)class。我們得通過(guò)cheerio的.slice( start, [end] )來(lái)切取第一個(gè)元素,即將score 修改為 score = $('.big').slice(0).eq(0).text().trim();。正確結(jié)果如圖。
{<7>}
- NodeJS制作爬蟲全過(guò)程
- nodejs爬蟲抓取數(shù)據(jù)亂碼問(wèn)題總結(jié)
- nodeJs爬蟲獲取數(shù)據(jù)簡(jiǎn)單實(shí)現(xiàn)代碼
- Nodejs爬蟲進(jìn)階教程之異步并發(fā)控制
- nodeJS實(shí)現(xiàn)簡(jiǎn)單網(wǎng)頁(yè)爬蟲功能的實(shí)例(分享)
- nodejs爬蟲抓取數(shù)據(jù)之編碼問(wèn)題
- 基于nodejs 的多頁(yè)面爬蟲實(shí)例代碼
- nodejs爬蟲遇到的亂碼問(wèn)題匯總
- nodejs爬蟲初試superagent和cheerio
- nodejs制作小爬蟲功能示例
相關(guān)文章
Node 使用express-http-proxy 做api網(wǎng)關(guān)的實(shí)現(xiàn)
這篇文章主要介紹了Node 使用express-http-proxy 做api網(wǎng)關(guān)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10詳細(xì)談?wù)凬odeJS進(jìn)程是如何退出的
這篇文章主要給大家介紹了關(guān)于NodeJS進(jìn)程是如何退出的相關(guān)資料,主要介紹了導(dǎo)致進(jìn)程退出的三個(gè)因素:主動(dòng)退出;未捕獲的異常、未處理的 promise rejection;未處理的 Event Emitter error 事件 系統(tǒng)信號(hào),需要的朋友可以參考下2021-07-07使用nodeJs來(lái)安裝less及編譯less文件為css文件的方法
這篇文章主要介紹了使用nodeJs來(lái)安裝less及編譯less文件為css文件的方法,在文章末尾給大家補(bǔ)充介紹了通過(guò)nodejs將less文件轉(zhuǎn)為css文件的方法,具體內(nèi)容詳情大家通過(guò)本文學(xué)習(xí)吧2017-11-11Node.js連接數(shù)據(jù)庫(kù)實(shí)現(xiàn)過(guò)程詳解
這篇文章主要為大家介紹了Node.js連接數(shù)據(jù)庫(kù)實(shí)現(xiàn)過(guò)程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12Nodejs+Socket.io實(shí)現(xiàn)通訊實(shí)例代碼
本篇文章主要介紹了Nodejs+Socket.io實(shí)現(xiàn)通訊實(shí)例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-02-02