使用Node.js制作爬蟲教程

應(yīng)邀寫一點使用Node.js爬點資料的實例,對于大家建站爬一些初始資料或者做分析研究的小伙伴們應(yīng)該有些幫助。

目標(biāo)分析

目標(biāo)地址:http://wcatproject.com/charSearch/

抓取內(nèi)容:抓取所有4星角色的數(shù)值數(shù)據(jù)。如果我們采用手工采集的步驟,需要先進(jìn)入目標(biāo)地址窜司,然后選擇4星角色的選項,頁面下方出現(xiàn)所有4星角色的頭像锭魔,依次點擊每個4星角色頭像后會出現(xiàn)角色的詳細(xì)頁面例证,記錄下詳細(xì)頁面中數(shù)據(jù)。顯然這樣的做法如果角色一多迷捧,手工處理是非常吃力的织咧,所以我們就需要一個自動的腳本去完成這樣的動作长酗。大家不妨先手工試試這樣的訪問步驟,有助于后面的分析和實踐风范。

頁面分析:

  1. 進(jìn)入http://wcatproject.com/charSearch/
  2. 打開Chrome的“開發(fā)者工具”聚唐,選擇“Network”標(biāo)簽。點亮“Record Network Log”按鈕
  3. 第一步頁面操作:在頁面中“星數(shù)”選擇“4”捅位,查詢出所有4星角色轧葛,觀察Network中記錄的請求信息⊥Р螅可以看到一個名為“getData.php”的請求尿扯,如圖所示:
    alt=getData請求查看
  4. getData.php中的重要信息記錄(通過nodejs發(fā)起請求時候需要)
    4.1 Request URL我們需要調(diào)用的請求地址:
    http://wcatproject.com/charSearch/function/getData.php
    4.2 Request Method該請求的類型:POST
    4.3 Request Header請求的頭信息
    4.4 Form Data請求的表單信息
    4.5 ResponsePreview中可以看到返回的內(nèi)容和格式化內(nèi)容,可以看到返回的是一個角色I(xiàn)D和角色名稱的數(shù)組內(nèi)容
    alt=getData返回內(nèi)容格式

    4.6 在“開發(fā)者工具”中選擇“Elements”標(biāo)簽焰雕,點擊左上角的放大鏡衷笋,將鼠標(biāo)移到下方伙伴的頭像部分點擊鼠標(biāo)左鍵,可以看到這塊的HTML結(jié)構(gòu)矩屁”僮冢可以看到每個角色的鏈接的規(guī)則為char/角色id
    alt=角色鏈接查看
  5. 第二部頁面操作:點擊頁面下面查詢出的4星角色的頭像,進(jìn)入到角色詳細(xì)頁面吝秕,觀察Network中記錄的請求信息泊脐。可以找到一個名為“SS0441”的請求烁峭,如上步驟容客,記錄下相關(guān)信息,由于這個請求的Request Method為GET约郁,因此沒有Form Data信息耘柱。

最后在理一下思路,我們的腳本過程如下:

  1. 發(fā)起getData.php請求棍现,獲得所有4星角色的ID
  2. 依次循環(huán)根據(jù)char/角色id規(guī)則訪問各個角色的詳細(xì)頁面调煎,并解析其中需要的數(shù)據(jù)并按我們想要的方式存儲起來

準(zhǔn)備工作

  • Node.js環(huán)境搭建
  • 一款具有代碼高亮功能文本編輯器,如Sublime Text等
  • 使用nvm工具將Node.js版本設(shè)置為5.0.0

創(chuàng)建工程

  • 選擇一個目錄己肮,新建一個準(zhǔn)備存放工程內(nèi)容的文件夾demo士袄。
  • 打開終端(windows機(jī)器打開CMD命令行),輸入npm init谎僻,根據(jù)提示娄柳,逐步輸入工程信息,具體示例如下
$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg> --save` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
name: (workspace) demo
version: (1.0.0)
description: 爬蟲案例
entry point: (index.js)
test command:
git repository:
keywords:
author: 程序猿DD
license: (ISC)
About to write to /Users/diyongchao/Documents/workspace/package.json:

{
  "name": "demo",
  "version": "1.0.0",
  "description": "爬蟲案例",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "程序猿DD",
  "license": "ISC"
}


Is this ok? (yes) yes
$
  • 此時文件夾下生成了一個package.json文件艘绍,其中包含了工程的基本信息以及引用的框架等信息

框架引入

  • superagent:發(fā)起http請求
  • cheerio:解析http返回的html內(nèi)容
  • async:多線程并發(fā)控制

安裝命令 npm install --save PACKAGE_NAME赤拒,執(zhí)行以下三條命令后,工程目錄下多了一個node_modules目錄,該目錄就是引入的框架內(nèi)容挎挖。

$npm install --save superagent
$npm install --save cheerio
$npm install --save async

編碼過程

工程目錄下这敬,創(chuàng)建index.js

var superagent = require('superagent'); 
var cheerio = require('cheerio');
var async = require('async');

console.log('爬蟲程序開始運行......');

// 第一步,發(fā)起getData請求蕉朵,獲取所有4星角色的列表
superagent
    .post('http://wcatproject.com/charSearch/function/getData.php')
    .send({ 
        // 請求的表單信息Form data
        info: 'isempty', 
        star : [0,0,0,1,0], 
        job : [0,0,0,0,0,0,0,0], 
        type : [0,0,0,0,0,0,0], 
        phase : [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        cate : [0,0,0,0,0,0,0,0,0,0], 
        phases : ['初代', '第一期','第二期','第三期','第四期','第五期','第六期', '第七期','第八期','第九期','第十期','第十一期','第十二期','第十三期','第十四期', '第十五期', '第十六期'],
        cates : ['活動限定','限定角色','聖誕限定','正月限定','黑貓限定','中川限定','茶熊限定','夏日限定'] })
    // Http請求的Header信息
   .set('Accept', 'application/json, text/javascript, */*; q=0.01')
   .set('Content-Type','application/x-www-form-urlencoded; charset=UTF-8')
   .end(function(err, res){         
        // 請求返回后的處理
        // 將response中返回的結(jié)果轉(zhuǎn)換成JSON對象
        var heroes = JSON.parse(res.text);    
        // 并發(fā)遍歷heroes對象
        async.mapLimit(heroes, 1, 
            function (hero, callback) {
            // 對每個角色對象的處理邏輯
                var heroId = hero[0];   // 獲取角色數(shù)據(jù)第一位的數(shù)據(jù)崔涂,即:角色id
                fetchInfo(heroId, callback);
            }, 
            function (err, result) {
                console.log('抓取的角色數(shù):' + heroes.length);
            }
        );

    }); 

// 獲取角色信息
var concurrencyCount = 0; // 當(dāng)前并發(fā)數(shù)記錄
var fetchInfo = function(heroId, callback){
    concurrencyCount++;
    // console.log("...正在抓取"+ heroId + "...當(dāng)前并發(fā)數(shù)記錄:" + concurrencyCount);

    // 根據(jù)角色I(xiàn)D,進(jìn)行詳細(xì)頁面的爬取和解析
    superagent
        .get('http://wcatproject.com/char/' + heroId)
        .end(function(err, res){  
            // 獲取爬到的角色詳細(xì)頁面內(nèi)容
            var $ = cheerio.load(res.text,{decodeEntities: false});                 

            // 對頁面內(nèi)容進(jìn)行解析始衅,以收集隊長技能為例
            console.log(heroId + '\t' + $('.leader-skill span').last().text())

            concurrencyCount--;
            callback(null, heroId);
        });
    
};

工程目錄下執(zhí)行命令冷蚂,node index.js,抓取程序開始執(zhí)行

$ node index.js
爬蟲程序開始運行......
SS0441  平衡型傷害增加 (20%)
NS1641  防禦型的移速增加 (20%)
SS1141  技術(shù)型的技能傷害增加 (20%)
SS1041  攻擊型的SP增加 (15%)
SS0941  攻擊型傷害增加 (20%)
SS0841  劍士減傷 (10%) / 技術(shù)型減傷 (15%)
LS0941  全員傷害增加 (15%)
LS1441  劍士傷害增加 (10%)  /  技術(shù)型傷害增加 (15%)
SS0741  劍士雷屬性傷害增加 (50%)
SS0641  攻擊型傷害增加 (20%)
NS1741  技能型的SP消費減少 (15%)
NS1141  全員傷害增加 (15%)
NS0031-A    獲得的魂增加 (20%)
SS0501  技術(shù)型傷害增加 (20%)
SS0141  劍士傷害增加 (20%)
SS0241  全員傷害增加 (15%)

后記

如果覺得爬的慢汛闸,可以通過修改下面代碼中的1來調(diào)整并發(fā)數(shù)量

async.mapLimit(heroes, 1, function (hero, callback)

同時也可以放開下面的注釋蝙茶,來觀察執(zhí)行過程中并發(fā)數(shù)

console.log("...正在抓取"+ heroId + "...當(dāng)前并發(fā)數(shù)記錄:" + concurrencyCount);

如果對示例有疑問,歡迎留言交流_

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末诸老,一起剝皮案震驚了整個濱河市尸闸,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌孕锄,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,430評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件苞尝,死亡現(xiàn)場離奇詭異畸肆,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)宙址,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,406評論 3 398
  • 文/潘曉璐 我一進(jìn)店門轴脐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人抡砂,你說我怎么就攤上這事大咱。” “怎么了注益?”我有些...
    開封第一講書人閱讀 167,834評論 0 360
  • 文/不壞的土叔 我叫張陵碴巾,是天一觀的道長。 經(jīng)常有香客問我丑搔,道長厦瓢,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,543評論 1 296
  • 正文 為了忘掉前任啤月,我火速辦了婚禮煮仇,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘谎仲。我一直安慰自己浙垫,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,547評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著夹姥,像睡著了一般杉武。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上佃声,一...
    開封第一講書人閱讀 52,196評論 1 308
  • 那天艺智,我揣著相機(jī)與錄音,去河邊找鬼圾亏。 笑死十拣,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的志鹃。 我是一名探鬼主播夭问,決...
    沈念sama閱讀 40,776評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼曹铃!你這毒婦竟也來了缰趋?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,671評論 0 276
  • 序言:老撾萬榮一對情侶失蹤陕见,失蹤者是張志新(化名)和其女友劉穎秘血,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體评甜,經(jīng)...
    沈念sama閱讀 46,221評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡灰粮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,303評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了忍坷。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片粘舟。...
    茶點故事閱讀 40,444評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖佩研,靈堂內(nèi)的尸體忽然破棺而出柑肴,到底是詐尸還是另有隱情,我是刑警寧澤旬薯,帶...
    沈念sama閱讀 36,134評論 5 350
  • 正文 年R本政府宣布晰骑,位于F島的核電站,受9級特大地震影響绊序,放射性物質(zhì)發(fā)生泄漏些侍。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,810評論 3 333
  • 文/蒙蒙 一政模、第九天 我趴在偏房一處隱蔽的房頂上張望岗宣。 院中可真熱鬧,春花似錦淋样、人聲如沸耗式。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,285評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽刊咳。三九已至彪见,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間娱挨,已是汗流浹背余指。 一陣腳步聲響...
    開封第一講書人閱讀 33,399評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留跷坝,地道東北人酵镜。 一個月前我還...
    沈念sama閱讀 48,837評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像柴钻,于是被迫代替她去往敵國和親淮韭。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,455評論 2 359

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