開開心心爬APP,結果一坑連一坑

本文來自「凹凸數據」讀者投稿,歡迎大家分享更多優質內容!獎勵多多~

大家好,我是新人三筒。

作爲凹凸的鐵粉,我會經常在歷史消息裏挖墳尋找我需要的教程。

最近因爲業務需求,而要爬的數據又剛好沒有對應的網頁版,使我對手機爬蟲教程格外感興趣,一頓操作之後我發現,在這個過程中我遇到了一些迴避不了的坑,需要跟大家分享一下。

前文回顧

回顧一下這篇文章用Fiddler篇爬取APP的教程:抓包手機大致分爲以下幾步(具體的大家可以回顧對不起,我把APP也給爬了):

  1. 安裝軟件,設置軟件。同時在電腦上安裝證書

  2. 用手機連上和電腦相同的WIFI後,手機端設置代理。

  3. 手機端安裝證書,信任證書。

  4. 打開抓包軟件,刷新手機數據,觀察並查找對應url。

一般來說,照這幾個步驟是能夠很順利的取到數據。但是總有人臉黑,比如我。無論是用Fiddler還是Charles,都只能打開瀏覽器和高德地圖。而打開知乎,小紅書,好好住等APP卻一律被拒絕訪問。(oppo和小米手機都嘗試過。)

儘管並非所有人都會踩到這個坑,但是這種進行到90%卻突然卡住的感覺真的非常膈應人,查了好幾篇博客,比較靠譜的說法是:Android7以後,APP一般不信任用戶自己安裝的憑據,也就是我們在手機上安裝的抓包軟件證書。

解決方法有兩個:

  • 方法一,用Xposed攔截對證書的驗證。

  • 方法二、把Fiddler/Charles的證書放進系統的證書目錄裏。

第一種方法仍然有坑,手機能檢測到xposed攔截終還是會失敗(這裏我沒有驗證過,有興趣的同學可以試試)。所以我選擇planB,這裏寫下我的過程,作爲一份補充參考給大家。

Charles的配置與步驟

在正餐開始之前,我簡單說下Charles的配置(和Fiddler一個邏輯。只是界面稍有不同,選擇用Fiddler的同學可以跳過這裏直接看後面)

Charles的配置

1、軟件安裝基本上就是一路Next,裝好以後進入主界面,進行如下設置:

Proxy》SSL Proxying Settings》Location中Add上Host:*,Port:*
ProxySettings》Proxies》Port設置爲8888(總之手機代理上的端口號要與之相同)

2、在PC端安裝證書,放置到受信任的機構。

Help》SSLProxying》InstallCharlesRootCertificate

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

好了,到這裏重點來了!

同學們,如果你該勾選的選項也勾選了,該安裝的證書也安裝了,端口和代理配置都麼有問題,以及最重要的是,如果你在電腦端能抓到數據,手機APP卻拒絕訪問。

別懷疑,你一定是碰到和我一樣的坑了:你的手機APP不信任你安裝的Charles/fiddler證書。我們需要想辦法把它放到系統證書目錄中去。

正餐開始。

當然,在開始之前,你需要準備:

  1. 一臺root過的安卓機(最好是備用機,我用的是小米)

  2. Charles或者Fiddler的證書文件(Charles是crt文件,Fiddler是cer文件,後面獲取hash值的時候會有差別)

  3. Windows系統需要下載安裝openSSL工具(官網:https://www.openssl.org/,安裝完後記得把openssl下的bin文件夾目錄加入到環境變量中去)

好了,開始我們的操作!

step1

手機端下載證書後先彆着急安裝,導到電腦上,複製下它的路徑(比如我的是"D:\證書\charles\getssl.crt")

step2

按Win+R,輸入cmd,進入命令窗口,輸入:

opensslx509-subject_hash_old-in"D:\證書\charles\getssl.crt"

記得in後面修改爲自己的證書路徑。執行後我們得到以下內容:

紅色的這串就是我們獲取到的證書的hash值,這個Hash值記得保存下來。Fiddler的證書由於是cer格式是無法直接獲取的,需要先導成crt格式,我會在最後補充

step3

把證書修改成hash值.0格式。如下,別帶後綴:

step4

將重命名好的證書放進手機的sd卡,記得複製進去的證書不可以有.crt或者.cer這樣的後綴,以.0結尾纔對。

step5

把改好名字的證書文件複製到系統的證書目錄裏,層級稍微有點深,路徑如下(我這是小米的路徑):

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

最後,重啓下各類應用,就可以抓取了!

Fiddler的配置與源碼

上面都是在說Charles,我們再講講Fiddler。

Fiddler的配置

其實Fiddler也是同理,需要我們獲取到證書的Hash值,修改證書名後放進系統證書目錄。只是因爲Fiddler的證書是cer格式,我們需要多一個步驟:先把證書轉成crt格式的。

同樣是Win+R後輸入cmd進入命令窗口。cd到你放置證書的目錄,然後輸入轉換格式的命令。如下(記得你的文件在哪個盤就輸入哪個盤,在哪個目錄就輸入哪個目錄):

d:
cd Zhengshu
openssl x509 -inform DER -in FiddlerRoot.cer -out FiddlerRoot1.crt

此目錄下就會生成一個crt格式的證書,然後我們繼續用上面的方法讀取它的hash值。輸入:

opensslx509-subject_hash_old-in FiddlerRoot.crt

得到我們想要的Hash值

再修改好名字放入系統證書後,我們就可以正常的抓數據了。最後我們以好好住這個APP爲例,看看抓下來的數據是什麼樣的,我們以下面這個話題爲例:

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

也可以過濾一下監聽的信息,在左下角的filter裏設置成只監聽該網址,看起來會更夾清爽:

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

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

因爲本文重點是如何突破APP的防備監聽手機數據,這裏我們就不詳細展開寫爬蟲的邏輯。

爬蟲源碼

完整的代碼如下。

代碼稍微有點醜陋大家不爬這個APP的話可以不用看。

#導入相關模塊
import requests
import time
import random
#複製請求頭,cookies等參數
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):
    #這個參數雖然又規律但是今天我看的時候已經發生變化了,大家如果要爬的話需要重新觀察下。
    params='topic_id=365&sort_type=1&current_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())

臉黑的朋友們可以考慮下試試我的方法,也許能夠解決困擾了你很久的問題。

三筒第一次投稿,大家點個在看支持一下吧

朱小五

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章