摘要:爬蟲介紹二爬蟲的分類通用網(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é)果:
選擇策略:決定所要下載的頁面;四、寫一個(gè)簡單網(wǎng)頁爬蟲的流程
重新訪問策略:決定什么時(shí)候檢查頁面的更新變化;
平衡禮貌策略:指出怎樣避免站點(diǎn)超載;
并行策略:指出怎么協(xié)同達(dá)到分布式抓取的效果;
確定爬取對(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.json1.在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中查看剛才安裝的依賴是否成功。
安裝正確后如下圖:
一、使用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的>下面下下的標(biāo)簽中。用jQuery的選擇器表示為:#pane-news ul li a。
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_news的div中?!白髠?cè)新聞”數(shù)據(jù)又在id為#localnews-focus的ul標(biāo)簽下的li標(biāo)簽下的a標(biāo)簽中,包括新聞標(biāo)題和頁面鏈接?!氨镜刭Y訊”數(shù)據(jù)又在id為#localnews-zixun的div下的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ù)組呢?
一個(gè)有意思的問題
經(jīng)過一番原因查找,才返現(xiàn)問題出在哪里!!為了找到原因,首先,我們看看用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í),接口URL中hostname部分變成了本地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
摘要:可以通過傳入待刪除數(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/...
摘要:前端日?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...
摘要:我們的目標(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)不量,但是本著...
摘要:實(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)大自己啦??!...
摘要:實(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)大自己啦??!...
閱讀 2681·2021-11-18 10:02
閱讀 3453·2021-09-22 15:50
閱讀 2373·2021-09-06 15:02
閱讀 3594·2019-08-29 16:34
閱讀 1757·2019-08-29 13:49
閱讀 1290·2019-08-29 13:29
閱讀 3653·2019-08-28 18:08
閱讀 2987·2019-08-26 11:52