摘要:剛開(kāi)始寫(xiě)的時(shí)候我把聲明在了全局,以至于返回成下面這組數(shù)據(jù)爬取課程詳情頁(yè)的信息在我們有了所有課程詳情頁(yè)的后,我們開(kāi)始爬取里面的內(nèi)容。
引言
在學(xué)習(xí)了 alsotang 大神的 《Node.js包教不包會(huì)》后的一個(gè)爬蟲(chóng)小練習(xí),期間也碰到挺多小問(wèn)題,也學(xué)到了很多小東西?!竼窝骸?」
這里是大神的教程地址 https://github.com/alsotang/node-lessons,
下面是自己的爬取效果圖
)
同時(shí)推薦一個(gè)谷歌插件 JSONView,會(huì)將 JSON 格式的數(shù)據(jù)轉(zhuǎn)化成上面圖的格式
imoocSpider練習(xí)源碼
搭建服務(wù)器首先,搭建一個(gè) http 服務(wù)
var http = require("http"); var express = require("express"); var app = express(); http.createServer(app).listen(8080); app.get("/", function(req, res) { //code here... })
用的是 express 搭建的,當(dāng)然也可以用原生的,在這里自己比較習(xí)慣用 express
在線爬蟲(chóng)在這里用到的是 superagent 和 cheerio 來(lái)爬取頁(yè)面,這里有相關(guān)文檔可以參考: superagent中文文檔、cheerio,都是來(lái)自 cnode 社區(qū),當(dāng)然英語(yǔ)能力較好的也可以參考原文檔。在這里就只貼出這兩個(gè)
爬取頁(yè)面鏈接 https://www.imooc.com/course/...
我們是要爬取慕課網(wǎng)前端開(kāi)發(fā)八個(gè)頁(yè)面的課程中的一些信息,但是打開(kāi)此鏈接發(fā)現(xiàn)每個(gè)頁(yè)面只有課程的名稱,并沒(méi)有老師的名稱和一些課程的主要信息。因此我們還需要獲取并根據(jù)每個(gè)課程的 url 進(jìn)行爬取。
獲取課程詳情頁(yè)鏈接
那我們先來(lái)爬取八個(gè)頁(yè)面的所有課程詳情頁(yè)的 url
通過(guò)點(diǎn)擊對(duì)應(yīng)頁(yè)面的按鈕,發(fā)現(xiàn)每次都會(huì)發(fā)送一個(gè)新的 get 請(qǐng)求,請(qǐng)求的鏈接就是對(duì)應(yīng)的頁(yè)面,而這里的鏈接只有 page 屬性是不同的,因此我們通過(guò)動(dòng)態(tài)改變 page 就可以模擬點(diǎn)擊對(duì)應(yīng)頁(yè)來(lái)獲取對(duì)應(yīng)頁(yè)的信息
var pages = 1; var baseUrl = "https://www.imooc.com/course/list/"; var params = { c: "fe", page: page }; superagent .get(baseUrl) .query(params) .end(function(err, content) { var topicUrls = []; var $ = cheerio.load(content.text); var courseCard = $(".course-card-container"); courseCard.each(function(index, element) { var $element = $(element); var href = url.resolve( homeUrl, $element.find(".course-card").attr("href") ); topicUrls.push(href); }); console.log(topicUrls); });
這樣就可以獲取到了第一個(gè)頁(yè)面的 25 個(gè)課程的詳情頁(yè)的 url,那要如何獲取八個(gè)頁(yè)面呢。
async
因?yàn)橛行┚W(wǎng)站通常都會(huì)有安全限制,不會(huì)允許同一個(gè)域名有過(guò)大的高并發(fā)數(shù),因此需要限制并發(fā)數(shù),在這里用我們用到了 async 這個(gè)庫(kù)。這里是其 github
我們首先把前面代碼封裝成一個(gè)函數(shù)
var baseUrl = "https://www.imooc.com/course/list/"; var fetchUrl = function(page, callback) { count++; console.log("當(dāng)前并發(fā)數(shù)", count); var params = { c: "fe", page: page }; superagent .get(baseUrl) .query(params) .end(function(err, content) { var topicUrls = []; var $ = cheerio.load(content.text); var courseCard = $(".course-card-container"); courseCard.each(function(index, element) { var $element = $(element); var href = url.resolve( homeUrl, $element.find(".course-card").attr("href") ); topicUrls.push(href); }); callback(err, topicUrls); count--; console.log("釋放并發(fā)數(shù)后當(dāng)前并發(fā)數(shù)", count); }); };
然后用 async 控制并發(fā)數(shù)和八個(gè)頁(yè)面的抓取
var pages = [1, 2, 3, 4, 5, 6, 7, 8]; async.mapLimit( pages, 5, function(page, callback) { fetchUrl(page, callback); }, function(err, result) { if (err) console.log(err); console.log(result) } ); });
這樣所有的 url 就被打印出來(lái),這里要注意一下,async 會(huì)自動(dòng)把第三個(gè)函數(shù)參數(shù)的返回值合并成一個(gè)數(shù)組給第四個(gè)函數(shù)參數(shù)的 result 參數(shù)。剛開(kāi)始寫(xiě)的時(shí)候我把 topicUrls 聲明在了全局,以至于返回成下面這組數(shù)據(jù)
爬取課程詳情頁(yè)的信息
在我們有了所有課程詳情頁(yè)的 url 后,我們開(kāi)始爬取里面的內(nèi)容。首先定義一個(gè)函數(shù)
var fetchMsg = function(topicUrl, callback) { console.log("開(kāi)啟新一輪抓取") superagent .get(topicUrl) .end(function(err, content){ var Item = []; var $ = cheerio.load(content.text); var title = $(".hd .l").text().trim();//課程名字 var teacher = $(".tit a").text().trim();//老師名字 var level = $(".meta-value").eq(0).text().trim();//難度 var time = $(".meta-value").eq(1).text().trim();//時(shí)長(zhǎng) var grade = $(".meta-value").eq(3).text().trim();//評(píng)分 Item.push({ title: title, teacher: teacher, level: level, time: time, grade: grade, href: topicUrl }) callback(null, Item); }) };
然后用 async 控制并發(fā)爬取
//result 為上文中的 result,下面的代碼也都是在上文中的第四個(gè)參數(shù)中 var topicUrls = result; //獲取所有 url ,但是大數(shù)組里面有 8 個(gè)小數(shù)組 var Urls = []; //將大數(shù)組合并 for(let i=0,l=topicUrls.length;i這里要注意一個(gè)小問(wèn)題,就是 result 獲取到的 url 結(jié)構(gòu)是一個(gè)大數(shù)組里面包含八個(gè)小數(shù)組,因此需要將其小數(shù)組先合并成一個(gè)大數(shù)組。
最后項(xiàng)目源碼
原文地址
每天探索一點(diǎn)點(diǎn),每天進(jìn)步一點(diǎn)點(diǎn)。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/95057.html
摘要:時(shí)間年月日星期日說(shuō)明本文部分內(nèi)容均來(lái)自慕課網(wǎng)。用戶可以在服務(wù)器端調(diào)用云存儲(chǔ)云檢索從而構(gòu)建自己的存儲(chǔ)和檢索服務(wù),甚至可以制作自己的數(shù)據(jù)管理臺(tái)。 時(shí)間:2017年08月13日星期日說(shuō)明:本文部分內(nèi)容均來(lái)自慕課網(wǎng)。@慕課網(wǎng):http://www.imooc.com教學(xué)源碼:無(wú)學(xué)習(xí)源碼:https://github.com/zccodere/s... 第一章:云圖產(chǎn)品介紹 1-1 云圖產(chǎn)品介紹...
摘要:時(shí)間年月日星期日說(shuō)明本文部分內(nèi)容均來(lái)自慕課網(wǎng)。用戶可以在服務(wù)器端調(diào)用云存儲(chǔ)云檢索從而構(gòu)建自己的存儲(chǔ)和檢索服務(wù),甚至可以制作自己的數(shù)據(jù)管理臺(tái)。 時(shí)間:2017年08月13日星期日說(shuō)明:本文部分內(nèi)容均來(lái)自慕課網(wǎng)。@慕課網(wǎng):http://www.imooc.com教學(xué)源碼:無(wú)學(xué)習(xí)源碼:https://github.com/zccodere/s... 第一章:云圖產(chǎn)品介紹 1-1 云圖產(chǎn)品介紹...
摘要:前言繼一次的魔方之后,這次帶你一起玩轉(zhuǎn)性感美女秀,正常套路,請(qǐng)先一堵為快,有興趣繼續(xù),沒(méi)興趣也可以看看美女養(yǎng)眼哦 showImg(https://segmentfault.com/img/bVbi4d2?w=1008&h=298); 前言 繼一次的3D魔方之后,這次帶你一起玩轉(zhuǎn)性感美女秀,正常套路,請(qǐng)先一堵為快,有興趣繼續(xù),沒(méi)興趣也可以看看美女養(yǎng)眼哦
閱讀 1404·2021-11-15 11:37
閱讀 2340·2021-09-30 09:55
閱讀 4866·2021-09-22 15:51
閱讀 3868·2021-09-22 15:46
閱讀 2855·2019-08-30 15:52
閱讀 582·2019-08-29 16:20
閱讀 2984·2019-08-29 15:12
閱讀 1243·2019-08-26 18:27