利用Python網絡爬蟲爬取各大音樂評論的代碼
python爬蟲–爬取網易雲音樂評論
方1:使用selenium模塊,簡單粗暴。但是雖然方便但是缺點也是很明顯,運行慢等等等。
方2:常規思路:直接去請求服務器
1.簡易看出評論是動態加載的,一定是ajax方式。
2.通過網絡抓包,可以找出評論請求的的URL
得到請求的URL
3.去查看post請求所上傳的數據
顯然是經過加密的,現在就需要按著網易的思路去解讀加密過程,然後進行模擬加密。
4.首先去查看請求是經過那些js到達服務器的
5.設置斷點:依次對所發送的內容進行觀察,找到評論對應的URL
6.查找加密函數
(忽略查找過程)找到:加密函數在
通過查找,找到加密函數具體位置:
7.解讀加密函數
運用的是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, #生成隨機數 e = Math.floor(e), #取整 c += b.charAt(e); #取出b中對應位置的字符 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是數據 , 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:數據json串 e:"010001" f: g = "0CoJUm6Qyw8W8jud" var h = {} , i = a(16); #16位隨機值 return h.encText = b(d, g), g是密鑰 h.encText = b(h.encText, i), #返回的就是params i是密鑰 h.encSecKey = c(i, e, f), #返回的是encSecKey e和f定死,能產生變數的隻能是i h function e(a, b, d, e) { var f = {}; return f.encText = c(a + e, b, d), f } window.asrsea = d
解讀該過程即可:代碼有註釋。
8.參數如何獲得:
function d(d, e, f, g) { d:數據json串 e:"010001" f: g = "0CoJUm6Qyw8W8jud" var bZe2x = window.asrsea(JSON.stringify(i4m), brx6r(["流淚", "強"]), brx6r(Sc1x.md), brx6r(["愛心", "女孩", "驚恐", "大笑"])); #使用網頁控制臺:發現都為定值;
9.這時隻需找到某一個i以及它對應的encSecKey 即可完成服務器的驗證
拿到該值之後開始編寫代碼
全部代碼粘貼
#1.找到未加密的參數 #通過函數window.asrsea()進行加密 #2.想辦法把參數進行加密,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默認是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) #創建加密器 bs = aes.encrypt(data.encode('utf-8')) #加密 return str(b64encode(bs),"utf-8") #轉化成字符串 #處理加密過程 ''' function a(a) { a=16 var d, e, b = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", c = ""; for (d = 0; a > d; d += 1) e = Math.random() * b.length, #生成隨機數 e = Math.floor(e), #取整 c += b.charAt(e); #取出b中對應位置的字符 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是數據 , 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:數據json串 e:"010001" f: g = "0CoJUm6Qyw8W8jud" var h = {} , i = a(16); #16位隨機值 return h.encText = b(d, g), g是密鑰 h.encText = b(h.encText, i), #返回的就是params i是密鑰 h.encSecKey = c(i, e, f), #返回的是encSecKey e和f定死,能產生變數的隻能是i h }''' if __name__ == '__main__': page = int(input('請輸入需要爬取的頁數:')) print('開始爬蟲!!!') fp = open('./網易雲評論.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('點贊數' + 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('點贊數'+str(result['data']['comments'][r]['likedCount'])+'\n') fp.write('-------------------------------------'+'\n') print('爬取完畢!!!')
效果圖
通過這次爬蟲實驗,在爬取的過程中,遇到各種困難,收貨很多。掌握遇到加密,該如何處理的步驟,以及拓寬自己的思路,去運用各種工具。以及各種自己想不到的思路。最起碼,下次遇到如此加密的數據獲取,心裡有瞭一些底氣。
也瞭解瞭大互聯網公司對數據進行加密的一種方式,以及網頁運作的更深一步的瞭解,受益頗多。
到此這篇關於如何用Python網絡爬蟲爬取網易雲音樂評論的文章就介紹到這瞭,更多相關python爬取網易雲音樂評論內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- None Found