目錄
- python爬蟲--爬取網(wǎng)易云音樂評論
- 1.簡易看出評論是動態(tài)加載的,一定是ajax方式。
- 2.通過網(wǎng)絡(luò)抓包,可以找出評論請求的的URL
- 3.去查看post請求所上傳的數(shù)據(jù)
- 4.首先去查看請求是經(jīng)過那些js到達(dá)服務(wù)器的
- 5.設(shè)置斷點(diǎn):依次對所發(fā)送的內(nèi)容進(jìn)行觀察,找到評論對應(yīng)的URL
- 6.查找加密函數(shù)
- 7.解讀加密函數(shù)
- 8.參數(shù)如何獲得:
- 9.這時只需找到某一個i以及它對應(yīng)的encSecKey 即可完成服務(wù)器的驗(yàn)證
python爬蟲--爬取網(wǎng)易云音樂評論
方1:使用selenium模塊,簡單粗暴。但是雖然方便但是缺點(diǎn)也是很明顯,運(yùn)行慢等等等。
方2:常規(guī)思路:直接去請求服務(wù)器
1.簡易看出評論是動態(tài)加載的,一定是ajax方式。
2.通過網(wǎng)絡(luò)抓包,可以找出評論請求的的URL
得到請求的URL
3.去查看post請求所上傳的數(shù)據(jù)
顯然是經(jīng)過加密的,現(xiàn)在就需要按著網(wǎng)易的思路去解讀加密過程,然后進(jìn)行模擬加密。
4.首先去查看請求是經(jīng)過那些js到達(dá)服務(wù)器的
5.設(shè)置斷點(diǎn):依次對所發(fā)送的內(nèi)容進(jìn)行觀察,找到評論對應(yīng)的URL
6.查找加密函數(shù)
(忽略查找過程)找到:加密函數(shù)在
通過查找,找到加密函數(shù)具體位置:
7.解讀加密函數(shù)
運(yùn)用的是AES,模式是:CBC
function a(a) { a=16
var d, e, b = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", c = "";
for (d = 0; a > d; d += 1)
e = Math.random() * b.length, #生成隨機(jī)數(shù)
e = Math.floor(e), #取整
c += b.charAt(e); #取出b中對應(yīng)位置的字符
return c
}
function b(a, b) {
var c = CryptoJS.enc.Utf8.parse(b)
, d = CryptoJS.enc.Utf8.parse("0102030405060708")
, e = CryptoJS.enc.Utf8.parse(a) #e是數(shù)據(jù)
, f = CryptoJS.AES.encrypt(e, c, { #c就是加密密鑰
iv: d, #iv是偏移量
mode: CryptoJS.mode.CBC # 模式:CBC加密
});
return f.toString()
}
function c(a, b, c) {
var d, e;
return setMaxDigits(131),
d = new RSAKeyPair(b,"",c),
e = encryptedString(d, a)
}
function d(d, e, f, g) { d:數(shù)據(jù)json串 e:"010001" f: g = "0CoJUm6Qyw8W8jud"
var h = {}
, i = a(16); #16位隨機(jī)值
return h.encText = b(d, g), g是密鑰
h.encText = b(h.encText, i), #返回的就是params i是密鑰
h.encSecKey = c(i, e, f), #返回的是encSecKey e和f定死,能產(chǎn)生變數(shù)的只能是i
h
function e(a, b, d, e) {
var f = {};
return f.encText = c(a + e, b, d),
f
}
window.asrsea = d
解讀該過程即可:代碼有注釋。
8.參數(shù)如何獲得:
function d(d, e, f, g) { d:數(shù)據(jù)json串 e:"010001" f: g = "0CoJUm6Qyw8W8jud"
var bZe2x = window.asrsea(JSON.stringify(i4m), brx6r(["流淚", "強(qiáng)"]), brx6r(Sc1x.md), brx6r(["愛心", "女孩", "驚恐", "大笑"]));
#使用網(wǎng)頁控制臺:發(fā)現(xiàn)都為定值;
9.這時只需找到某一個i以及它對應(yīng)的encSecKey 即可完成服務(wù)器的驗(yàn)證
拿到該值之后開始編寫代碼
全部代碼粘貼
#1.找到未加密的參數(shù) #通過函數(shù)window.asrsea()進(jìn)行加密
#2.想辦法把參數(shù)進(jìn)行加密,params--->encText encSecKey--->encSecKey
from Cryptodome.Cipher import AES
from base64 import b64encode
import requests,json
e = "010001"
f = "00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7"
g = "0CoJUm6Qyw8W8jud"
i = "0hyFaCNAVzOIdoht"
url = 'https://music.163.com/weapi/comment/resource/comments/get?csrf_token='
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36'
}
def get_encSecKey():
return "4022359ea3110bcd034e0160c3b89e5e172fd0110a3cf765d9f366d9fd09840a1f4a4705ac43719fdb8bfeb44d3b92334733061ad10942131184a4dfba0ac9d2cf867b8b6236523c1ca5f44c0d2d82c1c2665a3137a9241c7373539c1aa8e5e9bb9d33dafc764b5d76c2ab34fc94df85e27a934c8a603fa713f2cf38c2b7bbae"
def get_params(data): #data默認(rèn)是json字符串
first = enc_params(data,g)
second = enc_params(first,i)
return second
def to_16(data):
pad = 16-len(data)%16
data +=chr(pad) * pad
return data
def enc_params(data,key): #加密過程
iv = "0102030405060708"
data = to_16(data)
aes = AES.new(key=key.encode('utf-8'),IV=iv.encode('utf-8'),mode=AES.MODE_CBC) #創(chuàng)建加密器
bs = aes.encrypt(data.encode('utf-8')) #加密
return str(b64encode(bs),"utf-8") #轉(zhuǎn)化成字符串
#處理加密過程
'''
function a(a) { a=16
var d, e, b = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", c = "";
for (d = 0; a > d; d += 1)
e = Math.random() * b.length, #生成隨機(jī)數(shù)
e = Math.floor(e), #取整
c += b.charAt(e); #取出b中對應(yīng)位置的字符
return c
}
function b(a, b) {
var c = CryptoJS.enc.Utf8.parse(b)
, d = CryptoJS.enc.Utf8.parse("0102030405060708")
, e = CryptoJS.enc.Utf8.parse(a) #e是數(shù)據(jù)
, f = CryptoJS.AES.encrypt(e, c, { #c就是加密密鑰
iv: d, #iv是偏移量
mode: CryptoJS.mode.CBC # 模式:CBC加密
});
return f.toString()
}
function c(a, b, c) {
var d, e;
return setMaxDigits(131),
d = new RSAKeyPair(b,"",c),
e = encryptedString(d, a)
}
function d(d, e, f, g) { d:數(shù)據(jù)json串 e:"010001" f: g = "0CoJUm6Qyw8W8jud"
var h = {}
, i = a(16); #16位隨機(jī)值
return h.encText = b(d, g), g是密鑰
h.encText = b(h.encText, i), #返回的就是params i是密鑰
h.encSecKey = c(i, e, f), #返回的是encSecKey e和f定死,能產(chǎn)生變數(shù)的只能是i
h
}'''
if __name__ == '__main__':
page = int(input('請輸入需要爬取的頁數(shù):'))
print('開始爬蟲!?。?)
fp = open('./網(wǎng)易云評論.txt', 'w', encoding='utf-8')
for j in range(1,page+1):
page_num = str(j*20)
data = {
'csrf_token': "",
'cursor': "-1",
'offset': "0",
'orderType': "1",
'pageNo': "1",
'pageSize': page_num,
'rid': "R_SO_4_1376142151",
'threadId': "R_SO_4_1376142151"
}
response = requests.post(url,data={
"params":get_params(json.dumps(data)),
"encSecKey":get_encSecKey()
},headers=headers)
result = json.loads(response.content.decode('utf-8'))
#hotComments
for hot in range(len(result['data']['hotComments'])):
fp.write('hotComments' + ' ')
fp.write('昵稱:' + result['data']['hotComments'][hot]['user']['nickname'] + '\n')
fp.write('評論:' + result['data']['hotComments'][hot]['content'] + '\n')
if result['data']['hotComments'][hot]['user']['vipRights'] == None:
fp.write('vip:yes' + '\n')
else:
fp.write('vip:no' + '\n')
fp.write('點(diǎn)贊數(shù)' + str(result['data']['hotComments'][hot]['likedCount']) + '\n')
fp.write('-------------------------------------' + '\n')
#print(result['data']['hotComments'][1]['user']['nickname'])
#comments
for r in range(20):
fp.write('comments')
fp.write('昵稱:'+result['data']['comments'][r]['user']['nickname']+'\n')
fp.write('評論:'+result['data']['comments'][r]['content']+'\n')
if result['data']['comments'][r]['user']['vipRights'] == None:
fp.write('vip:yes'+'\n')
else:
fp.write('vip:no'+'\n')
fp.write('點(diǎn)贊數(shù)'+str(result['data']['comments'][r]['likedCount'])+'\n')
fp.write('-------------------------------------'+'\n')
print('爬取完畢?。。?)
效果圖
通過這次爬蟲實(shí)驗(yàn),在爬取的過程中,遇到各種困難,收貨很多。掌握遇到加密,該如何處理的步驟,以及拓寬自己的思路,去運(yùn)用各種工具。以及各種自己想不到的思路。最起碼,下次遇到如此加密的數(shù)據(jù)獲取,心里有了一些底氣。
也了解了大互聯(lián)網(wǎng)公司對數(shù)據(jù)進(jìn)行加密的一種方式,以及網(wǎng)頁運(yùn)作的更深一步的了解,受益頗多。
到此這篇關(guān)于如何用Python網(wǎng)絡(luò)爬蟲爬取網(wǎng)易云音樂評論的文章就介紹到這了,更多相關(guān)python爬取網(wǎng)易云音樂評論內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
您可能感興趣的文章:- js實(shí)現(xiàn)網(wǎng)頁音樂播放器
- Vue.js實(shí)現(xiàn)音樂播放器
- 如何用Python一次性下載抖音上音樂
- java實(shí)現(xiàn)播放背景音樂
- 用python制作個音樂下載器
- Android實(shí)現(xiàn)音樂視頻播放
- 自己用python做的一款超炫酷音樂播放器