有讀者讓我爬逼乎,是我大意了...
前言
大家好,我是Kuls。
昨天折騰了很久的逼乎的爬蟲,最后還是成功爬取到了相關(guān)的數(shù)據(jù)。
其實能夠爬取到數(shù)據(jù),用處有很多,看自己怎么用,但是kuls這里跟大家說千萬別拿數(shù)據(jù)做盈利,不然小心進局子。
爬取數(shù)據(jù)就當(dāng)提升自己的技術(shù)和見識吧。
逼乎思路
其實逼乎的爬蟲有一些難度,尤其是對于js不是很熟悉的朋友,我在爬取過程中也是遇到了一些問題,最后也在百度上參考了一些大佬的思路才得以獲取。
像這些大型網(wǎng)站js加密會經(jīng)常性的更新和變化,所以了解思路就行,代碼不是很重要。
也許你看這篇文章的時候,代碼已經(jīng)不管用了。

逼乎是需要登錄的,登錄的案例我就暫時不寫了,如果在看數(shù)多,之后也分享給大家!
除了自動登錄,我們也可以使用cookie的方式來進行登錄。
我們先登錄逼乎,然后搜索一個關(guān)鍵詞,打開調(diào)試器。

獲取cookie,我們點進Network調(diào)試,然后過濾doc文件,就會看到過濾出一個包,然后點開就能夠看到cookie了。
有了cookie,登錄的問題就解決了。
登錄解決后,我們就需要找到獲取數(shù)據(jù)的接口了。

https://www.zhihu.com/api/v4/search_v3?t=general&q=%E6%89%8B%E6%9C%BA&correction=1&offset=0&limit=20&lc_idx=0&show_all_topics=0
我們可以先按照平時的思路來進行爬取,首先就是把Request Headers中的信息給提取出來,編寫我們的header。
然后直接帶著cookie請求。
我們會發(fā)現(xiàn)我們是可以正常獲取的。
但是當(dāng)我們?nèi)Q一個關(guān)鍵詞搜索時,就會返回一個error的信息。
headers?=?{
????'User-Agent':?User_Agent,
????'cookie':?cookie,
????'referer':?referer,
????'user-agent':?'Mozilla/5.0?(Macintosh;?Intel?Mac?OS?X?11_0_1)?AppleWebKit/537.36?(KHTML,?like?Gecko)?Chrome/87.0.4280.67?Safari/537.36?Edg/87.0.664.52',
????'x-zse-83':?'3_2.0',
????'x-zse-86':?'1.0_%s'?%encrypt_str
}
通過簡化headers里的內(nèi)容,我們可以把它簡化成如上所示。
其中,最為關(guān)鍵的就是x-zse-86,這是逼乎的一個加密算法,想要爬取逼乎必須要去對這個加密進行了解。
那么,怎么去破解x-zse-86算法呢?
首先,我們要去找相關(guān)的js代碼。對于這類加密的玩法,我們都需要第一步去找js,怎么找呢?
這里也提供幾個思路,第一個右擊網(wǎng)頁->查看源代碼,有一些加密會在html頁面當(dāng)中,例如下圖:

但是,如果你去右擊逼乎的源碼,你會發(fā)現(xiàn)不太好找啊!

此時,我們應(yīng)該動用第二個思路,前往控制臺的source,可以查看到該網(wǎng)站相關(guān)的文件。

具體是哪個js文件,大家具體可以看我上面的圖片。

通過搜索x-zse-86關(guān)鍵詞,我們會發(fā)現(xiàn)它由"1.0"+"_"+p 來組成的。
c.set("x-zse-86",?"".concat("1.0",?"_").concat(p)),
也就是說,我們現(xiàn)在只要弄清楚了p變量是啥,然后獲取它就能夠拿到x-zse-86的值。

通過觀察,我們會發(fā)現(xiàn)p變量是等于f.signature的。于是我們就通過搜索signature來看看到底是什么。

在上圖中,我們找到了signature的值。
我們會發(fā)現(xiàn)它是通過幾個函數(shù)來得到的。
signature:?V()(B()(f))
既然這么多層,我們只能一層一層來扒了。
首先是f
f?=?[r,?u,?l,?o,?X(d)?&&?d,?i].filter(Boolean).join("+");
我們往上面看代碼,會發(fā)現(xiàn)f就是由上面幾個值拼湊而成的。

通過斷點debug(關(guān)于斷點不懂的,可以百度或者加我好友進行討論),我們發(fā)現(xiàn)f拼湊出來的幾個變量的值分別是什么。
其實就是headers里的x-zse-83+url+referer+“cookie.d_c0”
f解決了,我們需要解決一下B是啥了。
這里我們可以通過在控制臺中調(diào)用這個B方法,來看看它輸出的是什么:

可以發(fā)現(xiàn)它輸出了一串字符,經(jīng)過簡單的分析,我們將一串帶有url等信息作為參數(shù)傳入B方法,然后返回出另外一串字符。
作為程序員,我們接觸的最常見的加密就是md5,所以我們拿之前斷點的f值去進行加密

果不其然,我們拿到的值跟輸出的是一模一樣的。
B方法也解決了,就是一個md5加密。最后我們來講解一下V函數(shù):
照樣打斷點:

跳一次

我們會發(fā)現(xiàn)這是一個加密的算法
var?b?=?function(e)?{
????????return?__g._encrypt(encodeURIComponent(e))
????};

通過在console控制臺中簡單的執(zhí)行相關(guān)函數(shù),我們會發(fā)現(xiàn)__g._encrypt的處理方法就是這句話的上面一部分js代碼,由于代碼過多,這里就不展示出來,會在底部告知大家。
這就很好說了,執(zhí)行這個js加密算法,我們需要通過調(diào)用Python來調(diào)用js的代碼。這時我們會采用jsdom的方式來執(zhí)行。
jsdom的安裝:
npm i jsdom -g
結(jié)尾
整體的思路就說完了,如果你覺得本文對你有所幫助,麻煩點個在看呀!
如果想要獲取本項目完整的代碼
戀習(xí)Python 關(guān)注戀習(xí)Python,Python都好練
掃碼回復(fù)【逼乎】
好文章,我在看??
