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

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

獲取cookie,我們點(diǎn)進(jìn)Network調(diào)試,然后過(guò)濾doc文件,就會(huì)看到過(guò)濾出一個(gè)包,然后點(diǎn)開(kāi)就能夠看到cookie了。
有了cookie,登錄的問(wèn)題就解決了。
登錄解決后,我們就需要找到獲取數(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
我們可以先按照平時(shí)的思路來(lái)進(jìn)行爬取,首先就是把Request Headers中的信息給提取出來(lái),編寫我們的header。
然后直接帶著cookie請(qǐng)求。
我們會(huì)發(fā)現(xiàn)我們是可以正常獲取的。
但是當(dāng)我們?nèi)Q一個(gè)關(guān)鍵詞搜索時(shí),就會(huì)返回一個(gè)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
}
通過(guò)簡(jiǎn)化headers里的內(nèi)容,我們可以把它簡(jiǎn)化成如上所示。
其中,最為關(guān)鍵的就是x-zse-86,這是逼乎的一個(gè)加密算法,想要爬取逼乎必須要去對(duì)這個(gè)加密進(jìn)行了解。
那么,怎么去破解x-zse-86算法呢?
首先,我們要去找相關(guān)的js代碼。對(duì)于這類加密的玩法,我們都需要第一步去找js,怎么找呢?
這里也提供幾個(gè)思路,第一個(gè)右擊網(wǎng)頁(yè)->查看源代碼,有一些加密會(huì)在html頁(yè)面當(dāng)中,例如下圖:

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

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

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

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

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

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

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

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

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

跳一次

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

通過(guò)在console控制臺(tái)中簡(jiǎn)單的執(zhí)行相關(guān)函數(shù),我們會(huì)發(fā)現(xiàn)__g._encrypt的處理方法就是這句話的上面一部分js代碼,由于代碼過(guò)多,這里就不展示出來(lái),會(huì)在底部告知大家。
這就很好說(shuō)了,執(zhí)行這個(gè)js加密算法,我們需要通過(guò)調(diào)用Python來(lái)調(diào)用js的代碼。這時(shí)我們會(huì)采用jsdom的方式來(lái)執(zhí)行。
jsdom的安裝:
npm i jsdom -g
結(jié)尾
整體的思路就說(shuō)完了,如果你覺(jué)得本文對(duì)你有所幫助,麻煩點(diǎn)個(gè)在看呀!
如果想要獲取本項(xiàng)目完整的代碼
掃碼回復(fù)【逼乎】
參考鏈接:
https://blog.csdn.net/weixin_40352715/article/details/107546166
PS:公號(hào)內(nèi)回復(fù)「Python」即可進(jìn)入Python 新手學(xué)習(xí)交流群,一起?100 天計(jì)劃!
老規(guī)矩,兄弟們還記得么,右下角的 “在看” 點(diǎn)一下,如果感覺(jué)文章內(nèi)容不錯(cuò)的話,記得分享朋友圈讓更多的人知道!
【神秘禮包獲取方式】
識(shí)別文末二維碼,回復(fù):1024


