Python手機App數據抓取實戰:抖音用戶的抓取

前言

本文的文字及圖片來源於網絡,僅供學習、交流使用,不具有任何商業用途,版權歸原作者所有,如有問題請及時聯繫我們以作處理。

作者:風,又奈何

環境準備

  • fiddler

  • appium

  • mitmproxy(mitmdump)

  • python3.6

  • 自帶root的安卓虛擬機

  • Android SDK

安卓模擬器需要安裝xposed框架並安裝JustTrustMe組件,因爲抖音會有ssl驗證,會導致我們在將數據發送到我們的抓包工具的時候無法聯網,所以需要安裝這個組件來關閉ssl驗證

mitmproxy、AndroidSDK需要加入環境變量,這步就不再敘述

項目準備

首先我們需要給虛擬機安裝fiddler、mitmproxy的證書

1)fiddler 主要設置如下

端口設置可以隨意更改,本文設置爲8889

電腦主機打開命令行 輸入ipconfig查看本機IP

設置模擬器的代理

接下來打開瀏覽器,輸入 ip:prot 如本機爲 117.90.211.134:8889 下載安裝fiddler證書 如下步驟

接下來我們就可以使用fiddler正確的抓取手機數據包了

2)mitmproxy證書

我們在Windows系統上常用的是mitmproxy的mitmdump 打開cmd輸入mitmdump -p 端口號 就可以啓動服務

爲了方便我們將端口號也設置爲8889 但是開啓這個的時候需要先關閉fiddler 不然會端口衝突,然後打開模擬器的瀏覽器看看能否接受數據

我們發現出問題了,發現現在直接提示空的響應而不是證書的問題,看到mitmdump報的錯誤是 killed by block_global 是什麼原因呢?

這是mitmdump的自我保護措施,它防止全球網絡的連接,意思就是如果是本地局域網它不會阻攔,那該怎麼辦呢?

有兩種解決辦法:第一種,將模擬器的網絡連接設置爲橋接模式,這樣就不會出現問題;

第二種辦法是啓動的時候加入參數 mitmdump -p 8889 --set block_global=false 如下圖

接下來 安裝mitmproxy的證書 瀏覽器輸入網址 mitm.it 然後安裝證書

現在再打開網頁就不會出現證書的提醒了

這時候我們需要用的主要兩個抓包工具的證書就安裝完成了,需要注意的是我們每次測試都可能需要重新安裝證書,因爲我們的主機IP可能會變

ps:推薦一下我建的python零基礎系統學習交流扣扣qun:前面是937,中間667,後面是509,羣裏有免費的視頻教程,開發工具、電子書籍分享。專業的老師答疑!學習python web、python爬蟲、數據分析、大數據,人工智能等技術有不懂的可以加入一起交流學習,一起進步!

App分析

首先呢我們先確認模擬器中的xposed框架的JustTrustMe組件是否開啓 不然我們抖音App不能正常訪問網絡

注意以下步驟只能在網絡橋接模式下使用(或者使用真機與電腦在同一個網絡) 否則fiddler無法抓取到所有的包

首先使用fiddler分析,打開fiddler 並打開抖音進行操作 本項目是爬取cxk坤坤的粉絲數據,所以我們先進入他的抖音主頁點進粉絲列表

粉絲好多,我們接下來向下滑動,看看當向下滑動刷新出更多粉絲的時候 fiddler會抓取到什麼數據

會發現每次向下滑動的時候都會有一個含有 aweme/v1/user/follower/list/ 的網址,我們懷疑這就是粉絲數據的接口 我們把這個網址返回來的數據放入 json.cn 看看

還真的就是粉絲數據,會發現每次滑動更新的是二十個粉絲,所以我們就找對了方向,下面我們來分析這個請求

GET https://aweme-hl.snssdk.com/aweme/v1/user/follower/list/?user_id=103313639528&sec_user_id=MS4wLjABAAAAxj2Cuu75g3I2pGOs7jtw5XN6WMiCKbA-jfIjlONRRvM&max_time=1570336550&count=20&offset=0&source_type=1&address_book_access=1&gps_access=1&openudid=3ca06768d1f58615&version_name=8.1.1&ts=1570336895&device_type=OPPO%20R11&ssmix=a&iid=87664447665&app_type=normal&os_api=19&mcc_mnc=46007&device_id=68799320259&resolution=720*1280&device_brand=OPPO&aid=1128&manifest_version_code=811&app_name=aweme&_rticket=1570336895512&os_version=4.4.2&device_platform=android&version_code=811&update_version_code=8112&ac=wifi&dpi=240&uuid=866174010601603&language=zh&channel=tengxun_new HTTP/1.1

我們會發現這個請求的url帶有很多很多的參數,沒錯,這是抖音自身的加密方法,要破解這個可得好一會了,所以我們無法使用requests直接構造請求來獲得數據了,那我們該如何獲取數據呢?

沒錯就是使用mitmdump,mitmdump有個最大的好處就是可以與python文件交互,我們可以直接使用python寫好命令,使用mitmdump抓包,我們手動的滑動就可以解析出數據了

編寫douyin_mitmdump.py文件 代碼如下:

 


import json
#函數名必須這樣寫 這是mitmdump規則
def response(flow):
 #下面這個網址是通過fiddler獲取到的 但是有些數據我們無法解密,所以需要用mitmdump捕獲數據包然後做分析
 if 'aweme-hl.snssdk.com/aweme/v1/user/follower/list' in flow.request.url:
 for user in json.loads(flow.response.text)['followers']:
 user_info={}
 user_info['nickname'] = user['nickname']
 user_info['share_id'] = user['uid']
 user_info['douyin_id'] = user['short_id']
 #有的用戶修改了抖音號
 if user_info['douyin_id'] == '0':
 user_info['douyin_id'] = user['unique_id']
 print(user_info)

現在打開cmd並切換到項目目錄下 執行命令 mitmdump -p 8889 -s douyin_mitmdump.py

接下來手動滑動界面看看會不會解析數據

好的 現在我們已經成功的分析出來了粉絲數據,但是我們總不能一直鼠標滑動吧?所以我們現在需要使用Appium進行自動化測試模擬滑動

Appium自動化測試模擬滑動

配置信息

Appium是一個開源測試自動化框架,可用於原生,混合和移動Web應用程序測試。它使用WebDriver協議驅動iOS,Android和Windows應用程序。

比如本文我們就使用appium來實現從點開程序到模擬滑動的全部操作。

首先我們需要在電腦上安裝Appium

這個相當於appium服務端,我們在執行自動化測試的時候需要先在電腦上打開服務端,然後我們使用程序連接虛擬機或真機執行腳本進行自動化測試 點擊start server打開服務端

我們首先使用appium 自帶的測試程序來試一下如何操作 點擊右上角的放大鏡符號

進入配置選項界面 開始填寫選項信息

下面我來解釋每個參數都是如何得到的

1)platformName 這是平臺名稱 我們填寫 Andriod 相信不用過多解釋

2)platformVersion 這是問平臺版本信息,根據各個手機不同自主填寫,本文使用的是 Andriod4.4.2

3)deviceName 這個是設備的名稱,我們如何獲取呢?

  這個時候就用到了我們AndroidSDK中的adb工具了 adb是用來連接電腦與手機的工具 我們把手機進入開發者選項並打開允許USB調試,然後打開命令行輸入命令 adb devices看看有沒有輸出

返回的127.0.0.1:52001就是設備名稱 這個是模擬器的名稱,使用真機會不同 (如果沒有返回就關閉開發者模式重新打開USB調試多試幾次)

4)appPackage、appActivity這倆個參數非常重要,它指定了我們自動化測試的app,這兩個參數獲取有點麻煩,下面詳解如何獲取

  首先手機打開App,本文就是抖音了,然後電腦命令行輸入 adb shell 進入交互界面 然後輸入命令 dumpsys activity | grep mFocusedActivity

第一個就是包名,第二個就是activity名 我們記下來一會編寫進去(activity名稱前要跟着包名)

  即 包名com.ss.android.ugc.aweme activity名com.ss.android.ugc.aweme.main.MainActivity

5)noReset unicodekeyboard resetkeyboard解釋會在一會的程序中

然後點擊右下方保存配置信息並start session 如果點擊start session發現手機自動打開抖音時,就說明我們的配置信息寫對了,就可以開始使用了

這些配置信息一會要在我們的python腳本中使用,所以一定要填寫正確

內容分析

其實app自動化測試跟網頁爬蟲很相似,首先分析我們該怎麼做

點開抖音這一步已經不用我們去做 然後我們需要依次點左上角放大鏡按鈕、點擊搜索框輸入抖音號、點擊搜索、點擊用戶、點擊進入主頁、點擊粉絲、向上滑動

我們該如何定位按鈕以及輸入信息呢?

這又得使用AndroidSDK中的工具了 這次使用 AndroidSDK\tools\monitor.bat 中的monitor 可能有的小夥伴會問 爲什麼不使用可以查看xpath的魔改版的uiautomatorviewer呢?這是因爲我在測試的時候發現現在抖音加入了某種時鐘,我們都知道uiautomatorviewer無法獲取動態頁面的數據,而我發現monitor有的界面卻可以,所以使用monitor,下面開始

首先用鼠標點擊左邊畫藍色圈的地方獲取當前手機界面數據,然後鼠標點擊我們需要的控件,之後右邊出現的就是我們需要的信息,我們可以通過resource-id查找指定數據

現在先來編寫douyin_appium.py文件測試下能否自動打開抖音並點擊左上方放大鏡按鈕


from appium import webdriver
#WebDriverWait用來加入時間判斷,有時候控件元素需要過一段時間纔會出現
from selenium.webdriver.support.ui import WebDriverWait
import time
#配置信息
option={
 "platformName": "Android",
 "platformVersion": "4.4.2",
 "deviceName": "127.0.0.1:52001",
 #自動化測試包名
 "appPackage": "com.ss.android.ugc.aweme",
 #自動化測試Activity
 "appActivity": "com.ss.android.ugc.aweme.main.MainActivity",
 #再次啓動不需要再次安裝
 "noReset": True,
 #unicode鍵盤 我們可以輸入中文
 "unicodekeyboard": True,
 #操作之後還原回原先的輸入法
 "resetkeyboard":True
}
#其中的4723就是appium服務啓動時的端口號
driver = webdriver.Remote("http://localhost:4723/wd/hub",option)
#放大鏡按鈕
try:
 #使用resource-id查找按鈕
 if WebDriverWait(driver,5).until(lambda x:x.find_element_by_id('com.ss.android.ugc.aweme:id/b3o')):
 #點擊按鈕
 driver.find_element_by_id('com.ss.android.ugc.aweme:id/b3o').click()
except:
 pass

運行之前首先要開啓 appium 服務端,即start server

然後運行python文件

好的我們發現已經可以自動的點擊放大鏡按鈕了,那麼接下來只需要繼續編寫文件即可以完成自動化操作了 代碼如下


from appium import webdriver
#WebDriverWait用來加入時間判斷,有時候控件元素需要過一段時間纔會出現
from selenium.webdriver.support.ui import WebDriverWait
import time
#配置信息
option={
 "platformName": "Android",
 "platformVersion": "4.4.2",
 "deviceName": "127.0.0.1:52001",
 #自動化測試包名
 "appPackage": "com.ss.android.ugc.aweme",
 #自動化測試Activity
 "appActivity": "com.ss.android.ugc.aweme.main.MainActivity",
 #再次啓動不需要再次安裝
 "noReset": True,
 #unicode鍵盤 我們可以輸入中文
 "unicodekeyboard": True,
 #操作之後還原回原先的輸入法
 "resetkeyboard":True
}
#其中的4723就是appium服務啓動時的端口號
driver = webdriver.Remote("http://localhost:4723/wd/hub",option)
#放大鏡按鈕
try:
 #使用resource-id查找按鈕
 if WebDriverWait(driver,5).until(lambda x:x.find_element_by_id('com.ss.android.ugc.aweme:id/b3o')):
 #點擊按鈕
 driver.find_element_by_id('com.ss.android.ugc.aweme:id/b3o').click()
except:
 pass
#得到窗口大小
def get_size():
 x=driver.get_window_size()['width']
 y=driver.get_window_size()['height']
 return (x,y)
#搜索框
try:
 # 定位搜索框
 if WebDriverWait(driver,3).until(lambda x:x.find_element_by_id('com.ss.android.ugc.aweme:id/ad1')):
 #點擊搜索框
 driver.find_element_by_id('com.ss.android.ugc.aweme:id/ad1').click()
 #輸入抖音號並點解搜索
 driver.find_element_by_id('com.ss.android.ugc.aweme:id/ad1').send_keys("1307311292")
 driver.find_element_by_id('com.ss.android.ugc.aweme:id/dy8').click()
 #點擊用戶 注意寫法 這個控件由於無法獲取resource_id與xpath的值 所以只能通過text來查找
 driver.find_element_by_android_uiautomator("text(\"用戶\")").click()
except:
 pass
#點進去具體界面
try:
 if WebDriverWait(driver,5).until(lambda x:x.find_element_by_id('com.ss.android.ugc.aweme:id/bck')):
 #進入用戶信息界面
 driver.find_element_by_id('com.ss.android.ugc.aweme:id/bck').click()
 time.sleep(2)
 #點擊粉絲數
 driver.find_element_by_id('com.ss.android.ugc.aweme:id/akf').click()
except:
 pass
#得到屏幕尺寸
size = get_size()
#定義滑動
x1 = int(size[0]*0.5)
x2 = int(size[0]*0.7)
y1 = int(size[1]*0.9)
y2 = int(size[1]*0.2)
while(True):
 time.sleep(0.5)
 #模擬滑動
 driver.swipe(x1, y1, x2, y2)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章