大師兄的Python學(xué)習(xí)筆記(二十六): 爬蟲(七)
大師兄的Python學(xué)習(xí)筆記(二十八): 爬蟲(九)
九、爬取APP
- 在沒有網(wǎng)頁端的情況下,可以通過爬取App獲取數(shù)據(jù)。
- APP的反爬蟲措施沒有那么強(qiáng),且數(shù)據(jù)通常是Json格式,所以爬起來可能比web端更簡(jiǎn)單。
- 常用抓包軟件包括:WireShark、Fiddler、Charles、mitmproxy、AnyProxy...
- 可以使用Appium對(duì)APP進(jìn)行自動(dòng)化控制。
9.1 關(guān)于Charles
- Charles是一種網(wǎng)絡(luò)抓包工具,可以獲取App運(yùn)行過程中發(fā)生的所有網(wǎng)絡(luò)請(qǐng)求和相應(yīng)內(nèi)容。
- 可以作為主要的移動(dòng)端抓包工具,用于抓包分析。
9.1.1 安裝Charles
第一步:下載Charles
官網(wǎng)點(diǎn)此處下載安裝30天試用版。
第二步:安裝PC端Https證書
第三步:安裝手機(jī)端Https證書
- 首先將電腦和手機(jī)接入同一個(gè)局域網(wǎng)中。
PC端設(shè)置代理并開啟。
手機(jī)端接入PC端代理。
PC端同意接入。
- 手機(jī)端訪問http://www.charlesproxy.com/getssl下載證書。
- 下載后在手機(jī)端安裝證書: 加密和憑據(jù)->從存儲(chǔ)設(shè)備安裝
image.png
第四步:配置SSL監(jiān)聽
9.1.2 Charles抓包
-
首先確保http和https監(jiān)聽都已經(jīng)開啟。
- 可以考慮將Proxy->Windows Proxy關(guān)掉,以便觀察手機(jī)端數(shù)據(jù)。
-
用手機(jī)打開京東app,并隨便打開一件商品。
-
觀察PC端Charles抓取到的數(shù)據(jù),包括表單和Json格式的數(shù)據(jù)都已經(jīng)抓到了。
9.2 關(guān)于mitmproxy
- mitmproxy是與Charles類似的抓包程序,但是控制臺(tái)形式。
- mitmproxy有兩個(gè)關(guān)聯(lián)組件,分別是mitmdump和mitmweb。
- mitmdump是命令行接口,可以用來對(duì)接Python。
- mitmweb是web程序。
9.2.1 安裝mitmproxy
- 安裝mitmproxy非常簡(jiǎn)單,只需要使用
pip install mitmproxy就可以安裝mitmproxy、mitmdump和mitmweb。
9.2.2 獲取https證書
- 與charles一樣,如果想截取https請(qǐng)求,則需要設(shè)置證書。
- 谷歌在安卓7.0修改了安全策略,用戶添加的CA證書不能再用于安全連接,蘋果手機(jī)可以正常爬取。
第一步:使用
mitmdump指令啟動(dòng)mitmdump并生成證書。
第二步: 找到并雙擊認(rèn)證mitmproxy-ca-cert.p12證書文件。
第三步: 將證書文件mitmproxy-ca-cert.pem發(fā)送到手機(jī)端并驗(yàn)證。
9.2.3 手機(jī)端配置代理
-
在局域網(wǎng)配置->代理中配置mitmproxy主機(jī)的ip地址和port。
9.2.4 使用mitmproxy抓取數(shù)據(jù)
-
手機(jī)端完成代理配置后,就可以啟動(dòng)mitmproxy服務(wù)了
-
測(cè)試訪問頁面。
-
如果你用的是windows,也可以使用mitmweb使用網(wǎng)頁版抓取數(shù)據(jù)。
9.2.5 使用mitmdump對(duì)接Python
- mitmdump是mitmproxy的命令行對(duì)接口,同時(shí)也可以對(duì)接Python處理請(qǐng)求,這是mitmproxy相比charles的優(yōu)勢(shì)。
- 可以添加參數(shù),如
mitmdump -s script.py使用Python腳本處理截獲的數(shù)據(jù)。 - 此外,在控制臺(tái)使用
mitmdump -h可以查看所有參數(shù),其中比較常用的有:
-p port: 改變端口
-s script.py: 使用腳本處理截獲數(shù)據(jù)
-w outfile: 將截獲數(shù)據(jù)保存到文件
- 在Python腳本端,可以使用mitmproxy包處理截獲的數(shù)據(jù),
mitmproxy.http.HTTPFlow常用接口如下:
| 接口 | 作用 |
|---|---|
| flow.request.headers | 獲取所有頭信息,包含Host、User-Agent、Content-type等字段 |
| flow.request.pretty_url | 完整的請(qǐng)求地址,包含域名及請(qǐng)求參數(shù),但是不包含放在body里面的請(qǐng)求參數(shù) |
| flow.request.host | 域名 |
| flow.request.method | 請(qǐng)求方式。POST、GET等 |
| flow.request.scheme | 什么請(qǐng)求 ,如https |
| flow.request.path | 請(qǐng)求的路徑,url除域名之外的內(nèi)容 |
| flow.request.get_text() | 請(qǐng)求中body內(nèi)容,有一些http會(huì)把請(qǐng)求參數(shù)放在body里面,那么可通過此方法獲取,返回字典類型 |
| flow.request.query | MultiDictView類型的數(shù)據(jù),url直接帶的鍵值參數(shù) |
| flow.request.get_content() | bytes,結(jié)果如flow.request.get_text() |
| flow.request.raw_content | bytes,結(jié)果如flow.request.get_content() |
| flow.request.urlencoded_form | MultiDictView,content-type:application/x-www-form-urlencoded時(shí)的請(qǐng)求參數(shù),不包含url直接帶的鍵值參數(shù) |
| flow.request.multipart_form | MultiDictView,content-type:multipart/form-data時(shí)的請(qǐng)求參數(shù),不包含url直接帶的鍵值參數(shù) |
| flow.response.status_code | 返回狀態(tài)碼 |
| flow.response.text | 返回內(nèi)容,已解碼 |
| flow.response.content | 返回內(nèi)容,二進(jìn)制 |
| flow.response.setText() | 修改返回內(nèi)容,不需要轉(zhuǎn)碼 |
- 示例:
>>>from mitmproxy import http
>>>def request(flow):
>>> if flow.request.pretty_url == "http://httpbin.org/get":
>>> flow.response = http.HTTPResponse.make(
>>> 200,
>>> b'Hello World!',
>>> {"Content-Type":"text/html"}
>>> )


9.3 關(guān)于Appium
- Appium是一個(gè)跨平臺(tái)移動(dòng)端自動(dòng)化測(cè)試工具,可以看成是Andriod或IOS端的Selenium。
- 能夠在模擬App內(nèi)部的各種操作,比如點(diǎn)擊、滑動(dòng)、輸入等。
9.3.1 安裝Appium
-
點(diǎn)擊此處下載Appium。
如果需要用安卓手機(jī)抓取,則點(diǎn)擊此處下載Android Studio。
-
安裝Andriod Studio后繼續(xù)安裝Android SDK。
-
配置Android SDK環(huán)境變量。
如果使用IOS爬取數(shù)據(jù),則需要在mac電腦上執(zhí)行
xcode-select --install配置環(huán)境。
9.3.2 啟動(dòng)Appium
第一步:打開Appium界面,默認(rèn)端口為4723。

第二步:配置ANDROID_NAME并點(diǎn)擊Start Server啟動(dòng)服務(wù)器。


第三步:將手機(jī)連接數(shù)據(jù)線,并打開USB調(diào)試功能,通過adb指令檢查設(shè)備是否匹配成功。

第四步:點(diǎn)擊Appium界面的Start Inspector Session按鍵。

第五步:找到appPackage和appActivity。
- 在cmd使用
adb logcat指令
- 手機(jī)端打開app
-
查看log.txt
第六步:配置Desired Capablilities中的platformName(平臺(tái)名)、deviceName(設(shè)備名)、appPackage(程序包名)和appActivity(入口Activity名)

第七步:點(diǎn)擊Start Session按鈕
-
如果一切順利,不僅手機(jī)進(jìn)入啟動(dòng)界面,同時(shí)調(diào)試窗口會(huì)顯示頁面源碼。
-
不僅如此,還可以對(duì)元素進(jìn)行操作,比如點(diǎn)擊、輸入、拖拽等。
9.3.3 用Python驅(qū)動(dòng)Appium
- 以豆瓣app為例。
- 首先使用
pip install appium-python-client安裝appium包。 - 確保appium server處于開啟狀態(tài)。
>>>from appium import webdriver
>>>from selenium.webdriver.common.by import By
>>>from selenium.webdriver.support.ui import WebDriverWait
>>>from selenium.webdriver.support import expected_conditions as EC
>>>server = 'http://localhost:4723/wd/hub' # 服務(wù)器地址
>>>desired_caps = {
>>> # 配置desired參數(shù)
>>> "platformName": "Android",
>>> "deviceName": "HUAWEI_mate30_pro",
>>> "appPackage": "com.douban.frodo",
>>> "appActivity": ".activity.SplashActivity"
>>>}
>>>driver = webdriver.Remote(server,desired_caps) # 啟動(dòng)APP
>>>wait = WebDriverWait(driver,30)
>>>next = wait.until(EC.presence_of_all_elements_located((By.ID,'com.douban.frodo:id/next')))[0]
>>>next.click() # 點(diǎn)擊下一步
>>>prim_confirm = wait.until(EC.presence_of_all_elements_located((By.ID,'android:id/button1')))[0]
>>>prim_confirm.click() # 確認(rèn)給予權(quán)限
>>>cancel_login = wait.until(EC.presence_of_all_elements_located((By.ID,'com.douban.frodo:id/close')))[0]
>>>cancel_login.click() # 為了方便演示,這里就先不登錄了
>>># 切換tap刷新頁面
>>>tap_2 = wait.until(EC.presence_of_all_elements_located((By.ID,'com.douban.frodo:id/icon')))[1]
>>>tap_2.click()
>>>tap_1 = wait.until(EC.presence_of_all_elements_located((By.ID,'com.douban.frodo:id/icon')))[0]
>>>tap_1.click()
>>># 獲取推薦內(nèi)容
>>>contents = wait.until(EC.presence_of_all_elements_located((By.ID,'com.douban.frodo:id/status_text')))
>>>for content in contents:
>>> print(content.get_attribute("text"))
現(xiàn)在都懶得攢著,隨手扔了
參考資料
- https://blog.csdn.net/u010138758/article/details/80152151 J-Ombudsman
- https://www.cnblogs.com/zhuluqing/p/8832205.html moisiet
- https://www.runoob.com 菜鳥教程
- http://www.tulingxueyuan.com/ 北京圖靈學(xué)院
- http://www.imooc.com/article/19184?block_id=tuijian_wz#child_5_1 兩點(diǎn)水
- https://blog.csdn.net/weixin_44213550/article/details/91346411 python老菜鳥
- https://realpython.com/python-string-formatting/ Dan Bader
- https://www.liaoxuefeng.com/ 廖雪峰
- https://blog.csdn.net/Gnewocean/article/details/85319590 新海說
- https://www.cnblogs.com/Nicholas0707/p/9021672.html Nicholas
- https://www.cnblogs.com/dalaoban/p/9331113.html 超天大圣
- https://blog.csdn.net/zhubao124/article/details/81662775 zhubao124
- https://blog.csdn.net/z59d8m6e40/article/details/72871485 z59d8m6e40
- http://www.itdecent.cn/p/2b04f5eb5785 MR_ChanHwang
- 《Python學(xué)習(xí)手冊(cè)》Mark Lutz
- 《Python編程 從入門到實(shí)踐》Eric Matthes
- 《Python3網(wǎng)絡(luò)爬蟲開發(fā)實(shí)戰(zhàn)》崔慶才
本文作者:大師兄(superkmi)




























