前言
本文的文字及圖片來源於網絡,僅供學習、交流使用,不具有任何商業用途,版權歸原作者所有,如有問題請及時聯繫我們以作處理。
作者:風,又奈何
環境準備
-
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)