国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

使用Node.js開發(fā)一個小爬蟲

Songlcy / 2154人閱讀

摘要:前言很多程序猿在最開始學(xué)習(xí)開發(fā)的時候應(yīng)該都有一個想要自己開發(fā)一個爬蟲的想法至少我是有的。其實弄懂了爬蟲的原理,再回過頭去看,發(fā)現(xiàn)開發(fā)一個簡單的爬蟲來說還是很容易的。

前言

很多程序猿在最開始學(xué)習(xí)開發(fā)的時候應(yīng)該都有一個想要自己開發(fā)一個爬蟲的想法(至少我是有的)。所以國內(nèi)網(wǎng)絡(luò)上也是爬蟲盛行!學(xué)了node.js之后發(fā)現(xiàn)比較適合寫爬蟲,不過一直沒有動手去寫,正好這段時間比較閑,就寫個爬蟲玩下。

想著爬個什么東西呢?正好都比較喜歡看電影,那就從時光網(wǎng)爬下國內(nèi)的票房排行榜吧。

Talk is cheap. Show me the code

不bb,代碼在此

如何"食用"

</>復(fù)制代碼

  1. git clone https://github.com/XNAL/node-MovieSpider
  2. cd node-MovieSpider
  3. npm init
  4. node index.js
搭建環(huán)境

開發(fā)語言:node.js

發(fā)出http請求:superagent

并發(fā)控制:async

分析網(wǎng)頁內(nèi)容:cheerio

開始擼代碼 1. 代碼主體

作為一個簡單的示例,此次就不開啟node服務(wù)了,我這里就直接來個自執(zhí)行的方法。如果有需要,可以根據(jù)自己的需求擴展。

</>復(fù)制代碼

  1. // 啟動時直接執(zhí)行代碼
  2. (function spider() {
  3. util.fetch_data_get(reqUrl, reqParams)
  4. .then((result) => {
  5. // 根據(jù)頁面結(jié)構(gòu)獲取總的頁數(shù),然后再分頁獲取數(shù)據(jù)
  6. let $ = cheerio.load(result.body.html);
  7. let pageTotal = $(".bocontent .pagesize a:last-child").data("page") || 0;
  8. console.log("電影數(shù)據(jù)總頁數(shù):", pageTotal);
  9. return pageTotal;
  10. })
  11. .then((pageTotal) => {
  12. // 分頁獲取數(shù)據(jù)
  13. getMovieData(0, pageTotal);
  14. })
  15. .catch((err) => {
  16. console.log("獲取鏈接失敗:", err);
  17. })
  18. })();
2. 發(fā)送請求

因為代碼中需要多次發(fā)送http請求,所以把http請求寫成一個公共方法會比較好。使用上面提到superagent庫來實現(xiàn)。

</>復(fù)制代碼

  1. // 公共方法:通過get請求獲取數(shù)據(jù)
  2. function fetch_data_get(url, queryParams) {
  3. return new Promise((reslove, reject) => {
  4. superagent
  5. .get(url)
  6. .set(setting.header)
  7. .query(queryParams)
  8. .end((err, result) => {
  9. err ? reject(err) : reslove(result);
  10. })
  11. })
  12. }
3. 分析目標(biāo)網(wǎng)站api

根據(jù)人工操作得來的apihttp://movie.mtime.com/boxoffice/?year=2017&area=china&type=MovieRankingYear&category=all&page=0&display=list×tamp=1505818638620&version=07bb781100018dd58eafc3b35d42686804c6df8d&dataType=json可以得到以下參數(shù):

</>復(fù)制代碼

  1. // 根據(jù)網(wǎng)站api得到相應(yīng)的url和參數(shù)
  2. const reqUrl = "http://movie.mtime.com/boxoffice/";
  3. const reqParams = {
  4. "year": 2017,
  5. "area": "china",
  6. "type": "MovieRankingYear",
  7. "category": "all",
  8. "page": 0,
  9. "display": "list",
  10. "timestamp": 1501576013654,
  11. "version": "07bb781100018dd58eafc3b35d42686804c6df8d",
  12. "dataType": "json"
  13. };

因為此次要獲取的是2017年內(nèi)地票房排行榜。根據(jù)分析可知:需要變動的主要是page參數(shù),那這里就需要根據(jù)頁面返回的內(nèi)容來取得總的page

4. 使用cheerio獲取所需參數(shù)

api返回的頁面內(nèi)容可查看:將api獲取的數(shù)據(jù)格式化后的頁面代碼。

這里需要用到cheerio來取頁碼總數(shù)的代碼,cheerio可以理解為服務(wù)器端的jQuery,用法也類似:

</>復(fù)制代碼

  1. // 根據(jù)頁面結(jié)構(gòu)獲取總的頁數(shù),然后再分頁獲取數(shù)據(jù)
  2. let $ = cheerio.load(result.body.html);
  3. let pageTotal = $(".bocontent .pagesize a:last-child").data("page") || 0;
5. 開始分頁取目標(biāo)數(shù)據(jù)

<1> 調(diào)用上面所說的公共方法fetch_data_get獲取數(shù)據(jù),然后取頁面內(nèi)容,圖片地址都先保存在movieImgs中,最后再統(tǒng)一下載圖片:

</>復(fù)制代碼

  1. // 根據(jù)頁面結(jié)構(gòu)獲取所需數(shù)據(jù)
  2. let $ = cheerio.load(result.body.html);
  3. $(".bocontent .boxofficelist dd").each((idx, elem) => {
  4. $(elem).find("div.movietopmod").each((i, el) => {
  5. let _this = $(el);
  6. let arrLeadActor = [];
  7. _this.find(".txtbox b p").eq(1).find("a").each((idx, ela) => {
  8. arrLeadActor.push($(ela).text());
  9. })
  10. movieData.push({
  11. rank: _this.find(".picbox i").text(),
  12. img: _this.find(".picbox img").attr("src").replace(//u//, ""),
  13. name: _this.find(".txtbox h3").text(),
  14. director: _this.find(".txtbox b p").eq(0).find("a").text(),
  15. leadActor: arrLeadActor.join(","),
  16. point: _this.find(".gradebox .point").text(),
  17. total: _this.find(".totalbox .totalnum").text()
  18. }),
  19. movieImgs.push(_this.find(".picbox img").attr("src").replace(//u//, ""));
  20. })
  21. })

<2> 根據(jù)頁碼循環(huán)取數(shù)據(jù)

</>復(fù)制代碼

  1. if(pageIndex <= pageTotal) {
  2. // 設(shè)置timeout防止網(wǎng)站反爬蟲
  3. setTimeout(() => {
  4. pageIndex ++;
  5. getMovieData(pageIndex, pageTotal);
  6. }, setting.timeout);
  7. }

<3> 全部數(shù)據(jù)取出后存儲數(shù)據(jù),并下載圖片。

因為只是一個簡單的示例,所以此次數(shù)據(jù)只是保存到json文件中。如果需要對數(shù)據(jù)進行后續(xù)操作的話,那就最好保存到數(shù)據(jù)庫中:

</>復(fù)制代碼

  1. fs.writeFile(dataDir + reqParams.year + ".json", JSON.stringify(movieData), (err) => {
  2. if (err) {
  3. console.log(err);
  4. } else {
  5. console.log("數(shù)據(jù)寫入成功");
  6. }
  7. });

調(diào)用下載圖片的方法:

</>復(fù)制代碼

  1. let folderName = imgPrefix + reqParams.year;
  2. util.downloadImg(movieImgs, folderName);

util.js中的downloadImg方法:這里就需要用到上面所說的async,使用async是為了進行并發(fā)控制,不然極短時間發(fā)送至少幾十幾百次的請求,這種情況弄不好就被網(wǎng)站的發(fā)爬蟲程序給封了,而且大量并發(fā)也會導(dǎo)致出錯的概率更高。

</>復(fù)制代碼

  1. // 異步下載圖片
  2. function downloadImg(urls, folderName) {
  3. async.mapLimit(urls, setting.asyncNum, (img, callback) => {
  4. fetch_data_get(img, {})
  5. .then((result) => {
  6. let fileName = path.basename(img);
  7. let folder = imgDir + folderName;
  8. if(!fs.existsSync(folder)) {
  9. fs.mkdirSync(folder);
  10. }
  11. fs.writeFile(folder + "/" + fileName, result.body, (err) => {
  12. if (err) {
  13. console.log(img, "圖片寫入失敗:", err);
  14. } else {
  15. console.log(img, "圖片寫入成功");
  16. callback(null , fileName);
  17. }
  18. })
  19. })
  20. .catch((err) => console.log(err))
  21. }, (err, result) => {
  22. if (err) {
  23. console.log("圖片下載失敗:", err)
  24. } else {
  25. console.log(result);
  26. }
  27. })
  28. }
結(jié)語

到此為止一個簡單的node.js版的小爬蟲就開發(fā)完成了。其實弄懂了爬蟲的原理,再回過頭去看,發(fā)現(xiàn)開發(fā)一個簡單的爬蟲來說還是很容易的。

最后,歡迎大家去我的github進行starfork

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/91965.html

相關(guān)文章

  • 分分鐘教你用node.js寫個爬蟲

    摘要:爬蟲介紹二爬蟲的分類通用網(wǎng)絡(luò)爬蟲全網(wǎng)爬蟲爬行對象從一些種子擴充到整個,主要為門戶站點搜索引擎和大型服務(wù)提供商采集數(shù)據(jù)。 分分鐘教你用node.js寫個爬蟲 寫在前面 十分感謝大家的點贊和關(guān)注。其實,這是我第一次在segmentfault上寫文章。因為我也是前段時間偶然之間才開始了解和學(xué)習(xí)爬蟲,而且學(xué)習(xí)node的時間也不是很長。雖然用node做過一些后端的項目,但其實在node和爬蟲方面...

    fanux 評論0 收藏0
  • 養(yǎng)只爬蟲當(dāng)寵物(Node.js 爬蟲爬取 58 同城租房信息)

    摘要:一個爬蟲租房軟件。獲取導(dǎo)航頁以及數(shù)據(jù)打開同城主頁,我主要針對杭州的二手房進行了爬取分析,所以進入杭州租房。這次我們需要解析房屋所在地信息,用來可視化顯示。具體做法可以參照相關(guān)反爬蟲策略的文章。 一個爬蟲租房軟件。 先上一個源代碼吧。 https://github.com/answershuto/Rental 歡迎指導(dǎo)交流。 效果圖 showImg(https://segmentfau...

    宋華 評論0 收藏0
  • 實用的開源百度云分享爬蟲項目yunshare - 安裝篇

    摘要:今天開源了一個百度云網(wǎng)盤爬蟲項目,地址是。推薦使用命令安裝依賴,最簡單的安裝方式更多安裝的命令可以去上面找。啟動項目使用進行進程管理,運行啟動所有的后臺任務(wù),檢查任務(wù)是否正常運行可以用命令,正常運行的應(yīng)該有個任務(wù)。 今天開源了一個百度云網(wǎng)盤爬蟲項目,地址是https://github.com/callmelanmao/yunshare。 百度云分享爬蟲項目 github上有好幾個這樣的...

    lei___ 評論0 收藏0
  • 上天的Node.js爬蟲篇 15行代碼爬取京東淘寶資源 【深入淺出】

    摘要:這里由于京東的分界面都使用了,所以我們可以用,總之他們開發(fā)能用的選擇器,我們都可以用,否則就不可以。 難道爬蟲只能用 python 做? 不,我們上天的 Node.js 也可以做! 需要準(zhǔn)備的包 Node.js的最新版本 下載地址 Node.js官網(wǎng) npm 包管理器下載 下載最新的官網(wǎng)版本 Node.js 會自帶 npm npm的第三方包 puppeteer 在對應(yīng)...

    宋華 評論0 收藏0
  • 上天的Node.js爬蟲篇 15行代碼爬取京東淘寶資源 【深入淺出】

    摘要:這里由于京東的分界面都使用了,所以我們可以用,總之他們開發(fā)能用的選擇器,我們都可以用,否則就不可以。 難道爬蟲只能用 python 做? 不,我們上天的 Node.js 也可以做! 需要準(zhǔn)備的包 Node.js的最新版本 下載地址 Node.js官網(wǎng) npm 包管理器下載 下載最新的官網(wǎng)版本 Node.js 會自帶 npm npm的第三方包 puppeteer 在對應(yīng)...

    104828720 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<