不懂抓包也能做APP爬蟲?1招教你爬取抖音流行歌名


前言

說起APP爬蟲,相信大家會很容易聯想到一些抓包工具:Fiddler、Charles、mitmproxy和anyproxy等等。

借助這些抓包工具,我們可以知道APP在運行過程中具體發起了什么請求,之后我們就可以詳細分析這些請求,再用程序模擬這些請求最終實現爬蟲。

然而,在爬蟲的實操中,APP的各種反爬措施也是不容小覷的,比如抓包失敗、參數加密、代碼被編譯等等,都增加了我們爬取APP數據的難度。

那么作為一名不懂抓包的小白,是不是就無緣爬蟲了呢?不要慌,今天我們就帶大家 用airtest來實現1個模擬抓取的過程 ,把網易雲音樂中抖音排行榜的100首歌曲名稱爬取下來!

准備工作

為了 爬取抖音排行榜100首歌曲的名稱 ,首先我們需要編寫1個自動化腳本,在APP內打開這個排行榜,步驟如下:

  • 1.連接測試設備
  • 2.打開網易雲音樂的APP
  • 3.初始化poco
  • 4.同意首頁的服務條款彈窗
  • 5.勾選用戶協議並點擊立即體驗
  • 6.點擊輸入按鈕並輸入“抖音”
  • 7.點擊搜索關鍵詞並等待排行榜加載
  • 8.點擊進入抖音排行榜

代碼實現如下:

復制代碼
# -*- encoding=utf8 -*-
__author__ = "AirtestProject"
from airtest.core.api import *
auto_setup(__file__,devices=["Android://127.0.0.1:5037/emulator-5554"])

clear_app("com.netease.cloudmusic")
start_app("com.netease.cloudmusic")
sleep(1.0)

from poco.drivers.android.uiautomation import AndroidUiautomationPoco
poco = AndroidUiautomationPoco(use_airtest_input=True, screenshot_each_action=False)

# 同意服務條款
poco("com.netease.cloudmusic:id/agree").click()

wait(Template(r"tpl1595916981414.png", record_pos=(0.004, -0.452), resolution=(900, 1600)))
sleep(2.0)

# 勾選用戶協議並點擊立即體驗
poco("com.netease.cloudmusic:id/agreeCheckbox").click()
poco("com.netease.cloudmusic:id/trial").click()
sleep(2.0)

poco("搜索").wait_for_appearance()
sleep(1.0)
# 點擊搜索按鈕並輸入“抖音”
poco("搜索").click()
sleep(1.0)

poco("com.netease.cloudmusic:id/search_src_text").click()
poco("com.netease.cloudmusic:id/search_src_text").set_text("抖音")
sleep(1.0)
poco.click([0.14,0.13])

assert_exists(Template(r"tpl1595821867472.png", record_pos=(-0.283, -0.489), resolution=(900, 1600)), "找到抖音排行榜")

# 點擊進入抖音排行榜
poco("com.netease.cloudmusic:id/title").click()
復制代碼

 

其中需要注意的是poco的初始化順序,先連接設備,再打開APP,最后才初始化poco,可以有效避免一些奇奇怪怪的錯誤。

爬取歌名

進入抖音排行榜的歌曲列表之后,我們先來觀察下此刻的UI樹結構:

從UI樹中我們可以知道,歌曲名稱這個控件,都在 musicListItemContainer 這個控件里面,所以為了獲取歌曲名稱,首先我們需要遍歷所有加載出來的 musicListItemContainer ,再定位到歌曲名稱的控件,依此來獲取控件的 text 屬性:

for title in poco("com.netease.cloudmusic:id/musicInfoList").child("com.netease.cloudmusic:id/musicListItemContainer"):
    a = title.offspring("com.netease.cloudmusic:id/songName")
    name = a.get_text()
    print(a)

 

獲取完當前頁面加載的所有歌曲名稱之后,我們可以通過向上滑動列表,來不斷加載新的歌曲控件。

但這時候,我們還需要解決2個問題:

① 我們單次向上滑動歌曲列表,並不能保證當前加載出來的歌曲控件都是新的控件,有可能某些控件里面的歌曲名稱我們已經獲取到了,那么 如何解決獲取歌名重復的問題呢 ?

我們可以事先定義好1個空的數組,將獲取到的歌曲名稱放到數組里面,在放入歌曲名稱之前,做1個判斷,放入數組的歌名不能與數組已經存在的歌名相同,這樣子就能夠保證我們每次放入的都是新的歌名;

② 多次滑動列表之后,我們 如何判斷所有歌曲名稱已經獲取完畢呢 ?很簡單,我們可以設置1個數組長度的計數器,當數組長度不再增加,即沒有新的名字被添加到數組的時候,既可以認為我們已經把排行榜的歌曲名稱獲取完了。

最終實現的效果如下:

復制代碼
# 定義1個空數組用於存放排行榜的歌名
titles = []
# 定義數組目前的長度和最終的長度
current_count, last_count = len(titles), len(titles)

while True:
    last_count = len(titles)
    for title in poco("com.netease.cloudmusic:id/musicInfoList").child("com.netease.cloudmusic:id/musicListItemContainer"):
        a = title.offspring("com.netease.cloudmusic:id/songName")
        if not a.exists():
            continue
        name = a.get_text()
        if not name in titles:
            titles.append(name)
            print(name)
    
    current_count = len(titles)
    poco.swipe([0.5,0.7],[0.5,0.1],duration=2)
    sleep(1.0)
    
    # 當倆者數值相等,即current_count不再增加時,表明爬取完畢
    if current_count == last_count:
        print("總共爬取"+str(last_count)+"首歌曲的名稱")
        break
復制代碼

 

小結

上述就是利用airtest實現模擬爬取的全部過程。當然,我們不僅可以把爬取的歌曲名稱打印在log查看窗中,還可以將它保存在指定的文檔中,這個大家可以嘗試着自己實現一下。

 


Airtest官網:http://airtest.netease.com/
Airtest教程官網:https://airtest.doc.io.netease.com/
搭建企業私有雲服務:https://airlab.163.com/b2b


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM