成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

分分鐘教你用node.js寫個(gè)爬蟲

fanux / 1012人閱讀

摘要:爬蟲介紹二爬蟲的分類通用網(wǎng)絡(luò)爬蟲全網(wǎng)爬蟲爬行對(duì)象從一些種子擴(kuò)充到整個(gè),主要為門戶站點(diǎn)搜索引擎和大型服務(wù)提供商采集數(shù)據(jù)。

分分鐘教你用node.js寫個(gè)爬蟲 寫在前面
十分感謝大家的點(diǎn)贊和關(guān)注。其實(shí),這是我第一次在segmentfault上寫文章。因?yàn)槲乙彩乔岸螘r(shí)間偶然之間才開始了解和學(xué)習(xí)爬蟲,而且學(xué)習(xí)node的時(shí)間也不是很長。雖然用node做過一些后端的項(xiàng)目,但其實(shí)在node和爬蟲方面我還是一個(gè)新人,這篇文章主要是想和大家分享一下node和爬蟲方面的基本知識(shí),希望對(duì)大家有幫助,也想和大家一起交流,一起學(xué)習(xí),再次謝謝大家的支持!

對(duì)了,我開通了個(gè)人的 GitHub主頁 ,里面有自己的技術(shù)文章,還會(huì)有個(gè)人的隨想、思考和日志。以后所有的文章都會(huì)第一時(shí)間更新到這里,然后同步到其他平臺(tái)。有喜歡的朋友可以沒事去逛逛,再次感謝大家的支持!

一、什么是爬蟲
網(wǎng)絡(luò)爬蟲(又被稱為網(wǎng)頁蜘蛛,網(wǎng)絡(luò)機(jī)器人,在FOAF社區(qū)中間,更經(jīng)常的稱為網(wǎng)頁追逐者),是一種按照一定的規(guī)則,自動(dòng)地抓取萬維網(wǎng)信息的程序或者腳本。另外一些不常使用的名字還有螞蟻、自動(dòng)索引、模擬程序或者蠕蟲。
WIKIPEDIA 爬蟲介紹
二、爬蟲的分類

通用網(wǎng)絡(luò)爬蟲(全網(wǎng)爬蟲)

爬行對(duì)象從一些 種子URL 擴(kuò)充到整個(gè) Web,主要為門戶站點(diǎn)搜索引擎和大型 Web 服務(wù)提供商采集數(shù)據(jù)。

聚焦網(wǎng)絡(luò)爬蟲(主題網(wǎng)絡(luò)爬蟲)

指選擇性 地爬行那些與預(yù)先定義好的主題相關(guān)頁面的網(wǎng)絡(luò)爬蟲。

增量式網(wǎng)絡(luò)爬蟲

指對(duì)已下載網(wǎng)頁采取增量式更新和 只爬行新產(chǎn)生的或者已經(jīng)發(fā)生變化網(wǎng)頁 的爬蟲,它能夠在一定程度上保證所爬行的頁面是盡可能新的頁面。

Deep Web 爬蟲

爬行對(duì)象是一些在用戶填入關(guān)鍵字搜索或登錄后才能訪問到的深層網(wǎng)頁信息的爬蟲。
三、爬蟲的爬行策略

通用網(wǎng)絡(luò)爬蟲(全網(wǎng)爬蟲)

深度優(yōu)先策略、廣度優(yōu)先策略

聚焦網(wǎng)絡(luò)爬蟲(主題網(wǎng)絡(luò)爬蟲)

基于內(nèi)容評(píng)價(jià)的爬行策略(內(nèi)容相關(guān)性),基于鏈接結(jié)構(gòu)評(píng)價(jià)的爬行策略、基于增強(qiáng)學(xué)習(xí)的爬行策略(鏈接重要性),基于語境圖的爬行策略(距離,圖論中兩節(jié)點(diǎn)間邊的權(quán)重)

增量式網(wǎng)絡(luò)爬蟲

統(tǒng)一更新法、個(gè)體更新法、基于分類的更新法、自適應(yīng)調(diào)頻更新法

Deep Web 爬蟲

Deep Web 爬蟲爬行過程中最重要部分就是表單填寫,包含兩種類型:基于領(lǐng)域知識(shí)的表單填寫、基于網(wǎng)頁結(jié)構(gòu)分析的表單填寫

現(xiàn)代的網(wǎng)頁爬蟲的行為通常是四種策略組合的結(jié)果:

選擇策略:決定所要下載的頁面;
重新訪問策略:決定什么時(shí)候檢查頁面的更新變化;
平衡禮貌策略:指出怎樣避免站點(diǎn)超載;
并行策略:指出怎么協(xié)同達(dá)到分布式抓取的效果;

四、寫一個(gè)簡單網(wǎng)頁爬蟲的流程

確定爬取對(duì)象(網(wǎng)站/頁面)

分析頁面內(nèi)容(目標(biāo)數(shù)據(jù)/DOM結(jié)構(gòu))

確定開發(fā)語言、框架、工具等

編碼 測(cè)試,爬取數(shù)據(jù)

優(yōu)化

一個(gè)簡單的百度新聞爬蟲 確定爬取對(duì)象(網(wǎng)站/頁面)
百度新聞 (http://news.baidu.com/)
分析頁面內(nèi)容(目標(biāo)數(shù)據(jù)/DOM結(jié)構(gòu))
······
確定開發(fā)語言、框架、工具等
node.js (express) + SublimeText 3
編碼,測(cè)試,爬取數(shù)據(jù)
coding ···
Let"s start 新建項(xiàng)目目錄
1.在合適的磁盤目錄下創(chuàng)建項(xiàng)目目錄baiduNews(我的項(xiàng)目目錄是:F:webaiduNews

注:因?yàn)樵趯戇@篇文章的時(shí)候用的電腦真心比較渣。安裝WebStorm或者VsCode跑項(xiàng)目有些吃力。所以后面的命令行操作我都是在Window自帶的DOS命令行窗口中執(zhí)行的。

初始化package.json
1.在DOS命令行中進(jìn)入項(xiàng)目根目錄 baiduNews
2.執(zhí)行npm init,初始化package.json文件
安裝依賴
express (使用express來搭建一個(gè)簡單的Http服務(wù)器。當(dāng)然,你也可以使用node中自帶的http模塊)
superagent (superagent是node里一個(gè)非常方便的、輕量的、漸進(jìn)式的第三方客戶端請(qǐng)求代理模塊,用他來請(qǐng)求目標(biāo)頁面)
cheerio (cheerio相當(dāng)于node版的jQuery,用過jQuery的同學(xué)會(huì)非常容易上手。它主要是用來獲取抓取到的頁面元素和其中的數(shù)據(jù)信息)
// 個(gè)人比較喜歡使用yarn來安裝依賴包,當(dāng)然你也可以使用 npm install 來安裝依賴,看個(gè)人習(xí)慣。
yarn add express
yarn add superagent
yarn add cheerio

依賴安裝完成后你可以在package.json中查看剛才安裝的依賴是否成功。
安裝正確后如下圖:

開始coding

一、使用express啟動(dòng)一個(gè)簡單的本地Http服務(wù)器

1、在項(xiàng)目根目錄下創(chuàng)建index.js文件(后面都會(huì)在這個(gè)index文件中進(jìn)行coding)

2、創(chuàng)建好index.js后,我們首先實(shí)例化一個(gè)express對(duì)象,用它來啟動(dòng)一個(gè)本地監(jiān)聽3000端口的Http服務(wù)。

const express = require("express");
const app = express();

// ...

let server = app.listen(3000, function () {
  let host = server.address().address;
  let port = server.address().port;
  console.log("Your App is running at http://%s:%s", host, port);
});

對(duì),就是這么簡單,不到10行代碼,搭建啟動(dòng)一個(gè)簡單的本地Http服務(wù)。

3、按照國際慣例,我們希望在訪問本機(jī)地址http://localhost:3000的時(shí)候,這個(gè)服務(wù)能給我們犯規(guī)一個(gè)Hello World!index.js中加入如下代碼:

app.get("/", function (req, res) {
  res.send("Hello World!");
});
此時(shí),在DOS中項(xiàng)目根目錄baiduNews下執(zhí)行node index.js,讓項(xiàng)目跑起來。之后,打開瀏覽器,訪問http://localhost:3000,你就會(huì)發(fā)現(xiàn)頁面上顯示"Hellow World!"字樣。
這樣,在后面我們獲取到百度新聞首頁的信息后,就可以在訪問http://localhost:3000時(shí)看到這些信息。

二、抓取百度新聞首頁的新聞信息

1、 首先,我們先來分析一下百度新聞首頁的頁面信息。

百度新聞首頁大體上分為“熱點(diǎn)新聞”、“本地新聞”、“國內(nèi)新聞”、“國際新聞”......等。這次我們先來嘗試抓取左側(cè)“熱點(diǎn)新聞”和下方的“本地新聞”兩處的新聞數(shù)據(jù)。

F12打開Chrome的控制臺(tái),審查頁面元素,經(jīng)過查看左側(cè)“熱點(diǎn)新聞”信息所在DOM的結(jié)構(gòu),我們發(fā)現(xiàn)所有的“熱點(diǎn)新聞”信息(包括新聞標(biāo)題和新聞頁面鏈接)都在id#pane-news>下面

2、為了爬取新聞數(shù)據(jù),首先我們要用superagent請(qǐng)求目標(biāo)頁面,獲取整個(gè)新聞首頁信息

// 引入所需要的第三方包
const superagent= require("superagent");

let hotNews = [];                                // 熱點(diǎn)新聞
let localNews = [];                              // 本地新聞

/**
 * index.js
 * [description] - 使用superagent.get()方法來訪問百度新聞首頁
 */
superagent.get("http://news.baidu.com/").end((err, res) => {
  if (err) {
    // 如果訪問失敗或者出錯(cuò),會(huì)這行這里
    console.log(`熱點(diǎn)新聞抓取失敗 - ${err}`)
  } else {
   // 訪問成功,請(qǐng)求http://news.baidu.com/頁面所返回的數(shù)據(jù)會(huì)包含在res
   // 抓取熱點(diǎn)新聞數(shù)據(jù)
   hotNews = getHotNews(res)
  }
});

3、獲取頁面信息后,我們來定義一個(gè)函數(shù)getHotNews()來抓取頁面內(nèi)的“熱點(diǎn)新聞”數(shù)據(jù)。

/**
 * index.js
 * [description] - 抓取熱點(diǎn)新聞頁面
 */
// 引入所需要的第三方包
const cheerio = require("cheerio");

let getHotNews = (res) => {
  let hotNews = [];
  // 訪問成功,請(qǐng)求http://news.baidu.com/頁面所返回的數(shù)據(jù)會(huì)包含在res.text中。
  
  /* 使用cheerio模塊的cherrio.load()方法,將HTMLdocument作為參數(shù)傳入函數(shù)
     以后就可以使用類似jQuery的$(selectior)的方式來獲取頁面元素
   */
  let $ = cheerio.load(res.text);

  // 找到目標(biāo)數(shù)據(jù)所在的頁面元素,獲取數(shù)據(jù)
  $("div#pane-news ul li a").each((idx, ele) => {
    // cherrio中$("selector").each()用來遍歷所有匹配到的DOM元素
    // 參數(shù)idx是當(dāng)前遍歷的元素的索引,ele就是當(dāng)前便利的DOM元素
    let news = {
      title: $(ele).text(),        // 獲取新聞標(biāo)題
      href: $(ele).attr("href")    // 獲取新聞網(wǎng)頁鏈接
    };
    hotNews.push(news)              // 存入最終結(jié)果數(shù)組
  });
  return hotNews
};

這里要多說幾點(diǎn):

async/await據(jù)說是異步編程的終級(jí)解決方案,它可以讓我們以同步的思維方式來進(jìn)行異步編程。Promise解決了異步編程的“回調(diào)地獄”,async/await同時(shí)使異步流程控制變得友好而有清晰,有興趣的同學(xué)可以去了解學(xué)習(xí)一下,真的很好用。

superagent模塊提供了很多比如get、post、delte等方法,可以很方便地進(jìn)行Ajax請(qǐng)求操作。在請(qǐng)求結(jié)束后執(zhí)行.end()回調(diào)函數(shù)。.end()接受一個(gè)函數(shù)作為參數(shù),該函數(shù)又有兩個(gè)參數(shù)error和res。當(dāng)請(qǐng)求失敗,error會(huì)包含返回的錯(cuò)誤信息,請(qǐng)求成功,error值為null,返回的數(shù)據(jù)會(huì)包含在res參數(shù)中。

cheerio模塊的.load()方法,將HTML document作為參數(shù)傳入函數(shù),以后就可以使用類似jQuery的$(selectior)的方式來獲取頁面元素。同時(shí)可以使用類似于jQuery中的.each()來遍歷元素。此外,還有很多方法,大家可以自行Google/Baidu。

4、將抓取的數(shù)據(jù)返回給前端瀏覽器

前面,const app = express();實(shí)例化了一個(gè)express對(duì)象app
app.get("", async() => {})接受兩個(gè)參數(shù),第一個(gè)參數(shù)接受一個(gè)String類型的路由路徑,表示Ajax的請(qǐng)求路徑。第二個(gè)參數(shù)接受一個(gè)函數(shù)Function,當(dāng)請(qǐng)求此路徑時(shí)就會(huì)執(zhí)行這個(gè)函數(shù)中的代碼。
/**
 * [description] - 跟路由
 */
// 當(dāng)一個(gè)get請(qǐng)求 http://localhost:3000時(shí),就會(huì)后面的async函數(shù)
app.get("/", async (req, res, next) => {
  res.send(hotNews);
});
在DOS中項(xiàng)目根目錄baiduNews下執(zhí)行node index.js,讓項(xiàng)目跑起來。之后,打開瀏覽器,訪問http://localhost:3000,你就會(huì)發(fā)現(xiàn)抓取到的數(shù)據(jù)返回到了前端頁面。我運(yùn)行代碼后瀏覽器展示的返回信息如下:
注:因?yàn)槲业?b>Chrome
安裝了JSONView擴(kuò)展程序,所以返回的數(shù)據(jù)在頁面展示的時(shí)候會(huì)被自動(dòng)格式化為結(jié)構(gòu)性的JSON格式,方便查看。

OK??!這樣,一個(gè)簡單的百度“熱點(diǎn)新聞”的爬蟲就大功告成啦?。?/strong>

簡單總結(jié)一下,其實(shí)步驟很簡單:

express啟動(dòng)一個(gè)簡單的Http服務(wù)

分析目標(biāo)頁面DOM結(jié)構(gòu),找到所要抓取的信息的相關(guān)DOM元素

使用superagent請(qǐng)求目標(biāo)頁面

使用cheerio獲取頁面元素,獲取目標(biāo)數(shù)據(jù)

返回?cái)?shù)據(jù)到前端瀏覽器

現(xiàn)在,繼續(xù)我們的目標(biāo),抓取“本地新聞”數(shù)據(jù)(編碼過程中,我們會(huì)遇到一些有意思的問題)
有了前面的基礎(chǔ),我們自然而然的會(huì)想到利用和上面相同的方法“本地新聞”數(shù)據(jù)。
1、 分析頁面中“本地新聞”部分的DOM結(jié)構(gòu),如下圖:

F12打開控制臺(tái),審查“本地新聞”DOM元素,我們發(fā)現(xiàn),“本地新聞”分為兩個(gè)主要部分,“左側(cè)新聞”和右側(cè)的“新聞資訊”。這所有目標(biāo)數(shù)據(jù)都在id#local_newsdiv中?!白髠?cè)新聞”數(shù)據(jù)又在id#localnews-focusul標(biāo)簽下的li標(biāo)簽下的a標(biāo)簽中,包括新聞標(biāo)題和頁面鏈接?!氨镜刭Y訊”數(shù)據(jù)又在id#localnews-zixundiv下的ul標(biāo)簽下的li標(biāo)簽下的a標(biāo)簽中,包括新聞標(biāo)題和頁面鏈接。

2、OK!分析了DOM結(jié)構(gòu),確定了數(shù)據(jù)的位置,接下來和爬取“熱點(diǎn)新聞”一樣,按部就班,定義一個(gè)getLocalNews()函數(shù),爬取這些數(shù)據(jù)。

/**
 * [description] - 抓取本地新聞頁面
 */
let getLocalNews = (res) => {
  let localNews = [];
  let $ = cheerio.load(res);
    
  // 本地新聞
  $("ul#localnews-focus li a").each((idx, ele) => {
    let news = {
      title: $(ele).text(),
      href: $(ele).attr("href"),
    };
    localNews.push(news)
  });
    
  // 本地資訊
  $("div#localnews-zixun ul li a").each((index, item) => {
    let news = {
      title: $(item).text(),
      href: $(item).attr("href")
    };
    localNews.push(news);
  });

  return localNews
};

對(duì)應(yīng)的,在superagent.get()中請(qǐng)求頁面后,我們需要調(diào)用getLocalNews()函數(shù),來爬去本地新聞數(shù)據(jù)。
superagent.get()函數(shù)修改為:

superagent.get("http://news.baidu.com/").end((err, res) => {
  if (err) {
    // 如果訪問失敗或者出錯(cuò),會(huì)這行這里
    console.log(`熱點(diǎn)新聞抓取失敗 - ${err}`)
  } else {
   // 訪問成功,請(qǐng)求http://news.baidu.com/頁面所返回的數(shù)據(jù)會(huì)包含在res
   // 抓取熱點(diǎn)新聞數(shù)據(jù)
   hotNews = getHotNews(res)
   localNews = getLocalNews(res)
  }
});

同時(shí),我們要在app.get()路由中也要將數(shù)據(jù)返回給前端瀏覽器。app.get()路由代碼修改為:

/**
 * [description] - 跟路由
 */
// 當(dāng)一個(gè)get請(qǐng)求 http://localhost:3000時(shí),就會(huì)后面的async函數(shù)
app.get("/", async (req, res, next) => {
  res.send({
    hotNews: hotNews,
    localNews: localNews
  });
});
編碼完成,激動(dòng)不已!!DOS中讓項(xiàng)目跑起來,用瀏覽器訪問http://localhost:3000

尷尬的事情發(fā)生了?。》祷氐臄?shù)據(jù)只有熱點(diǎn)新聞,而本地新聞返回一個(gè)空數(shù)組[ ]。檢查代碼,發(fā)現(xiàn)也沒有問題,但為什么一直返回的空數(shù)組呢?
經(jīng)過一番原因查找,才返現(xiàn)問題出在哪里!!

一個(gè)有意思的問題
為了找到原因,首先,我們看看用superagent.get("http://news.baidu.com/").end((err, res) => {})請(qǐng)求百度新聞首頁在回調(diào)函數(shù).end()中的第二個(gè)參數(shù)res中到底拿到了什么內(nèi)容?
// 新定義一個(gè)全局變量 pageRes
let pageRes = {};        // supergaent頁面返回值

// superagent.get()中將res存入pageRes
superagent.get("http://news.baidu.com/").end((err, res) => {
  if (err) {
    // 如果訪問失敗或者出錯(cuò),會(huì)這行這里
    console.log(`熱點(diǎn)新聞抓取失敗 - ${err}`)
  } else {
   // 訪問成功,請(qǐng)求http://news.baidu.com/頁面所返回的數(shù)據(jù)會(huì)包含在res
   // 抓取熱點(diǎn)新聞數(shù)據(jù)
   // hotNews = getHotNews(res)
   // localNews = getLocalNews(res)
   pageRes = res
  }
});

// 將pageRes返回給前端瀏覽器,便于查看
app.get("/", async (req, res, next) => {
  res.send({
    // {}hotNews: hotNews,
    // localNews: localNews,
    pageRes: pageRes
  });
});
訪問瀏覽器http://localhost:3000,頁面展示如下內(nèi)容:

可以看到,返回值中的text字段應(yīng)該就是整個(gè)頁面的HTML代碼的字符串格式。為了方便我們觀察,可以直接把這個(gè)text字段值返回給前端瀏覽器,這樣我們就能夠清晰地看到經(jīng)過瀏覽器渲染后的頁面。

修改給前端瀏覽器的返回值

app.get("/", async (req, res, next) => {
  res.send(pageRes.text)
}

訪問瀏覽器http://localhost:3000,頁面展示如下內(nèi)容:

審查元素才發(fā)現(xiàn),原來我們抓取的目標(biāo)數(shù)據(jù)所在的DOM元素中是空的,里面沒有數(shù)據(jù)!
到這里,一切水落石出!在我們使用superagent.get()訪問百度新聞首頁時(shí),res中包含的獲取的頁面內(nèi)容中,我們想要的“本地新聞”數(shù)據(jù)還沒有生成,DOM節(jié)點(diǎn)元素是空的,所以出現(xiàn)前面的情況!抓取后返回的數(shù)據(jù)一直是空數(shù)組[ ]。

在控制臺(tái)的Network中我們發(fā)現(xiàn)頁面請(qǐng)求了一次這樣的接口:
http://localhost:3000/widget?id=LocalNews&ajax=json&t=1526295667917,接口狀態(tài) 404。
這應(yīng)該就是百度新聞獲取“本地新聞”的接口,到這里一切都明白了!“本地新聞”是在頁面加載后動(dòng)態(tài)請(qǐng)求上面這個(gè)接口獲取的,所以我們用superagent.get()請(qǐng)求的頁面再去請(qǐng)求這個(gè)接口時(shí),接口URLhostname部分變成了本地IP地址,而本機(jī)上沒有這個(gè)接口,所以404,請(qǐng)求不到數(shù)據(jù)。

找到原因,我們來想辦法解決這個(gè)問題!!

直接使用superagent訪問正確合法的百度“本地新聞”的接口,獲取數(shù)據(jù)后返回給前端瀏覽器。

使用第三方npm包,模擬瀏覽器訪問百度新聞首頁,在這個(gè)模擬瀏覽器中當(dāng)“本地新聞”加載成功后,抓取數(shù)據(jù),返回給前端瀏覽器。

以上方法均可,我們來試試比較有意思的第二種方法

使用Nightmare自動(dòng)化測(cè)試工具
Electron可以讓你使用純JavaScript調(diào)用Chrome豐富的原生的接口來創(chuàng)造桌面應(yīng)用。你可以把它看作一個(gè)專注于桌面應(yīng)用的Node.js的變體,而不是Web服務(wù)器。其基于瀏覽器的應(yīng)用方式可以極方便的做各種響應(yīng)式的交互

Nightmare是一個(gè)基于Electron的框架,針對(duì)Web自動(dòng)化測(cè)試和爬蟲,因?yàn)槠渚哂懈?b>PlantomJS一樣的自動(dòng)化測(cè)試的功能可以在頁面上模擬用戶的行為觸發(fā)一些異步數(shù)據(jù)加載,也可以跟Request庫一樣直接訪問URL來抓取數(shù)據(jù),并且可以設(shè)置頁面的延遲時(shí)間,所以無論是手動(dòng)觸發(fā)腳本還是行為觸發(fā)腳本都是輕而易舉的。

安裝依賴
// 安裝nightmare
yarn add nightmare
為獲取“本地新聞”,繼續(xù)coding...

index.js中新增如下代碼:

const Nightmare = require("nightmare");          // 自動(dòng)化測(cè)試包,處理動(dòng)態(tài)頁面
const nightmare = Nightmare({ show: true });     // show:true  顯示內(nèi)置模擬瀏覽器

/**
 * [description] - 抓取本地新聞頁面
 * [nremark] - 百度本地新聞在訪問頁面后加載js定位IP位置后獲取對(duì)應(yīng)新聞,
 * 所以抓取本地新聞需要使用 nightmare 一類的自動(dòng)化測(cè)試工具,
 * 模擬瀏覽器環(huán)境訪問頁面,使js運(yùn)行,生成動(dòng)態(tài)頁面再抓取
 */
// 抓取本地新聞頁面
nightmare
.goto("http://news.baidu.com/")
.wait("div#local_news")
.evaluate(() => document.querySelector("div#local_news").innerHTML)
.then(htmlStr => {
  // 獲取本地新聞數(shù)據(jù)
  localNews = getLocalNews(htmlStr)
})
.catch(error => {
  console.log(`本地新聞抓取失敗 - ${error}`);
})

修改getLocalNews()函數(shù)為:

/**
 * [description]- 獲取本地新聞數(shù)據(jù)
 */
let getLocalNews = (htmlStr) => {
  let localNews = [];
  let $ = cheerio.load(htmlStr);

  // 本地新聞
  $("ul#localnews-focus li a").each((idx, ele) => {
    let news = {
      title: $(ele).text(),
      href: $(ele).attr("href"),
    };
    localNews.push(news)
  });

  // 本地資訊
  $("div#localnews-zixun ul li a").each((index, item) => {
    let news = {
      title: $(item).text(),
      href: $(item).attr("href")
    };
    localNews.push(news);
  });

  return localNews
}

修改app.get("/")路由為:

/**
 * [description] - 跟路由
 */
// 當(dāng)一個(gè)get請(qǐng)求 http://localhost:3000時(shí),就會(huì)后面的async函數(shù)
app.get("/", async (req, res, next) => {
  res.send({
    hotNews: hotNews,
    localNews: localNews
  })
});
此時(shí),DOS命令行中重新讓項(xiàng)目跑起來,瀏覽器訪問https://localhost:3000,看看頁面展示的信息,看是否抓取到了“本地新聞”數(shù)據(jù)!

至此,一個(gè)簡單而又完整的抓取百度新聞頁面“熱點(diǎn)新聞”和“本地新聞”的爬蟲就大功告成啦!!

最后總結(jié)一下,整體思路如下:

express啟動(dòng)一個(gè)簡單的Http服務(wù)

分析目標(biāo)頁面DOM結(jié)構(gòu),找到所要抓取的信息的相關(guān)DOM元

使用superagent請(qǐng)求目標(biāo)頁面

動(dòng)態(tài)頁面(需要加載頁面后運(yùn)行JS或請(qǐng)求接口的頁面)可以使用Nightmare模擬瀏覽器訪問

使用cheerio獲取頁面元素,獲取目標(biāo)數(shù)據(jù)

完整代碼
爬蟲完整代碼GitHub地址:完整代碼

后面,應(yīng)該還會(huì)做一些進(jìn)階,來爬取某些網(wǎng)站上比較好看的圖片(手動(dòng)滑稽),會(huì)牽扯到并發(fā)控制反-反爬蟲的一些策略。再用爬蟲取爬去一些需要登錄和輸入驗(yàn)證碼的網(wǎng)站,歡迎到時(shí)大家關(guān)注和指正交流。

我想說
再次感謝大家的點(diǎn)贊和關(guān)注和評(píng)論,謝謝大家的支持,謝謝!我自己覺得我算是一個(gè)愛文字,愛音樂,同時(shí)也喜歡coding的半文藝程序員。之前也一直想著寫一寫技術(shù)性和其他偏文學(xué)性的文章。雖然自己的底子沒有多么優(yōu)秀,但總是覺得在寫文章的過程中,不論是技術(shù)性的還是偏文學(xué)性的,這個(gè)過程中可以督促自己去思考,督促自己去學(xué)習(xí)和交流。畢竟每天忙忙碌碌之余,還是要活出自己不一樣的生活。所以,以后如果有一些好的文章我會(huì)積極和大家分享!再次感謝大家的支持!

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/94878.html

相關(guān)文章

  • 手把手教你寫帶登錄的NodeJS爬蟲+數(shù)據(jù)展示

    摘要:可以通過傳入待刪除數(shù)組元素組成的數(shù)組進(jìn)行一次性刪除。如果后臺(tái)返回的為表示登錄的已失效,需要重新執(zhí)行。等所有的異步執(zhí)行完畢后,再執(zhí)行回調(diào)函數(shù)?;卣{(diào)函數(shù)的參數(shù)是每個(gè)函數(shù)返回?cái)?shù)據(jù)組成的數(shù)組。 其實(shí)在早之前,就做過立馬理財(cái)?shù)匿N售額統(tǒng)計(jì),只不過是用前端js寫的,需要在首頁的console調(diào)試面板里粘貼一段代碼執(zhí)行,點(diǎn)擊這里。主要是通過定時(shí)爬取https://www.lmlc.com/s/web/...

    cpupro 評(píng)論0 收藏0
  • 2017-06-20 前端日?qǐng)?bào)

    摘要:前端日?qǐng)?bào)精選專題之跟著學(xué)節(jié)流冴羽的博客全家桶仿微信項(xiàng)目,支持多人在線聊天和機(jī)器人聊天騰訊前端團(tuán)隊(duì)社區(qū)編碼的奧秘模塊實(shí)現(xiàn)入門淺析知乎專欄前端每周清單發(fā)布新版本提升應(yīng)用性能的方法中文寇可往吾亦可往用實(shí)現(xiàn)對(duì)決支付寶的微信企業(yè)付款到零 2017-06-20 前端日?qǐng)?bào) 精選 JavaScript專題之跟著 underscore 學(xué)節(jié)流 - 冴羽的JavaScript博客 - SegmentFau...

    Galence 評(píng)論0 收藏0
  • 手把手你用Python爬蟲煎蛋妹紙海量圖片

    摘要:我們的目標(biāo)是用爬蟲來干一件略污事情最近聽說煎蛋上有好多可愛的妹子,而且爬蟲從妹子圖抓起練手最好,畢竟動(dòng)力大嘛。服務(wù)器超載尤其是對(duì)給定服務(wù)器的訪問過高時(shí)。個(gè)人爬蟲,如果過多的人使用,可能導(dǎo)致網(wǎng)絡(luò)或者服務(wù)器阻塞。 我們的目標(biāo)是用爬蟲來干一件略污事情 最近聽說煎蛋上有好多可愛的妹子,而且爬蟲從妹子圖抓起練手最好,畢竟動(dòng)力大嘛。而且現(xiàn)在網(wǎng)絡(luò)上的妹子很黃很暴力,一下接受太多容易營養(yǎng)不量,但是本著...

    tuantuan 評(píng)論0 收藏0
  • 手把手你用koa+mongoodb實(shí)現(xiàn)自己的接口

    摘要:實(shí)際前端開發(fā)中我們常常需要模擬數(shù)據(jù)市場(chǎng)上有許多工具提供使用但是基本都是提供數(shù)據(jù)展示如果我們想要一個(gè)具備增刪改查功能的接口怎么辦呢當(dāng)然是強(qiáng)大自己啦首先我們需要新建一個(gè)目錄安裝依賴及以上版本,首先確認(rèn)版本在以上,版本低的請(qǐng)自行搞定寫個(gè)試 實(shí)際前端開發(fā)中我們常常需要模擬數(shù)據(jù),市場(chǎng)上有許多工具提供使用但是基本都是提供數(shù)據(jù)展示,如果我們想要一個(gè)具備增刪改查功能的接口怎么辦呢?當(dāng)然是強(qiáng)大自己啦??!...

    ingood 評(píng)論0 收藏0
  • 手把手你用koa+mongoodb實(shí)現(xiàn)自己的接口

    摘要:實(shí)際前端開發(fā)中我們常常需要模擬數(shù)據(jù)市場(chǎng)上有許多工具提供使用但是基本都是提供數(shù)據(jù)展示如果我們想要一個(gè)具備增刪改查功能的接口怎么辦呢當(dāng)然是強(qiáng)大自己啦首先我們需要新建一個(gè)目錄安裝依賴及以上版本,首先確認(rèn)版本在以上,版本低的請(qǐng)自行搞定寫個(gè)試 實(shí)際前端開發(fā)中我們常常需要模擬數(shù)據(jù),市場(chǎng)上有許多工具提供使用但是基本都是提供數(shù)據(jù)展示,如果我們想要一個(gè)具備增刪改查功能的接口怎么辦呢?當(dāng)然是強(qiáng)大自己啦??!...

    piapia 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

fanux

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<