我要爬爬蟲(15)用appium爬取手機QQ音樂歌名

我想爬一下QQ音樂的我喜歡的歌單裏的VIP歌曲的歌名,想知道哪些歌曲是vip歌曲,獲取一個歌名清單。
分別試了網頁版和windows版以及官方PC版,可是網頁版的歌單顯示不全,只顯示前幾十首歌,之前還是顯示完全的,應該是最近一段時間變更的;而windows商店裏自帶的版本不顯示VIP歌曲。
本來打算用Charles來監聽qq音樂PC版的,可是監聽到的請求,其中的歌曲數據經過了加密,獲取不到,我還是會得太少了。。。
所以就打算用appium,類似於移動端的selenium,對於移動端的頁面進行操作。

安裝Appium

首先在電腦中安裝Android sdk。
將Android sdk的路徑保存爲Android_Home寫進環境變量,sdk文件夾下的tools和platform-tools寫入path裏。
本機是要安裝jdk的,一開始不知道一運行就閃退。。。同樣把jdk的路徑也寫入環境變量。
最後將手機與電腦連接,安裝Appium,手機上自動安裝Appium Settings和Unlock。

連接手機

打開Appium,出現的是日誌界面,
日誌界面
點擊右上角的放大鏡,進入Automatic Server.
在Automatic Server中設定Desired Capabilities,分別是
platformName(操作系統名),
deviceName(設備名),
appPackage和appActivity,這兩個是具體某個app的信息,noReset(啓動app時不要清除app裏的原有的數據,設爲True)
其中deviceName可以在手機設置中查看,也可以連接電腦後在cmd中通過命令來查看

adb devices -l

可能出現報錯的情況
報錯
重啓電腦或者確認手機開發者模式是否開啓。

List of devices attached

而appPackage和appActivity可以在開啓某個app後通過命令來查看。

adb.exe shell dumpsys window |findstr mCurrent

連接手機
上圖即爲打開手機qq音樂的連接配置。
配置完畢後,點擊 Start Session連接。
手機會自動打開qq音樂,app source中也可以看到出現qq音樂的操作界面。
qq音樂主界面
如果手機設置密碼,那麼手機會停在鎖屏界面,app source亦然。
如果VIP剛剛過期,還可能有vip的彈窗廣告。。。這些都會影響操作。

代碼邏輯設計

根據qq音樂的UI特點,打開app後的操作步驟應爲
1 點擊 我的
2 點擊 喜歡
3 獲得當前界面下所有的vip歌曲的歌名,作者,專輯。
4 向下滑動手機屏幕。
5 重複3,4,直至滑動至歌單底部。

需要pythonAppium-Python-Client模塊中的webdriver類建立連接對象。
selenium模塊的一些方法可以模擬appium軟件中的操作。
定義連接時,分別定義webdriver對象的server和attrs。server爲http://localhost:4723/wd/hub,localhost就是連接本地,4723爲appium的服務端口號,wd即爲webdriver的縮寫,hub 是指主(中心) 節點,在selenium 分佈式裏中心節點。所以/wd/hub可以理解爲appium的規定地址。attrs即爲剛纔Appium軟件中Desired Capabilities那些選項。

self.attrs = {
            "platformName": "Android",
            "deviceName": "DUK_AL20",
            "appPackage": "com.tencent.qqmusic",
            "appActivity": "com.tencent.qqmusic.activity.AppStarterActivity",
            "noReset": "True"
        }
        self.server = 'http://localhost:4723/wd/hub'
        self.driver = webdriver.Remote(self.server,self.attrs)

建立連接後即可打開手機qq音樂,進入其主界面。

1,2點擊

首先需要定位 我的 按鈕,已知其accessibility id=我的,所以可以通過find_element_by_accessibility_id來定位按鈕。然後使用click()方法點擊即可。
我的按鈕
然後界面跳轉到 我的 界面,以同樣的方法點擊 喜歡 即可。由於界面刷新有延遲,可以使用WebDriverWait()方法等待2s再點擊。
喜歡按鈕

3 獲取歌曲信息

進入我喜歡的歌單後,需要定位每一首歌,並判斷其是否爲vip歌曲。
每一首歌曲
可以定位到歌曲的歌名和歌曲信息,均可以通過元素的text值獲取到文本信息。通過定位vip元素,如果能找到該元素則爲vip歌曲,反之則不是。
歌曲元素
使用find_elements_by_id定位到當前界面的所有歌曲,然後遍歷每一首歌,同樣使用find_element_by_id定位每首歌的vip元素,如果定位到則獲取歌名和歌曲信息,反之則捕獲異常並跳過這首歌。將捕獲到的信息寫入文本文件中。
值得注意的是,爲了反爬蟲的需要,qq音樂中的元素名稱有時候會變化,比如歌曲的resource_id並不一定是com.tencent.qqmusic:id/aqi,所以代碼運行前需要檢查一下元素名。

4 滑動

當前屏幕中的vip歌曲獲取完畢後,下滑屏幕獲取新的歌曲。這裏用到webdriver的swipe()方法,在方法中分別設定滑動軌跡起始點和終點的座標即可。例如

swipe(start_x=1256, start_y=1931, end_x=1388, end_y=780, duration=1500)

start_x,start_y,end_x,end_y分別對應滑動軌跡起始點和終點的橫縱座標。
duration爲滑動時間,這決定滑動的速度。
元素的bounds值爲元素的左上角和右下角的座標,可以參照它設定始終點的座標。
定位元素
由於觸屏手機滑動是有慣性設定的,手指離開屏幕後,屏幕依然會遵循原來的軌跡繼續滑行一段距離,之前手指滑動的越快,手指離開後屏幕繼續滑動的越遠。所以這裏滑動時間duration可以適當設置長一點,讓滑動速度慢一些,避免屏幕繼續向下滑動,導致錯過一些歌曲。爲此,滑動的終點座標也應該設定適當在下面一些。
在這裏插入圖片描述
如圖,end點不要設定的太高,滑動距離短一點,給慣性一點緩衝距離。

5 滑動次數

簡單來說,就是設定滑動幾下。歌單的總歌曲數是知道的,大約900首,一個屏幕最多顯示7首,所以設計滑動大約130下即可。

總結

最終獲取到VIP的歌單,所有VIP歌曲的名字。
獲取到歌單
最終結果不是特別理想,
1 速度比較慢,定位屏幕中的7首歌的元素本身就很慢,而且爲了保證數據完全刷新出來,在很多操作之間需要設計等待,這也會耽擱一些時間。
2 由於怕漏掉一些歌曲,所以滑動的比較謹慎,滑動距離設計的比較小,這也導致歌曲被重複獲取(上一個屏幕底部獲取到,又在下一個屏幕頂部獲取到),後面還得做去重處理。
不過目的還是達到了,確實獲取到了vip歌單,而且沒有漏掉的歌曲。

參考

appium自動化爬蟲
Android查看appPackage和Activity的多種方法
"http://127.0.0.1:4723/wd/hub"的解釋

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