開開心心爬APP,結(jié)果一坑連一坑
本文來自「凹凸數(shù)據(jù)」讀者投稿,歡迎大家分享更多優(yōu)質(zhì)內(nèi)容!獎勵多多~
最近因?yàn)闃I(yè)務(wù)需求,而要爬的數(shù)據(jù)又剛好沒有對應(yīng)的網(wǎng)頁版,使我對手機(jī)爬蟲教程格外感興趣,一頓操作之后我發(fā)現(xiàn),在這個過程中我遇到了一些回避不了的坑,需要跟大家分享一下。
前文回顧
回顧一下這篇文章用Fiddler篇爬取APP的教程:抓包手機(jī)大致分為以下幾步(具體的大家可以回顧對不起,我把APP也給爬了):
安裝軟件,設(shè)置軟件。同時在電腦上安裝證書
用手機(jī)連上和電腦相同的WIFI后,手機(jī)端設(shè)置代理。
手機(jī)端安裝證書,信任證書。
打開抓包軟件,刷新手機(jī)數(shù)據(jù),觀察并查找對應(yīng)url。
一般來說,照這幾個步驟是能夠很順利的取到數(shù)據(jù)。但是總有人臉黑,比如我。無論是用Fiddler還是Charles,都只能打開瀏覽器和高德地圖。而打開知乎,小紅書,好好住等APP卻一律被拒絕訪問。(oppo和小米手機(jī)都嘗試過。)

盡管并非所有人都會踩到這個坑,但是這種進(jìn)行到90%卻突然卡住的感覺真的非常膈應(yīng)人,查了好幾篇博客,比較靠譜的說法是:Android7以后,APP一般不信任用戶自己安裝的憑據(jù),也就是我們在手機(jī)上安裝的抓包軟件證書。
解決方法有兩個:
方法一,用Xposed攔截對證書的驗(yàn)證。 方法二、把Fiddler/Charles的證書放進(jìn)系統(tǒng)的證書目錄里。
第一種方法仍然有坑,手機(jī)能檢測到xposed攔截終還是會失敗(這里我沒有驗(yàn)證過,有興趣的同學(xué)可以試試)。所以我選擇planB,這里寫下我的過程,作為一份補(bǔ)充參考給大家。
Charles的配置與步驟
在正餐開始之前,我簡單說下Charles的配置(和Fiddler一個邏輯。只是界面稍有不同,選擇用Fiddler的同學(xué)可以跳過這里直接看后面)
Charles的配置
1、軟件安裝基本上就是一路Next,裝好以后進(jìn)入主界面,進(jìn)行如下設(shè)置:


2、在PC端安裝證書,放置到受信任的機(jī)構(gòu)。

3、打開手機(jī)的瀏覽器,輸入彈窗中提示的鏈接chls.pro/ssl,下載證書安裝。

好了,到這里重點(diǎn)來了!
同學(xué)們,如果你該勾選的選項(xiàng)也勾選了,該安裝的證書也安裝了,端口和代理配置都么有問題,以及最重要的是,如果你在電腦端能抓到數(shù)據(jù),手機(jī)APP卻拒絕訪問。
別懷疑,你一定是碰到和我一樣的坑了:你的手機(jī)APP不信任你安裝的Charles/fiddler證書。我們需要想辦法把它放到系統(tǒng)證書目錄中去。
正餐開始。
當(dāng)然,在開始之前,你需要準(zhǔn)備:
一臺root過的安卓機(jī)(最好是備用機(jī),我用的是小米)
Charles或者Fiddler的證書文件(Charles是crt文件,F(xiàn)iddler是cer文件,后面獲取hash值的時候會有差別)
Windows系統(tǒng)需要下載安裝openSSL工具(官網(wǎng):https://www.openssl.org/,安裝完后記得把openssl下的bin文件夾目錄加入到環(huán)境變量中去)
好了,開始我們的操作!
step1
手機(jī)端下載證書后先別著急安裝,導(dǎo)到電腦上,復(fù)制下它的路徑(比如我的是"D:\證書\charles\getssl.crt")
step2
按Win+R,輸入cmd,進(jìn)入命令窗口,輸入:
opensslx509-subject_hash_old-in"D:\證書\charles\getssl.crt"
記得in后面修改為自己的證書路徑。執(zhí)行后我們得到以下內(nèi)容:

紅色的這串就是我們獲取到的證書的hash值,這個Hash值記得保存下來。Fiddler的證書由于是cer格式是無法直接獲取的,需要先導(dǎo)成crt格式,我會在最后補(bǔ)充
step3
把證書修改成hash值.0格式。如下,別帶后綴:

step4
將重命名好的證書放進(jìn)手機(jī)的sd卡,記得復(fù)制進(jìn)去的證書不可以有.crt或者.cer這樣的后綴,以.0結(jié)尾才對。

step5
把改好名字的證書文件復(fù)制到系統(tǒng)的證書目錄里,層級稍微有點(diǎn)深,路徑如下(我這是小米的路徑):

這里就會有個問題出現(xiàn)。直接用系統(tǒng)自帶的文件管理器查看的話可能會獲取不到完整的system文件目錄,建議下載一個RE文件管理器,并且在安全中心里給予它root權(quán)限。如下(各品牌手機(jī)可能不同):

最后,重啟下各類應(yīng)用,就可以抓取了!
Fiddler的配置與源碼
上面都是在說Charles,我們再講講Fiddler。
Fiddler的配置
其實(shí)Fiddler也是同理,需要我們獲取到證書的Hash值,修改證書名后放進(jìn)系統(tǒng)證書目錄。只是因?yàn)镕iddler的證書是cer格式,我們需要多一個步驟:先把證書轉(zhuǎn)成crt格式的。
同樣是Win+R后輸入cmd進(jìn)入命令窗口。cd到你放置證書的目錄,然后輸入轉(zhuǎn)換格式的命令。如下(記得你的文件在哪個盤就輸入哪個盤,在哪個目錄就輸入哪個目錄):
d:
cd Zhengshu
openssl x509 -inform DER -in FiddlerRoot.cer -out FiddlerRoot1.crt
此目錄下就會生成一個crt格式的證書,然后我們繼續(xù)用上面的方法讀取它的hash值。輸入:
opensslx509-subject_hash_old-in FiddlerRoot.crt
得到我們想要的Hash值

再修改好名字放入系統(tǒng)證書后,我們就可以正常的抓數(shù)據(jù)了。最后我們以好好住這個APP為例,看看抓下來的數(shù)據(jù)是什么樣的,我們以下面這個話題為例:

多滑動幾屏,觀察下哪個url是在閃爍的,這個多半就是我們要找的,或者直接從評論里摘取一段話,ctrl+F搜索。這里我們發(fā)現(xiàn)是下評論內(nèi)容都在下面這個url里。

也可以過濾一下監(jiān)聽的信息,在左下角的filter里設(shè)置成只監(jiān)聽該網(wǎng)址,看起來會更夾清爽:

好好住這個APP的數(shù)據(jù)是很清晰的json格式,我們只需要把對應(yīng)的headers,cookies等參數(shù)加上,再寫個循環(huán),就能輕松把評論爬下來了。這些信息可以在右上角的窗口觀察到,如下:

params參數(shù)如下,topic_id對應(yīng)不同的話題(不過這個id并不是固定不變的,和我上一次觀察的不同)

因?yàn)楸疚闹攸c(diǎn)是如何突破APP的防備監(jiān)聽手機(jī)數(shù)據(jù),這里我們就不詳細(xì)展開寫爬蟲的邏輯。
爬蟲源碼
完整的代碼如下。
代碼稍微有點(diǎn)丑陋大家不爬這個APP的話可以不用看。
#導(dǎo)入相關(guān)模塊
import?requests
import?time
import?random
#復(fù)制請求頭,cookies等參數(shù)
headers={
????'user-agent':'Dalvik/2.1.0?(Linux;?U;?Android?8.0.0;?MI?5?MIUI/8.11.22)hhz4.7.0-did44c043bb9672a88b4eafdfb3ce276c2c-h16946635abc3f22102c7e10-uid597199-ovid_1000000000597199-proxy-emu0',
????'accept-encoding':'gzip',
????'content-type':?'application/x-www-form-urlencoded',
}
cookies={
????'visitor_token':'ovid_1000000000597199',
????'hhz_token':'8ebae5a0dd1c47223a76243ce32f1347',
????'Token':'8ebae5a0dd1c47223a76243ce32f1347'
}
url='https://yapi.haohaozhu.cn/topic/GetAnswerList460'
remark_list=[]
for?i??in?range(1,28):
????#這個參數(shù)雖然又規(guī)律但是今天我看的時候已經(jīng)發(fā)生變化了,大家如果要爬的話需要重新觀察下。
????params='topic_id=365&sort_type=1¤t_time=1589453251&page={}&basic_info=%7B%22%24app_version%22%3A%224.7.0%22%2C%22%24carrier%22%3A%22%E5%85%B6%E4%BB%96%22%2C%22%24lib%22%3A%22Android%22%2C%22%24lib_version%22%3A%221.6.19%22%2C%22%24manufacturer%22%3A%22Xiaomi%22%2C%22%24os%22%3A%22Android%22%2C%22%24os_version%22%3A%228.0.0%22%2C%22%24screen_height%22%3A1920%2C%22%24screen_width%22%3A1080%2C%22distinct_id%22%3A%2244c043bb9672a88b4eafdfb3ce276c2c%22%7D'.format(i)
????#注意請求方式是POST
????res=requests.post(url,headers=headers,cookies=cookies,params=params)
????json_obj=res.json()
????data=json_obj['data']
????list=data['list']
????for?content?in?list:
????????#把評論文本提取出來
????????comment_box=content['photo']['photo_info']
????????comment=comment_box['remark']
????????remark_list.append(comment)
????????#加入停頓防止被反爬
????????time.sleep(random.random())
臉黑的朋友們可以考慮下試試我的方法,也許能夠解決困擾了你很久的問題。
