什么是爬蟲
這里所說的爬蟲是指通過程序腳本將互聯(lián)網(wǎng)上的網(wǎng)站信息下載到本地决瞳,然后提取需要的數(shù)據(jù)信息搂誉。其原理可以參照https://www.cnblogs.com/xingzc/p/5986464.html芦拿。
準(zhǔn)備工具
node環(huán)境支示,cheerio(主要是解析下載的網(wǎng)頁可以像jquery一樣騷操作,必備暇矫,使用也很簡(jiǎn)單可以上npm上查看文檔)主之。iconv-lite(主要解決下載的資源亂碼問題)。正則表達(dá)式(如果是接口數(shù)據(jù)的話有些關(guān)鍵參數(shù)是在script中李根,需要通過正則提取出來)
大概的爬去代碼如下
const cheerio = require('cheerio');
const http = require('http');
const iconv = require('iconv-lite');
// 如果是https協(xié)議的網(wǎng)站槽奕,這里改用https就可以了
// 請(qǐng)求頭最好設(shè)置為user-agent,不然有的網(wǎng)站爬不到朱巨,做了限制爬蟲爬取網(wǎng)頁
const options = {
url: 'http://xxxxx',
header: {
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.'
}
}
http.get(options, function(res) {
const chunks = [];
res.on('data', function(chunk) {
chunks.push(chunk);
});
res.on('end', function() {
//查看網(wǎng)頁源代碼編碼方式史翘,設(shè)置對(duì)應(yīng)的編碼格式
const html = iconv.decode(Buffer.concat(chunks), 'gb2312');
//html就是下載到的資源了,
console.log(html);
const $ = cheerio.load(html);
//接下來就是對(duì)數(shù)據(jù)的處理了冀续,jquery怎樣操作琼讽,你就怎么操作
});
爬取接口數(shù)據(jù),源碼中找加密線索
這段代碼基本上能爬很多網(wǎng)頁了洪唐。那么有些網(wǎng)頁數(shù)據(jù)其實(shí)是在通過ajax拉取數(shù)據(jù)在渲染頁面的钻蹬。比如看下https://www.newrank.cn/public/info/list.html?period=day&type=data這個(gè)網(wǎng)頁我們爬去新榜數(shù)據(jù)的時(shí)候
這里的數(shù)據(jù)就是通過接口獲取。所有我們需要分析接口凭需。
首先分析以下接口是使用post方式提交數(shù)據(jù)问欠,所有這里可以使用request或者h(yuǎn)ttp.post都可以×r冢看一下參數(shù)主要是nonce和xyz這兩個(gè)字段是屬于一種加密都方式顺献,所以我們需要獲取它的加密方式。那么我們就得去源代碼中找信息了枯怖。通過chrome的調(diào)試工具我們到source下找源代碼
因?yàn)榇a混淆過注整,但是像這種傳輸字段是不會(huì)被混淆的。首先把代碼展開然后ctrl + f 在該js文件中搜索關(guān)鍵字段nonce度硝。找到了之后打上一個(gè)斷點(diǎn)肿轨,刷新瀏覽器看是否會(huì)執(zhí)行到這個(gè)驗(yàn)證我們到猜測(cè)。
從上圖可以看到蕊程,確實(shí)是如我們所想椒袍,那兩個(gè)加密字段就是在這里生成的。我們只需要找到對(duì)應(yīng)的算法函數(shù)拷貝到本地藻茂,然后在每次請(qǐng)求到時(shí)候生成對(duì)應(yīng)到加密密碼驹暑,這樣在該網(wǎng)站服務(wù)器上就能正確到解析到了玫恳。
這里的技巧就是根據(jù)關(guān)鍵信息,到源碼(chrome瀏覽器是在source調(diào)試tab下)中找線索优俘,因?yàn)橹灰窃谇岸说綎|西纽窟,都是透明的。還有就是斷點(diǎn)的方式兼吓,讓你更快的找到線索。
爬蟲數(shù)據(jù)來自Jsonp
數(shù)據(jù)可能不止是網(wǎng)頁那么簡(jiǎn)單森枪。當(dāng)數(shù)據(jù)通過Jsonp傳輸?shù)臅r(shí)候视搏,遇到這種情況下使用eval就可以解決。Jsonp是通過script標(biāo)簽加載一段js腳本县袱,這個(gè)腳本會(huì)有一個(gè)函數(shù)浑娜,當(dāng)加載完之后就會(huì)執(zhí)行里面的腳本。一般會(huì)在請(qǐng)求路徑中加一個(gè)callback參數(shù)式散,這個(gè)值就是加載腳本中定義的函數(shù)名筋遭。![這個(gè)是騰訊網(wǎng)首頁一個(gè)jsonp”┲簦可以看出js腳本中定義了一個(gè)方法漓滔,參數(shù)是一個(gè)數(shù)組。那么如果在爬蟲中我們要怎樣取獲取這個(gè)數(shù)組呢乖篷?
const options = {
url: 'https://dp3.qq.com/dynamic?get_type=cm&ch=www&callback=crystal.cookieMapping',
header: {
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.'
}
}
https.get(options, function(res) {
const chunks = [];
res.on('data', function(chunk) {
chunks.push(chunk);
});
res.on('end', function() {
const jsonP = iconv.decode(Buffer.concat(chunks));
const crystal = {
cookieMapping (arr) {
return arr
}
}
// 必須定義對(duì)象crystal和方法cookieMapping响驴,否則下面執(zhí)行eval會(huì)報(bào)錯(cuò)。
// 如果是一些動(dòng)態(tài)的callback 可以這樣
// function jqx(obj) {
// return obj
// }
// url: 'https://dp3.qq.com/dynamic?get_type=cm&ch=www&callback=jqx',
// 總之callback的值一定要先定義
//
const data = eval(jsonP); //這里就拿到了數(shù)組[{"id":"13","url":"http://cm.l.qq.com/?Bid=5bdbc925ad7403a84d1459393b1ddc05"},{"id":"14","url":"http://cm.l.qq.com/?Bid=dca6ea17cca2289887e097157db2998a"},{"id":"15","url":"http://cm.l.qq.com/?Bid=05d485d64761beaacc678aeefb1269fb"}]
});
爬蟲是一個(gè)很好玩的編程撕蔼,小伙伴們可以自行研究研究豁鲤。