游賢 成都理工大學(xué)信息科學(xué)與技術(shù)學(xué)院
抓取全站信息一般選擇有規(guī)律的網(wǎng)頁(yè)采用廣度優(yōu)先方法,考慮到如果從歌單頁(yè)面開(kāi)始的話(huà),會(huì)有很多歌曲重復(fù),因?yàn)橄嗤母枨梢詣澐值讲煌母鑶?。因此最終決定從歌手頁(yè)面開(kāi)始,作為種子頁(yè)面,這樣歌曲的重復(fù)量會(huì)小很多(如果有多個(gè)歌手合唱,那么這首歌會(huì)出現(xiàn)在每個(gè)歌手的歌曲頁(yè)面當(dāng)中,他們的訪問(wèn)地址是不一樣的)。
方法一: 從http://music.163.com/discover/artist頁(yè)面出發(fā),可以找到所有的音樂(lè)人,
如圖所示,每個(gè)歌手分類(lèi)對(duì)應(yīng)的url為http://music.163.com/discover/artist/cat?id=xxx 它 的 可 取 值 有 1001,1002,1003,2001,2002,2003,6001,6002,6003,7001,7002,7003,4001,4002,4003。然后我沒(méi)隨便進(jìn)入其中其一個(gè)頁(yè)面
網(wǎng)頁(yè)中的id就是之前提到的id的可取值,這里取1001代表華語(yǔ)男歌手;initial是首字母的意思。這里的65代表A(華語(yǔ)男歌手中姓氏首字母是A的歌手), ASCII碼的表示方式,表示,,最后有個(gè)其他的分類(lèi),用0表示,然后我們繼續(xù)跟進(jìn)可以來(lái)到歌手的專(zhuān)輯頁(yè)面和歌曲的詳細(xì)頁(yè)面,從而獲取到歌曲的下載地址和評(píng)論信息。
以楊宗緯的“可惜不是你”這首歌為例子,對(duì)應(yīng)url為music.163.com/song?id-29375071。
打開(kāi)抓包工具或者瀏覽器開(kāi)發(fā)者工具,下拉顯示評(píng)論信息,可以獲取到評(píng)論的http請(qǐng)求??梢钥闯鲞@是一個(gè)POST的請(qǐng)求,帶有params和encSecKey兩個(gè)參數(shù),這兩個(gè)參數(shù)都是經(jīng)過(guò)加密處理的
這兩個(gè)參數(shù)是經(jīng)過(guò)js加密的,因此我們需要對(duì)相應(yīng)的js文件做斷點(diǎn)調(diào)試,找到它生成加密參數(shù)的函數(shù)。利用瀏覽器開(kāi)發(fā)者工具的全局搜索功能,我們很快就能定位到
var bua = window.asrsea(JSON.stringify(bl), bbZ([‘流淚’,‘強(qiáng)’]), bbZ(Ka.md), bbZ([‘愛(ài)心’, ‘女孩’,
‘驚恐’, ‘大笑’]));
bf.data = bm.eX({
params: bua.encText,
encSecKey: bua.encSecKey
}),
可以看出兩個(gè)加密參數(shù)都是在這里生成的。
繼續(xù)跟進(jìn)調(diào)試發(fā)現(xiàn)Window.asrsea 是一個(gè)d函數(shù):
其中 e, f,g都是固定的字符:
e: “010001”
f: “””00e0b509f6259df8642dbc35662901477df22677ec152b 5ff68ace615
bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fc cf
695280104e0 312 ecbda92557c93870114af6c9d05c4f7f0c3685b 7a46
bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d5 46b
8e2 89 dc6935b3ece0462db0a22b8e7”””
g: 0CoJUm6Qyw8W8jud
這個(gè)函數(shù)的功能如下:
1. 先生成一個(gè)16位隨機(jī)數(shù)i
2. 使用g參數(shù)作為key,將動(dòng)態(tài)參數(shù)d進(jìn)行加密得encText(加密函數(shù)b(a,b))
3. 使用隨機(jī)數(shù)i作為key,將上步加密得到的encText再次加密(加密函數(shù)b(a,b))
4. 使用參數(shù)e,f作為key,將隨機(jī)數(shù)i進(jìn)行加密的encSecKey(加密函數(shù)c(a, b, c))
5. 函數(shù)c是一個(gè)簡(jiǎn)單的rsa加密
3.關(guān)鍵代碼實(shí)現(xiàn)
利用python實(shí)現(xiàn)兩次aes和一次rsa解密
def create_aes_key(size):
return (''.join([hex(b)[2:] for b in os.urandom(size)]))[0:16]
def aesEncrypt(self, text, key):
iv = '0102030405060708'
pad = 16 - len(text) % 16
text = text + pad * chr(pad)
encryptor = AES.new(key, 2, iv)
ciphertext = encryptor.encrypt(text)
ciphertext = base64.b64encode(ciphertext)
return ciphertext.decode('utf8')
def rsa_encrypt(self, text):
e = '010001'
n = '00e0b509f6259df8642dbc35662901477df22677ec152b5ff 68ace615'
'bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135f ccf'
'695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b 7a46'
'bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d 546b'
'8e289dc6935b3ece0462db0a22b8e7'
reverse_text = text[::-1].encode('utf8')
pub_key = RSA.construct([int(n, 16), int(e, 16)])
encrypt_text = pub_key.encrypt(int(binascii.hexlify(reverse_text), 16), None)[0]
return format(encrypt_text, 'x').zfill(256)