「抓取」微信讀書生成的唯一標(biāo)識獲取詳情信息
昨天有位小姐姐請我?guī)兔?,讓我看如何生成獲取微信讀書里獲取圖書詳細信息的唯一標(biāo)識,業(yè)務(wù)方給她的需要是抓取微信讀書里的詳細信息,我當(dāng)然是義不容辭的看一下。

定位來源
通過F12查看一下這個特殊的字符串是不是通過接口返回來的,如何是通過服務(wù)端返回來的,那么通過調(diào)取接口就可以獲取到,如果不是調(diào)接口返回那么換一種思路。

很快通過查看network發(fā)現(xiàn)并不是接口直接返回,那么可能就是通過某一個特殊的標(biāo)識,通過加密算法生成的唯一字符串

轉(zhuǎn)化思路
通過頁面元素自身的屬性class查看,看看是不是存在動態(tài)的自定義屬性

果不奇然在sources中找到了動態(tài)添加自定義屬性的方法,可以看到a標(biāo)簽上的href屬性是動態(tài)生成的


然后就可以按部就班的依次查找這個方法的參數(shù)以及返回值,找到這個方法最終來源就可以找到這個算法的核心了
查找方法
查找方法中的參數(shù)

顯然這個_0x4711f8['bookData']['bookInfo']['bookId']是圖書的bookId

如果有疑問的話,我們可以看一下_0x4711f8這個對象是啥

有沒有很熟悉的感覺vue,這個頁面的開始使用過vue來寫的,將接口https://weread.qq.com/web/bookListInCategory/all?maxIndex=20&rank=1里返回的數(shù)據(jù)存到了bookData屬性里。
查找方法

_0x3c43('0x6')代表的是readerURL方法名,雙擊上圖標(biāo)綠色的部分,瀏覽器會自動定位到代碼部分即

點擊右上角代碼調(diào)試按鈕,讓代碼部分繼續(xù)往下走,進入我們找到的方法可以看到函數(shù)中有兩個參數(shù)_0xe6d312是改變this的指向,arguments是我們傳遞過來的參數(shù)

下面查找_0xe6d312[_0x4c35('0x879')]方法,雙擊標(biāo)紅色的地方,自動跳到代碼所在部分

繼續(xù)通過斷點調(diào)試,我們可以看到生成我們需要的字符串就是_0x1ef0a0['e'](_0x1dd4bb)這個方法

繼續(xù)斷點調(diào)試,最終找到算法的位置,即下圖標(biāo)紅的位置。

node實現(xiàn)
下面我們通過node.js實現(xiàn)這個算法
const crypto = require("crypto");
function createId(bookId){
let str = crypto.createHash("md5").update(bookId).digest('hex');
let strSub = str.substr(0,3);
let fa = function(id){
if (/^\d*$/['test'](id)) {
for (var len = id['length'], c = [], a = 0; a < len; a += 9) {
var b = id['slice'](a, Math.min(a + 9, len));
c['push'](parseInt(b)['toString'](16));
}
return ['3', c];
}
for (var d = '', i = 0; i < id['length']; i++) {
d += id['charCodeAt'](i)['toString'](16);
}
return ['4', [d]];
}(bookId);
strSub += fa[0],
strSub += 2 + str['substr'](str['length'] - 2, 2);
for (var m = fa[1], j = 0; j < m.length; j++) {
var n = m[j].length.toString(16);
1 === n['length'] && (n = '0' + n),
strSub += n,
strSub += m[j],
j < m['length'] - 1 && (strSub += 'g');
}
return strSub.length< 20 && (strSub += str.substr(0, 20 - strSub.length)),
strSub += crypto.createHash("md5").update(strSub).digest('hex').substr(0, 3);;
}
let strId = createId(bookId)
console.log(strId);
效果如下圖所示


通過對比我們生成的字符串和頁面生成的是一致的,多次測試滿足要求。
python實現(xiàn)
import hashlib
import re
def creatid(bookId):
str = hashlib.md5(bookId.encode("utf8")).hexdigest()
strSub = str[0:3]
reg = re.search('(\d+)',bookId).group(1)
if reg:
lenth = len(bookId)
for a in range(0,lenth):
b = bookId[a:min(a+9,lenth)]
c_str = hex(int(b))[2:]
fa =['3',[c_str]]
a += 9
if a >= lenth:
break
strSub += fa[0]
strSub += '2' + str[len(str)-2:]
m = fa[1]
for j in range(0,len(m)):
n = hex(len(m[j]))[2:]
if len(n) == 1:
n = '0'+ n
strSub += n + m[j]
if len(strSub) < 20:
strSub += str[0:20-len(strSub)]
strSub += hashlib.md5(strSub.encode("utf8")).hexdigest()[0:3]
print(strSub)
if __name__ == "__main__":
creatid(bookId)
運行結(jié)果:

關(guān)注數(shù):10億+?文章數(shù):10億+
粉絲量:10億+?點擊量:10億+
?懸賞博主專區(qū)請掃描這里
喜愛數(shù):?1億+?發(fā)帖數(shù):?1億+
回帖數(shù):?1億+?結(jié)貼率:?99.9%
—————END—————
喜歡本文的朋友,歡迎關(guān)注公眾號?程序員哆啦A夢,收看更多精彩內(nèi)容
點個[在看],是對小達最大的支持!
如果覺得這篇文章還不錯,來個【分享、點贊、在看】三連吧,讓更多的人也看到~



