Nodejs學習筆記(十一)--- 資料採集器示例(request和cheerio)
目錄
寫在之前
很多人都有做資料採集的需求,用不同的語言,不同的方式都能實現,我以前也用C#寫過,主要還是傳送各類請求和正則解析資料比較繁瑣些,總體來說沒啥不好的,就是效率要差一些,
用nodejs寫採集程式還是比較有效率(可能也只是相對C#來說),今天主要用一個示例來說一下使用nodejs實現資料採集器,主要使用到request和cheerio。
request :用於http請求
cheerio:用於提取request返回的html中需要的資訊(和jquery用法一致)
示例
單獨去說API用法沒什麼意思也沒必要記住全部API,下面開始示例
還是說點閒話:
nodejs開發工具還是很多,以前我也很推薦sublime,自從微軟推出了Visual Studio Code後就轉用它去做nodejs開發。
用它開發還是比較舒服的,免配置、啟動快、自動補全、檢視定義和引用、搜尋快等,有VS的一貫風格,應該會越做越好,所以推薦一下^_^!
示例要求
從 http://36kr.com/ 中抓取其中文章的“標題”、“地址”、“釋出時間”、“封面圖片”
採集器
1.建立專案資料夾sampleDAU
2.建立package.json檔案
{ "name": "Wilson_SampleDAU","version": "0.0.1", "private": false, "dependencies": { "request":"*", "cheerio":"*" } }
3.在終端中用npm安裝引用
cd 專案根目錄 npm install
4.建立app.js編寫採集器程式碼
首先要用瀏覽器開啟要採集的URL,使用開發者工具檢視HTML結構,然後根據結構寫解析程式碼
/* * 功能: 資料採集 * 建立人: Wilson * 時間: 2015-07-29 */ var request = require('request'), cheerio= require('cheerio'), URL_36KR = 'http://36kr.com/'; //36氪 /* 開啟資料採集器 */ function dataCollectorStartup() { dataRequest(URL_36KR); } /* 資料請求 */ function dataRequest(dataUrl) { request({ url: dataUrl, method: 'GET' }, function(err, res, body) { if (err) { console.log(dataUrl) console.error('[ERROR]Collection' + err); return; } switch(dataUrl) { case URL_36KR: dataParse36Kr(body); break; } }); } /* 36kr 資料解析 */ function dataParse36Kr(body) { console.log('============================================================================================'); console.log('======================================36kr=================================================='); console.log('============================================================================================'); var $ = cheerio.load(body); var articles = $('article') for (var i = 0; i < articles.length; i++) { var article = articles[i]; var descDoms = $(article).find('.desc'); if(descDoms.length == 0) { continue; } var coverDom = $(article).children().first(); var titleDom = $(descDoms).find('.info_flow_news_title'); var timeDom = $(descDoms).find('.timeago'); var titleVal = titleDom.text(); var urlVal = titleDom.attr('href'); var timeVal = timeDom.attr('title'); var coverUrl = coverDom.attr('data-lazyload'); //處理時間 var timeDateSecs = new Date(timeVal).getTime() / 1000; if(urlVal != undefined) { console.info('--------------------------------'); console.info('標題:' + titleVal); console.info('地址:' + urlVal); console.info('時間:' + timeDateSecs); console.info('封面:' + coverUrl); console.info('--------------------------------'); } }; } dataCollectorStartup();
測試結果
這個採集器就完成了,其實就是request一個get請求,請求回撥中會返回body即HTML程式碼,通過cheerio庫以jquery庫語法一樣操作解析,取出想要的資料!
加入代理
做一個採集器DEMO上面就基本完成了。如果需要長期使用為了防止網站遮蔽,還是需要加入一個代理列表
為示例我從網上的免費代理中提出一些做示例,製作成proxylist.js,其中提供一個隨機取一條代理的函式
var PROXY_LIST = [{"ip":"111.1.55.136","port":"55336"},{"ip":"111.1.54.91","port":"55336"},{"ip":"111.1.56.19","port":"55336"} ,{"ip":"112.114.63.16","port":"55336"},{"ip":"106.58.63.83","port":"55336"},{"ip":"119.188.133.54","port":"55336"} ,{"ip":"106.58.63.84","port":"55336"},{"ip":"183.95.132.171","port":"55336"},{"ip":"11.12.14.9","port":"55336"} ,{"ip":"60.164.223.16","port":"55336"},{"ip":"117.185.13.87","port":"8080"},{"ip":"112.114.63.20","port":"55336"} ,{"ip":"188.134.19.102","port":"3129"},{"ip":"106.58.63.80","port":"55336"},{"ip":"60.164.223.20","port":"55336"} ,{"ip":"106.58.63.78","port":"55336"},{"ip":"112.114.63.23","port":"55336"},{"ip":"112.114.63.30","port":"55336"} ,{"ip":"60.164.223.14","port":"55336"},{"ip":"190.202.82.234","port":"3128"},{"ip":"60.164.223.15","port":"55336"} ,{"ip":"60.164.223.5","port":"55336"},{"ip":"221.204.9.28","port":"55336"},{"ip":"60.164.223.2","port":"55336"} ,{"ip":"139.214.113.84","port":"55336"} ,{"ip":"112.25.49.14","port":"55336"},{"ip":"221.204.9.19","port":"55336"} ,{"ip":"221.204.9.39","port":"55336"},{"ip":"113.207.57.18","port":"55336"} ,{"ip":"112.25.62.15","port":"55336"} ,{"ip":"60.5.255.143","port":"55336"},{"ip":"221.204.9.18","port":"55336"},{"ip":"60.5.255.145","port":"55336"} ,{"ip":"221.204.9.16","port":"55336"},{"ip":"183.232.82.132","port":"55336"},{"ip":"113.207.62.78","port":"55336"} ,{"ip":"60.5.255.144","port":"55336"} ,{"ip":"60.5.255.141","port":"55336"},{"ip":"221.204.9.23","port":"55336"} ,{"ip":"157.122.96.50","port":"55336"},{"ip":"218.61.39.41","port":"55336"} ,{"ip":"221.204.9.26","port":"55336"} ,{"ip":"112.112.43.213","port":"55336"},{"ip":"60.5.255.138","port":"55336"},{"ip":"60.5.255.133","port":"55336"} ,{"ip":"221.204.9.25","port":"55336"},{"ip":"111.161.35.56","port":"55336"},{"ip":"111.161.35.49","port":"55336"} ,{"ip":"183.129.134.226","port":"8080"} ,{"ip":"58.220.10.86","port":"80"},{"ip":"183.87.117.44","port":"80"} ,{"ip":"211.23.19.130","port":"80"},{"ip":"61.234.249.107","port":"8118"},{"ip":"200.20.168.140","port":"80"} ,{"ip":"111.1.46.176","port":"55336"},{"ip":"120.203.158.149","port":"8118"},{"ip":"70.39.189.6","port":"9090"} ,{"ip":"210.6.237.191","port":"3128"},{"ip":"122.155.195.26","port":"8080"}]; module.exports.GetProxy = function () { var randomNum = parseInt(Math.floor(Math.random() * PROXY_LIST.length)); var proxy = PROXY_LIST[randomNum]; return 'http://' + proxy.ip + ':' + proxy.port; }proxylist.js
對app.js程式碼做如下修改
/* * 功能: 資料採集 * 建立人: Wilson * 時間: 2015-07-29 */ var request = require('request'), cheerio = require('cheerio'), URL_36KR = 'http://36kr.com/', //36氪 Proxy = require('./proxylist.js'); ... /* 資料請求 */ function dataRequest(dataUrl) { request({ url: dataUrl, proxy: Proxy.GetProxy(), method: 'GET' }, function(err, res, body) { ... } } ... dataCollectorStartup() setInterval(dataCollectorStartup, 10000);
這樣就改造完成,加入程式碼,並且加了setInterval進行定間隔執行!
請求https
上面示例中採集http請求,如果換成https呢?
新建app2.js,程式碼如下
/* * 功能: 請求HTTPS * 建立人: Wilson * 時間: 2015-07-29 */ var request = require('request'), URL_INTERFACELIFE = 'https://interfacelift.com/wallpaper/downloads/date/wide_16:10/'; /* 開啟資料採集器 */ function dataCollectorStartup() { dataRequest(URL_INTERFACELIFE); } /* 資料請求 */ function dataRequest(dataUrl) { request({ url: dataUrl, method: 'GET' }, function(err, res, body) { if (err) { console.log(dataUrl) console.error('[ERROR]Collection' + err); return; } console.info(body); }); } dataCollectorStartup();
執行會發現返回body中什麼也沒有^_^!
加入一些程式碼再看看
/* * 功能: 請求HTTPS * 建立人: Wilson * 時間: 2015-07-29 */ var request = require('request'), URL_INTERFACELIFE = 'https://interfacelift.com/wallpaper/downloads/date/wide_16:10/'; /* 開啟資料採集器 */ ... /* 資料請求 */ function dataRequest(dataUrl) { request({ url: dataUrl, method: 'GET', headers: { 'User-Agent': 'wilson' } }, function(err, res, body) { if (err) { console.log(dataUrl) console.error('[ERROR]Collection' + err); return; } console.info(body); }); } ...
再執行,你會發現body中返回請求的HTML!(結果就不放上來了,自已執行一下!)
寫在之後
離上一篇快半年了^_^! 最近有計劃寫幾篇操作型別的,不講原理也不通講API,只講例項!
request庫我還是推薦API可以多看看,比如Forms部分我就在實際專案測試中用的比較多!
比如做介面測試:
1.提交兩個引數(引數1:字串 引數2:數字)
request.post({url:'介面URL',form: {引數一名稱:'引數一值',引數二名稱:引數二值},function(err,res,body){ if(err) { return; } console.log(body); });
body就是介面返回
2.提交一個字串引數,提交一個檔案引數(比如上傳頭像等)
var r = request.post('介面URL',function(err,res,body){ if(err) { return; } console.log(body); }); var form = r.form(); form.append('引數一名稱', '引數一值'); form.append('引數二名稱', fs.createReadStream('1.jpg'), {filename: '1.jpg'});
cheerio庫真沒什麼好講的,會jquery就行,它庫的api基本都不用看!
相關推薦
Nodejs學習筆記(十一)--- 資料採集器示例(request和cheerio)
目錄 寫在之前 很多人都有做資料採集的需求,用不同的語言,不同的方式都能實現,我以前也用C#寫過,主要還是傳送各類請求和正則解析資料比較繁瑣些,總體來說沒啥不好的,就是效率要差一些, 用nodejs寫採集程式還是比較有效率(可能也只是相對C#來說),今天主要用一個示例來說一下使用node
Nodejs學習筆記(十一)—數據采集器示例(request和cheerio)
列表 意思 9.1 很多 AD 開發 com http undefined 寫在之前 很多人都有做數據采集的需求,用不同的語言,不同的方式都能實現,我以前也用C#寫過,主要還是發送各類請求和正則解析數據比較繁瑣些,總體來說沒啥不好的,就是效率要差一些, 用nodej
python學習筆記第十一節(叠代和其他)
技術分享 img 余數 商品列表 步長 取數 sorted函數 學習 四舍五入 yiled 面相過程編程 造好內容,統一發給下面 上面這個是傻瓜版 內置函數 print(divmod(10,3)) 將10除以3,顯示商和余數 enumerate函數,顯示元素及它
設計模式C++學習筆記之十一(c/c++面試筆試題)
一、指標與引用有什麼區別? 1、指標會佔用記憶體,引用不佔用記憶體。 2、引用在定義時必須初始化。 3、沒有空的引用,但是有空的指標。 二、static關鍵的幾個作用 1、函式體內的static變數的作用範圍為該函式體,該變數記憶體只分配一次,因此其值在下次再呼叫該函式時
2018秋招面試問題(十一、資料結構基礎問題)
注:面試過程中整理的學習資料,如有侵權聯絡我即刻刪除。 目錄 資料結構中連結串列和陣列的異同? 陣列的元素在記憶體中是連續存放的,我們可以通過下標快速訪問到某個元素,而如果要對陣列進行增加或者刪除元素,就要移動大量的元
《SAS編程與數據挖掘商業案例》學習筆記之十一
ror otto -c ace mov 得到 replace 讀書筆記 集中 繼續讀書筆記,本文重點側重sas觀測值的操作方面, 主要包含:輸出觀測值、更新觀測值、刪除觀測值、停止輸出觀測值等
學習筆記第十一節課
作業linux和windows互傳文件 互傳文件 先安裝一個工具 yum install -y lrzsz 使用sz命令 就可以把linux上的文件傳到windows上去。 rz 就可以把windows上的東西傳到linux上 (當前目錄) 前提是用 xshell securecrt putty是
學習筆記第二十一節課
作業yum更換國內源 有時候自帶的yum源,不好用,因為自帶的裏面的網址資源是國外的。從國內下載很慢。 想辦法更改國內的源。 實驗: 先把dvd給刪除了, 然後把之前刪除的給cp回來。 然後刪除 CentOS-Base.repo 改一個CentOS7-Base-163.repo 新的需要去下載,寫入下載
Java學習筆記二十一:Java面向對象的三大特性之繼承
類構造 接下來 多重 通過 prot 圖片 等級 ++ class Java面向對象的三大特性之繼承 一:繼承的概念; 繼承是java面向對象編程技術的一塊基石,因為它允許創建分等級層次的類。 繼承就是子類繼承父類的特征和行為,使得子類對象(實例)具有父
深度學習花書學習筆記 第十一章 實踐方法論
效能度量 根據任務需求,需要有不同的效能度量方式,常規度量方式如下: _ 真 假 認為真 true positive(TP) false positive(FP)
kubernetes學習筆記之十一:kubernetes dashboard認證及分級授權
第一章、部署dashboard 作為Kubernetes的Web使用者介面,使用者可以通過Dashboard在Kubernetes叢集中部署容器化的應用,對應用進行問題處理和管理,並對叢集本身進行管理。通過Dashboard,使用者可以檢視叢集中應用的執行情況,同時也能夠基於Dashboard建立或修
【OS學習筆記】十一 真實模式:中斷-軟中斷和硬中斷基本原理
上一篇文章我們模擬作業系統的載入器程式,使用匯編語言實現了一個程式載入器:點選連結檢視上一篇文章:程式載入器的實現原理 本篇文章,是真實模式學習的結尾。在經過了那麼多坎坷,終於學完了8086的真實模式!!!最重要的是本篇文章沒有彙編程式碼,只講原理~~ 今天的內容比較簡單,學習一下中
opencv學習筆記七十一:影象修復
當我們的照片有劃痕或遭到人為的塗鴉(比如馬賽克)時, 如果我們想讓這些遭到破壞的圖片儘可能恢復到原樣,Opencv能幫我們做到嗎?答案是肯定的。 那麼影象修復技術的原理是什麼呢? 簡而言之,就是利用那些已經被破壞的區域的邊緣, 即邊緣的顏色和結構,根據這些影象留下的資訊去
機器學習筆記之十一——整合學習之Boosting及AdaBoosting
上一篇記述了Bagging的思維與應用 : https://blog.csdn.net/qq_35946969/article/details/85045432 本篇記錄Boosting的思想與應用:AdaBoosting、GDBT(
Maven 學習筆記二十一:Maven倉庫(快照版本)
Maven倉庫(快照版本) ---------- 在Maven的世界中,任何一個專案或者構件都必須有自己的版本。版本的值可能是1.0.0,1.3-alpha-4,2.0,2.1-SNAPSHOT或者2.1-20091214.221414-13。其中,1.0、1.3-a
Java Web 學習筆記之十一:RestEasy統一處理異常
JBoss RestEasy框架配置異常統一處理 前提 利用JBoss restEasy框架搭建的restful java web後臺應用 希望通過統一的方式對restful介面丟擲的異常進行
Oracle學習筆記第十一天
Oracle學習筆記第十一天 備份和恢復和遷移 這活按我猜想應該是DBA的活,沒有往這方面發展的想法,所以筆記做得簡單點了… 概念: 備份 備份就是把資料庫複製到轉儲裝置的過程 恢復 恢復就是把資料庫由存在故障的狀態轉變為無故障狀態的過程 --
【PMP】Head First PMP 學習筆記 第十一章 風險管理
第十一章 風險管理 計劃再仔細的專案也會遇到麻煩。 什麼是風險 風險是任何可能影響專案的不確定時間或狀況,但並非所有風險都是負面的 風險(risk) 事件(event) 狀況(condition) 機會(opporunity) 風險偏好。為了預期的回
pytorch學習筆記(二十一): 使用 pack_padded_sequence
在使用 pytorch 的 RNN 模組的時候, 有時會不可避免的使用到 pack_padded_sequence 和 pad_packed_sequence, 當使用雙向RNN的時候, 必須要使用 pack_padded_sequence !! .否則的話,
EF6學習筆記二十一:格式化日誌輸出
exec https edi 進行 mman sel 能夠 database container 要專業系統地學習EF推薦《你必須掌握的Entity Framework 6.x與Core 2.0》。這本書作者(汪鵬,Jeffcky)的博客:https://www.cnblo