1. 程式人生 > >Python網路爬蟲——Appuim+夜神模擬器爬取得到APP課程資料

Python網路爬蟲——Appuim+夜神模擬器爬取得到APP課程資料

一、背景介紹

隨著生產力和經濟社會的發展,溫飽問題基本解決,人們開始追求更高層次的精神文明,開始願意為知識和內容付費。從2016年開始,內容付費漸漸成為時尚。 羅輯思維創始人羅振宇全力打造“得到APP”就是這樣一款優質的可以聽音訊、學通識課程、看電子書、看直播、記筆記的知識付費平臺,得到匯聚羅振宇、薛兆豐、樑寧、萬維鋼、吳軍、香帥、寧向東等各個領域的專家學者的精品課程,致力於服務所有終身學習者。

也許你會感到奇怪,得到就是這樣一款只有APP而沒有網頁版的產品,所以傳統的網頁爬取對於爬取得到資料只能是望洋興嘆了。本文用於爬取得到APP的課程資料,包括課程名稱、作者、單價、學習人數等資料,可作為一個爬取APP資料的demo進行分享。

二、APP爬取思路和方案選擇

2.1 思路一

通過抓包軟體對APP進行抓包分析, 這種方式可以看到 App 在執行過程中發生的所有請求和響應。得知介面之後可以通過設定合適的請求頭和各種引數來發送HTTP或者HTTPS請求介面,介面返回的資料就是想要資料了。

這種方式一旦實現,基本上算是一勞永逸的,除非介面和返回資料定義發生變化。但是如果一些動態引數設定不對,訪問介面則不能得到任何資料,換句話說,只要無法破解引數,這條路就是死路一條。

2.2 思路二

通過自動化測試工具模擬手工操作APP進行資料的爬取。通過向自動化測試工具(例如Appium)傳送操作指令,驅動裝置完成點選、輸入、滑動等各種操作,分析頁面資料完成資料爬取。

這種方式相比於方式一而言,並不會受限於請求頭和動態引數,只要是人工可以操作的,自動化測試工具都可以幫助我們進行完成,而所有的APP的所有功能所有頁面使用者都可以進行操作,意味著APP內所有的資料都可以拿到。

2.3 方案選擇

本人在嘗試使用方式一的過程中,抓包分析介面之後發現有些動態引數無法搞定,故放棄該方式。採用方式二進行爬取。

三、準備工作

3.1 Python環境的搭建

下載Python安裝包:官方下載地址

安裝:注意勾選“Add Python 3.8 to PATH”

3.2 Android SDK安裝和環境變數配置

下載Android Studio進行安裝Android SDK:下載地址

預設安裝或者選擇路徑進行安裝即可

環境變數的配置:

變數名稱:ANDROID_HOME
變數值:SDK安裝路徑
在Path變數下面新增:%ANDROID_SDK_HOME%\platform-tools
在Path變數下面新增:%ANDROID_SDK_HOME%\tools

3.3 夜神模擬器安裝和得到APP安裝

夜神模擬器下載:夜神模擬器

夜神模擬器安裝:預設安裝即可。

得到APP下載:得到APP下載

將下載的apk安裝包拖動到夜神模擬器中進行安裝。

3.4 Appium安裝

Appium下載地址: Appium下載

安裝:預設安裝到C盤即可。

配置環境變數:

變數名稱:APPIUM_HOME
變數值:Appium安裝路徑(eg:C:\Program Files\Appium)
在Path變數下面新增:%APPIUM_HOME%

四、爬取核心

4.1 Appium啟動APP

使用Appium啟動APP時需要配置引數:platformName、deviceName、appPackage、appActivity。配置完成之後Appium會自動查詢手機上面的包名和入口類,然後將其啟動。

platformName:平臺名稱,本文使用的是安卓平臺,填寫Android。
deviceName:裝置名稱。
appPackage:APP程式包。
appActivity:程式入口。
  • 獲取appPackage和appActivity的方法:

最簡單有效的方法為使用命令列獲取。使用Appium客戶端連線到APP,將APP開啟到需要獲取appActivity的頁面,執行下面命令:

adb shell
dumpsys activity | grep mFocusedActivity

程式碼如下:

 def __init__(self):
 print("init")
 self.desired_caps = {
 "platformName": "Android",
 "deviceName": "127.0.0.1:62001",
 'platformVersion': '5.1',
 "appPackage": "com.luojilab.player",
 "appActivity": "com.luojilab.business.HomeTabActivity",  # 主頁
 "noReset": True
 }
 self.driver = webdriver.Remote(DRIVER_SERVER, self.desired_caps)
 self.wait = WebDriverWait(self.driver, TIMEOUT)

這段程式碼的作用是使用Appium啟動得到APP並進入主頁。如圖:

4.2 點選“課程”按鈕進入課程頁

本文目的是爬取課程的資料,所以需要點選課程進入課程頁。人的操作是這樣的的,首先在課程頁面找到課程按鈕,然後點選。程式的操作也是一樣的:首先要定位到“課程”這個按鈕,然後進行點選。

使用Appium定位元素

點選選中左邊“課程”按鈕,可以看到這個元素的原始碼,通過xpath定位:

course = self.driver.find_element_by_xpath("//android.widget.TextView[@text='課程']") # 課程

Appium可以進行點選的操作。點選課程按鈕的程式碼如下:course.click()

4.3 定義課程資料類

課程頁面如圖所示:

從課程頁面可以看到,一門課程展現出來的資料有:課程名稱、課程摘要、作者姓名和頭銜、單價以及銷量。

從面向物件的思想來說,課程就是一個物件,這個物件有如下屬性:課程名稱、課程摘要、作者姓名和頭銜、單價以及銷量。用程式碼表示就是這樣的:

class CourseData(object):
 def __init__(self, course_name, summary, lecturer_name_and_title, price, subscribe_num):
 super().__init__()
 self.course_name = course_name
 self.summary = summary
 self.lecturer_name_and_title = lecturer_name_and_title
 self.price = price
 self.subscribe_num = subscribe_num

4.4 獲取所有課程資料

通過Appium分析頁面的原始碼,可以很容易解析得到課程的各種資料。

程式碼如下:

course_names = temp.find_element_by_id('com.luojilab.player:id/column_name') #課程名稱
summaries = temp.find_element_by_id('com.luojilab.player:id/summary') # 摘要
lecturer_name_and_titles = temp.find_element_by_id(
'com.luojilab.player:id/tv_name_and_title') # 講師
prices = temp.find_element_by_id('com.luojilab.player:id/price') #價格
subscribe_nums = temp.find_element_by_id('com.luojilab.player:id/tv_subscribe_num') # 價格

當獲取完一屏的資料,需要向上滑動繼續獲取資料。

Appium滑動API說明:

方法:swipe(int start x,int start y,int end x,int y,duration) 
引數說明:
int start x:開始滑動的x座標;
int start y:開始滑動的y座標 ;
int end x:結束點x座標;
int end y:結束點y座標; 
duration:滑動時間。

本文是從螢幕下部滑動到螢幕上部,滑動時間為2000ms。具體程式碼為:

self.driver.swipe(FLICK_START_X, FLICK_START_Y, FLICK_START_X,
 FLICK_START_Y + FLICK_DISTANCE,
 2000)

當無法滑動的時候,資料就獲取完成了。

4.5 課程資料寫入Excel

資料獲取完成之後需要進行儲存。Python中有專門操作Excel的庫:openpyxl。本文使用openpyxl將爬取到的資料寫入Excel進行儲存。核心程式碼如下:

# 定義資料輸出的Excel
try:
 wb = openpyxl.load_workbook(PATH)
except:
 wb = openpyxl.Workbook()
# wb = openpyxl.Workbook()
sheet_name = time.strftime("%F")
sheet = wb.create_sheet(sheet_name)
row = ["學院", "課程名稱", "課程摘要", "主講人", "單價", "銷量", "銷售金額"]
sheet.append(row)
...
wb.save(PATH)

五、總結

本文使用Appium和夜神模擬器在Windows平臺上面實現得到課程資料的爬取。這裡給出GitHub程式碼供大家學習,程式適用於最新版得到APP的課程資料爬取,如遇到APP版本升級等特殊情況,程式也需要進行升級維護。

GitHub地址