應(yīng)邀寫一點(diǎn)使用Node.js爬點(diǎn)資料的實(shí)例,對(duì)于大家建站爬一些初始資料或者做分析研究的小伙伴們應(yīng)該有些幫助。
目標(biāo)分析
目標(biāo)地址:http://wcatproject.com/charSearch/
抓取內(nèi)容:抓取所有4星角色的數(shù)值數(shù)據(jù)。如果我們采用手工采集的步驟,需要先進(jìn)入目標(biāo)地址,然后選擇4星角色的選項(xiàng),頁(yè)面下方出現(xiàn)所有4星角色的頭像,依次點(diǎn)擊每個(gè)4星角色頭像后會(huì)出現(xiàn)角色的詳細(xì)頁(yè)面,記錄下詳細(xì)頁(yè)面中數(shù)據(jù)。顯然這樣的做法如果角色一多,手工處理是非常吃力的,所以我們就需要一個(gè)自動(dòng)的腳本去完成這樣的動(dòng)作。大家不妨先手工試試這樣的訪問步驟,有助于后面的分析和實(shí)踐。
頁(yè)面分析:
- 進(jìn)入http://wcatproject.com/charSearch/
- 打開Chrome的“開發(fā)者工具”,選擇“Network”標(biāo)簽。點(diǎn)亮“Record Network Log”按鈕
-
第一步頁(yè)面操作:在頁(yè)面中“星數(shù)”選擇“4”,查詢出所有4星角色,觀察Network中記錄的請(qǐng)求信息??梢钥吹揭粋€(gè)名為“getData.php”的請(qǐng)求,如圖所示:alt=getData請(qǐng)求查看
- getData.php中的重要信息記錄(通過nodejs發(fā)起請(qǐng)求時(shí)候需要)
4.1Request URL我們需要調(diào)用的請(qǐng)求地址:
http://wcatproject.com/charSearch/function/getData.php
4.2Request Method該請(qǐng)求的類型:POST
4.3Request Header請(qǐng)求的頭信息
4.4Form Data請(qǐng)求的表單信息
4.5Response和Preview中可以看到返回的內(nèi)容和格式化內(nèi)容,可以看到返回的是一個(gè)角色I(xiàn)D和角色名稱的數(shù)組內(nèi)容alt=getData返回內(nèi)容格式
4.6 在“開發(fā)者工具”中選擇“Elements”標(biāo)簽,點(diǎn)擊左上角的放大鏡,將鼠標(biāo)移到下方伙伴的頭像部分點(diǎn)擊鼠標(biāo)左鍵,可以看到這塊的HTML結(jié)構(gòu)??梢钥吹矫總€(gè)角色的鏈接的規(guī)則為char/角色idalt=角色鏈接查看 - 第二部頁(yè)面操作:點(diǎn)擊頁(yè)面下面查詢出的4星角色的頭像,進(jìn)入到角色詳細(xì)頁(yè)面,觀察Network中記錄的請(qǐng)求信息??梢哉业揭粋€(gè)名為“SS0441”的請(qǐng)求,如上步驟,記錄下相關(guān)信息,由于這個(gè)請(qǐng)求的
Request Method為GET,因此沒有Form Data信息。
最后在理一下思路,我們的腳本過程如下:
- 發(fā)起getData.php請(qǐng)求,獲得所有4星角色的ID
- 依次循環(huán)根據(jù)
char/角色id規(guī)則訪問各個(gè)角色的詳細(xì)頁(yè)面,并解析其中需要的數(shù)據(jù)并按我們想要的方式存儲(chǔ)起來
準(zhǔn)備工作
- Node.js環(huán)境搭建
- 一款具有代碼高亮功能文本編輯器,如Sublime Text等
- 使用nvm工具將Node.js版本設(shè)置為5.0.0
創(chuàng)建工程
- 選擇一個(gè)目錄,新建一個(gè)準(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
$
- 此時(shí)文件夾下生成了一個(gè)
package.json文件,其中包含了工程的基本信息以及引用的框架等信息
框架引入
- superagent:發(fā)起http請(qǐng)求
- cheerio:解析http返回的html內(nèi)容
- async:多線程并發(fā)控制
安裝命令 npm install --save PACKAGE_NAME,執(zhí)行以下三條命令后,工程目錄下多了一個(gè)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('爬蟲程序開始運(yùn)行......');
// 第一步,發(fā)起getData請(qǐng)求,獲取所有4星角色的列表
superagent
.post('http://wcatproject.com/charSearch/function/getData.php')
.send({
// 請(qǐng)求的表單信息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 : ['活動(dòng)限定','限定角色','聖誕限定','正月限定','黑貓限定','中川限定','茶熊限定','夏日限定'] })
// Http請(qǐng)求的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){
// 請(qǐng)求返回后的處理
// 將response中返回的結(jié)果轉(zhuǎn)換成JSON對(duì)象
var heroes = JSON.parse(res.text);
// 并發(fā)遍歷heroes對(duì)象
async.mapLimit(heroes, 1,
function (hero, callback) {
// 對(duì)每個(gè)角色對(duì)象的處理邏輯
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ì)頁(yè)面的爬取和解析
superagent
.get('http://wcatproject.com/char/' + heroId)
.end(function(err, res){
// 獲取爬到的角色詳細(xì)頁(yè)面內(nèi)容
var $ = cheerio.load(res.text,{decodeEntities: false});
// 對(duì)頁(yè)面內(nèi)容進(jìn)行解析,以收集隊(duì)長(zhǎng)技能為例
console.log(heroId + '\t' + $('.leader-skill span').last().text())
concurrencyCount--;
callback(null, heroId);
});
};
工程目錄下執(zhí)行命令,node index.js,抓取程序開始執(zhí)行
$ node index.js
爬蟲程序開始運(yùn)行......
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消費(fèi)減少 (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)
同時(shí)也可以放開下面的注釋,來觀察執(zhí)行過程中并發(fā)數(shù)
console.log("...正在抓取"+ heroId + "...當(dāng)前并發(fā)數(shù)記錄:" + concurrencyCount);
如果對(duì)示例有疑問,歡迎留言交流_


