Nodejs爬蟲——機票查詢學(xué)習(xí)筆記(1).md

2017.3.6 - 3.17

學(xué)習(xí)內(nèi)容:

  • 學(xué)習(xí)nodejs數(shù)據(jù)挖掘基本想法
  • 熟悉superagent模塊的基本接口
  • 熟悉cheerio模塊的基本接口
  • 學(xué)習(xí)范例挖掘Cnode首頁信息
  • eventproxy模塊學(xué)習(xí)
  • async模塊學(xué)習(xí)
  • js變量提升
  • 模擬post請求與get請求

詳細筆記:

1. 基本想法

nodejs項目通過superagent模塊包向網(wǎng)站發(fā)起有(或無)參數(shù)的get/post請求抡诞,獲取目標網(wǎng)頁的html源代碼
——>使用cherrio模塊包分析前一步抓取的html世曾,使用方法類似Jquery
——>保存json數(shù)據(jù)到文本

2. superagent模塊接口整理

參考文獻:superagent文檔 整理稿
一個用于發(fā)起get/post請求的https模塊包

3. cherrio模塊接口整理

一個用于抓取當(dāng)前頁面信息的模塊包

4. 簡單抓取頁面信息的核心代碼 ——————挖掘Cnode首頁
//通過get請求抓取
router.get('/', function(req, res, next) {
    superAgent.get('https://cnodejs.org/')
      .end(function (err, sres) {
        if(err){
          return next(err);
        }
        // sres.text 里面存儲著網(wǎng)頁的 html 內(nèi)容堂竟,將它傳給 cheerio.load 之后
        // 就可以得到一個實現(xiàn)了 jquery 接口的變量叙谨,我們習(xí)慣性地將它命名為 `$`
        var $ = cherrio.load(sres.text);
        var items = [];
        $('#topic_list .topic_title').each(function (idx, element) {
          // 對每一個查找到的結(jié)果(idx, element),存入items數(shù)組?中
          var $element = $(element);
          items.push({
                  title: $element.attr('title'),
                  href: $element.attr('href'),
                });
        });
        res.send(items);
      })
});  
5. js變量聲明提升,賦值不提升

參考博客:js中的變量提升hoisting
總結(jié):
JavaScript是函數(shù)級作用域(function-level scope)。只有在函數(shù)中才會創(chuàng)建新的作用域(適用局部變量)。

// 初始代碼
var v='Hello World';
(function(){
    alert(v);
    var v='I love you';
})()
// 運行結(jié)果  : 彈出 undefined
// 實際運行過程
var v='Hello World';
(function(){
    var v;              //變量聲明被提升
    alert(v);
    v='I love you';     //變量賦值未提升
})()
//對于函數(shù)級作用域的理解
function foo() {
    var x = 1;
    if (x) {
        (function () {
            var x = 2;
            // some other code
        }());
    }
    // x is still 1.     //匿名函數(shù)中的作用域與foo函數(shù)的作用域無關(guān)
}
6. eventproxy模塊包API整理

一個用于監(jiān)聽多個函數(shù)并發(fā)執(zhí)行的模塊報(類似于計數(shù)器,等所有監(jiān)聽事件都冒泡表示完成袜茧,在執(zhí)行callback)
eventproxy——API

  • 注冊單個異步并發(fā):
    ep.all('tpl', 'data', function (tpl, data) {})
    所有監(jiān)聽事件完成后觸發(fā)callback

  • 注冊重復(fù)異步并發(fā):
    ep.after('got_file', files.length, function (list) {})
    監(jiān)聽事件重復(fù)指定次數(shù)后,觸發(fā)callback

  • 注冊持續(xù)異步并發(fā):
    ep.tail('tpl', 'data', function (tpl, data) {})
    在所有監(jiān)聽事件執(zhí)行后瓣窄,觸發(fā)callback笛厦;監(jiān)聽事件再次更新,仍然觸發(fā)callback

7. async模塊API整理
  • 流程控制:簡化十種常見流程的處理
    --- series(tasks, [callback]) (多個函數(shù)依次執(zhí)行俺夕,之間沒有數(shù)據(jù)交換)
    有多個異步函數(shù)需要依次調(diào)用裳凸,一個完成之后才能執(zhí)行下一個。各函數(shù)之間沒有數(shù)據(jù)的交換劝贸,僅僅需要保證其執(zhí)行順序姨谷。
    --- parallel(tasks, [callback]) (多個函數(shù)并行執(zhí)行)
    并行執(zhí)行多個函數(shù),每個函數(shù)都是立即執(zhí)行映九,不需要等待其它函數(shù)先執(zhí)行梦湘。傳給最終callback的數(shù)組中的數(shù)據(jù)按照tasks中聲明的順序,而不是執(zhí)行完成的順序件甥。
    如果某個函數(shù)出錯捌议,則立刻將err和已經(jīng)執(zhí)行完的函數(shù)的結(jié)果值傳給parallel最終的callback。其它未執(zhí)行完的函數(shù)的值不會傳到最終數(shù)據(jù)引有,但要占個位置瓣颅。
    --- waterfall(tasks, [callback]) (多個函數(shù)依次執(zhí)行,且前一個的輸出為后一個的輸入)
    與seires相似譬正,按順序依次執(zhí)行多個函數(shù)弄捕。不同之處,每一個函數(shù)產(chǎn)生的值导帝,都將傳給下一個函數(shù)。如果中途出錯穿铆,后面的函數(shù)將不會被執(zhí)行您单。錯誤信息以及之前產(chǎn)生的結(jié)果,將傳給waterfall最終的callback荞雏。

  • 集合處理:如何使用異步操作處理集合中的數(shù)據(jù)
    forEach:對集合中每個元素進行異步操作
    map:對集合中的每個元素通過異步操作得到另一個值虐秦,得到新的集合
    filter:對集合中元素使用異步操作進行篩選平酿,得到符合條件的集合
    reject:與filter相似,只是判斷條件時正好相反悦陋,得到剩下的元素的集合
    reduce:使用一個初始值同集合中每一個元素進行異步操作蜈彼,最后得到一個唯一的結(jié)果
    detect:得到集合中滿足條件的第一個數(shù)據(jù)
    sortBy:對集合中的數(shù)據(jù)進行異步操作,再根據(jù)值從小到大排序
    some/any:集合中是否有至少一個元素滿足條件
    every/all:集合中是否每個元素都滿足條件
    concat:對集合中的元素進行異步操作俺驶,將結(jié)果集合并成一個數(shù)組

  • 工具類:幾個常用的工具類

8. 定時抓取補充

https://github.com/node-schedule/node-schedule

9. jqury的API

$.map() 遍歷
$.trim() 字符串去首位的空格

10. 爬蟲相關(guān)的模塊介紹

爬蟲相關(guān)模塊
express框架詳細總結(jié)

11. 模擬post請求與get請求 規(guī)范整理
//模擬發(fā)起get請求
superAgent.get('http://flight.qunar.com/twell/flight/inter/search')
    .query(queryString)
    .set(headers)
    .end(function (err, res) {
        if (res.error)
            throw new Error(res.error);
        console.log(res.body);
    });

****在get請求中需要注意的地方:****  
1. 在chrome檢查——network——headers中查到看的request URL要去除查詢參數(shù)(?search/departCity=XXXXX等)  
2. 在.query中發(fā)送查詢參數(shù)幸逆,對應(yīng)的post方法則是用send(data)的方式發(fā)送參數(shù)  
//模擬發(fā)起post請求
superAgent.post('http://flights.ctrip.com/international/AjaxRequest/SearchFlights/AsyncSearchHandlerSOAII.ashx')
    .set(ctripHeaders)
    .type('form')
    .send(data)
    .end(function (err, res) {
        // res是json對象
        if (err){
            return console.error(err);
        }
        console.dir(res.body);
    })

****在post請求中的注意:****
1. 在chrome檢查——network中找準發(fā)起請求的URL,并且保證req的參數(shù)完整且正確  
2. 在發(fā)送數(shù)據(jù)前通過.type('form') 聲明發(fā)送數(shù)據(jù)的格式  
3. 注意返回數(shù)據(jù)的解析

json文件讀寫
sublime中的json格式化插件—— pretty json

遇到的問題

Q1:一個json數(shù)組在debug時暮现,可以取到其中的值还绘,但是在實際運行中,出現(xiàn)Cannot read property 'href' of undefined
A1:- id重復(fù)栖袋,找不到dom或找錯dom

  • 數(shù)組越界拍顷,導(dǎo)致在debug時的前幾輪循環(huán)中可取,在整體運行中出錯塘幅。
  • 重點理解nodejs的異步機制昔案!需要在回調(diào)函數(shù)中操作dom,以防還未捕捉到dom
    —————————
    Q2:get請求抓取信息的數(shù)據(jù)結(jié)構(gòu)失敗
    A2:出于安全保密电媳,攜程網(wǎng)頁的數(shù)據(jù)信息由post請求得到踏揣,因此僅僅通過get請求無法得到目標html,需要在當(dāng)前網(wǎng)頁發(fā)起post請求
    參考鏈接

總結(jié):

  1. 通過一周學(xué)習(xí)匆背,再次理解了上一學(xué)期中易混淆未理解“異步調(diào)用”呼伸、“get/post請求”的概念
    異步調(diào)用,依次開啟多個函數(shù)入口钝尸,并發(fā)執(zhí)行括享,返回結(jié)果順序與入口執(zhí)行順序不一定相同,可以使用async模塊包來控制異步與同步的切換珍促。
    get請求:通過添加url中的查詢參數(shù)铃辖,向當(dāng)前網(wǎng)頁發(fā)出get請求,獲得返回數(shù)據(jù)猪叙,不具備保密性娇斩。相當(dāng)于得到了帶參數(shù)的url完整路徑,就得到了這個網(wǎng)頁的數(shù)據(jù)穴翩。
    post請求:通過某個動作(如搜索按鈕犬第、提交按鈕)向服務(wù)器后臺發(fā)送數(shù)據(jù)包,再收獲相應(yīng)數(shù)據(jù)芒帕,將得到的數(shù)據(jù)渲染到當(dāng)前頁面歉嗓,動態(tài)生成頁面,如果截取到當(dāng)前網(wǎng)頁的url只能獲得一個空的HTML頁面框架背蟆,不具備有價值的數(shù)據(jù)鉴分。
  1. 對于新工具的學(xué)習(xí)使用能力還要加強
    這一次的模擬請求哮幢,用到了postman這個軟件+插件進行網(wǎng)頁抓包(抓取客戶端向服務(wù)器發(fā)出的請求數(shù)據(jù)包,與服務(wù)器返回的響應(yīng)數(shù)據(jù)包)與發(fā)包測試(模擬發(fā)出get/post請求)志珍,在初次使用中因不太理解請求原理+不熟悉使用方法橙垢,導(dǎo)致在盲目測試請求時浪費了很多時間。
  2. 爬蟲與反爬蟲:通過對反爬蟲的了解伦糯,反面思考爬蟲的設(shè)計思路
    現(xiàn)在主流的幾個反爬蟲技術(shù):
    1柜某、限制查詢頻率,超過一定頻率舔株,采取封號莺琳、封IP
    2、通過圖片驗證碼等技術(shù)識別機器查詢與手工查詢
    3载慈、設(shè)計cookie值與cookie值的隨機有效domain
    4惭等、加密查詢的參數(shù)
    因此通過爬去攜程與去哪兒,了解了兩家的反爬蟲核心:
    攜程
    通過post請求傳輸參數(shù)办铡,發(fā)送的參數(shù)中包含"transNo"與"searchKey"兩個參數(shù)辞做,均為隨機加密參數(shù),每次查詢均獨立加密
攜程的查詢參數(shù)

去哪兒
通過get請求傳輸參數(shù)寡具,查詢參數(shù)中包含"es"隨機參數(shù)秤茅,每一次查詢都會產(chǎn)生不同的es參數(shù)。
因為缺少這兩個加密參數(shù)童叠,無法獲取加密規(guī)則框喳,使得我們無法爬取攜程與去哪兒兩大門戶的機票信息,嗨呀真是太氣了……

去哪兒的查詢參數(shù)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末厦坛,一起剝皮案震驚了整個濱河市五垮,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌杜秸,老刑警劉巖放仗,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異撬碟,居然都是意外死亡诞挨,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門呢蛤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來惶傻,“玉大人,你說我怎么就攤上這事其障〈锫蓿” “怎么了?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長粮揉。 經(jīng)常有香客問我,道長抚笔,這世上最難降的妖魔是什么扶认? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮殊橙,結(jié)果婚禮上辐宾,老公的妹妹穿的比我還像新娘。我一直安慰自己膨蛮,他們只是感情好叠纹,可當(dāng)我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著敞葛,像睡著了一般誉察。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上惹谐,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天持偏,我揣著相機與錄音,去河邊找鬼氨肌。 笑死鸿秆,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的怎囚。 我是一名探鬼主播卿叽,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼恳守!你這毒婦竟也來了考婴?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤井誉,失蹤者是張志新(化名)和其女友劉穎蕉扮,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體颗圣,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡喳钟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了在岂。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片奔则。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖蔽午,靈堂內(nèi)的尸體忽然破棺而出易茬,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布抽莱,位于F島的核電站范抓,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏食铐。R本人自食惡果不足惜匕垫,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望虐呻。 院中可真熱鬧象泵,春花似錦、人聲如沸斟叼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽朗涩。三九已至忽孽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間馋缅,已是汗流浹背扒腕。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留萤悴,地道東北人瘾腰。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像覆履,于是被迫代替她去往敵國和親蹋盆。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,700評論 2 354

推薦閱讀更多精彩內(nèi)容