現在短視頻橫行的時代,以某短視頻爲首的,背後依靠着強大的資金後盾,瘋狂地對平臺用戶進行紅包轟炸。shell
與傳統的紅包不同,視頻紅包包含位置的不肯定性、大小不肯定性、元素 ID 的不肯定性等......這些不肯定性都會致使搶紅包的操做變得異常的複雜。app
本篇文章的目的是利用 Python 自動化實現「搶視頻紅包」這一騷操做。異步
ps:本文僅用做學習交流,請勿用於其餘用途。ide
在開始編寫腳本以前,須要作以下準備工具
一、一部 Android 手機,並在 PC 端配置好 ADB 運行環境學習
二、Python 虛擬環境下安裝自動化依賴庫、圖片對比依賴庫測試
三、PS 或者其餘圖片編輯軟件ui
# 自動化依賴 pip3 install pocoui # 圖片對比依賴 pip3 install aircv
第一步,咱們須要藉助 Airtest 驅動手機打開目標短視頻 App。線程
# 目標應用的包名和LaunchActivity self.package_name = 'com.**.weishi' self.home_activity = 'com.**.oscar.module.splash.SplashActivity' # 回到主界面 home() # stop_app(self.package_name) # 打開應用 start_my_app(self.package_name, self.home_activity)
第一次打開應用的時候,會彈出一個警告對話框。3d
這裏利用「異步線程」去處理。
循環檢測對話框元素是否存在,一旦出現,就模擬點擊操做,關閉這個對話框。
def __handle_dialog(self): """ 處理警告對話框 :return: """ count = 0 while count < self.wait_for_dialog_timeout: tip_notice = self.poco('com.tencent.weishi:id/title_text', text=u'青少年保護功能提示') try: if tip_notice.exists(): # 關閉 print('出現警告對話框,關閉之。') self.poco('com.tencent.weishi:id/close_btn').click() break else: pass except Exception as e: print('產生異常了') time.sleep(1) count += 1 # 異步處理 threading.Thread(target=self.__handle_dialog, name='thread1').start()
第二步,「判斷」當前播放的視頻是不是一個包含紅包的視頻。
經過對大量視頻的觀察,能夠看出視頻內包含兩類紅包,分別是普通視頻紅包、問答視頻紅包。
經過 Android SDK 自動的工具 Monitor 查看界面元素。
惋惜的是,這個互動紅包元素標識「元素 ID 不存在」,而且 Text 屬性也爲空,無法利用傳統的方式來獲取到。
我換一種方式來實現,利用「圖片對比」技術來判斷互動紅包元素是否存在,進而判斷視頻是不是一個包含紅包的視頻。
利用「PS」把互動紅包元素圖片從屏幕截圖中裁剪出來。
須要注意的是,因爲這個元素形狀不規則,這裏只能裁剪一個規則的矩形區域,不能截取其餘多餘的區域,不然會致使圖片比對會失敗。
接着利用 adb 命令截取手機屏幕的圖片,而後保存到本地。
def save_screenshot_to_pc(desc): """ 獲取屏幕截圖 desc 截圖保存路徑 :return: """ exec_cmd('adb shell /system/bin/screencap -p /sdcard/screenshot.png') exec_cmd('adb pull /sdcard/screenshot.png %s' % desc)
而後就能夠利用「aircv」庫,利用上面裁剪的圖和屏幕截圖進行比對,判斷裁剪的互動紅包元素是否能匹配到。
當匹配指數爲 0.8 以上的時候,就認爲當前視頻內必定包含紅包。
def find_image(source_path, part_path): """ 匹配模板 :param source_path: 原圖片 :param part_path: 待匹配的圖片 :return: """ # 原始圖像 source = ac.imread(source_path) # 待查找的部分 part = ac.imread(part_path) result_raw = ac.find_template(source, part) # 匹配圖片中心點座標 if result_raw and result_raw.get('confidence') >= 0.8: center_position = result_raw.get('result') print(result_raw) else: center_position = None return center_position
第三步,若是判斷當前視頻內包含互動紅包元素,就能夠執行「搶紅包」的操做了。
首先,利用 Monitor 截取紅包出現那一刻的界面元素樹,依然能夠看到紅包圖片元素不存在 ID 和 Text 屬性。
而後我首先想到是否能夠利用上面的方式,經過局部圖片匹配去拿到紅包圖片的中心點座標。
但是經過大量的測試發現,視頻中紅包圖片元素的大小「存在不肯定性」,用 PS 截取的圖片不能適用於全部視頻。
最後,只能經過分析元素的層次結構,拿到存在元素 ID 的最近一級父類元素,而後再去獲得紅包元素,進而獲得「bound」屬性值。
vp = self.poco('com.tencent.weishi:id/hippy_container') if vp.exists(): # 元素 try: red_package_element = vp.children()[0].children()[0].children()[0].children()[0] except Exception: print('產生一個異常') continue # 獲取bound()屬性 element_size = red_package_element.get_bounds()
拿到紅包圖片元素的 bound 屬性以後,就能夠計算出紅包圖片元素的中心點座標。
def get_element_center_position(poco, bound): """ 獲取元素的中心點座標 :return: """ # 獲取手機屏幕的寬、高 screen_width = poco.get_screen_size()[0] screen_height = poco.get_screen_size()[1] # 元素的中心點座標 center_position = (bound[1] + bound[-1]) / 2 * screen_width, ( bound[0] + bound[2]) / 2 * screen_height return center_position
咱們都知道一段視頻中,紅包出現的時間存在不肯定性。
經過對紅包圖片出現前和出現後的元素樹進行對比,能夠發現,當紅包出現的時候,紅包圖片元素「存在多個子元素」。
所以能夠循環獲取 UI 元素樹,直到紅包元素存在子元素的時候,就退出循環。
# 一直等待紅包元素出現,才執行點擊操做 if len(red_package_element.children()) > 0: print(center_position) break else: # print('等待紅包出現能夠點擊') pass
經過點擊紅包元素的「中心點座標」,就能夠完成搶視頻紅包的最後操做。
# 獲取到紅包座標以後,執行點擊點擊操做,直到搶到紅包爲止 exec_cmd('adb shell input tap %d %d' % (center_position[0], center_position[1]))
經過上面的操做,完成了搶普通視頻紅包的操做,循環操做就能夠拿到應用內的全部的普通視頻紅包。
針對問答視頻紅包,利用 Monitor 能夠直接拿到題目和答案的文本內容,這須要針對題目內容和答案進行一次匹配。
我已經將源碼上傳到後臺上,關注公衆號後回覆「 ws 」便可得到下載連接。
若是你以爲文章還不錯,請你們點贊分享下。你的確定是我最大的鼓勵和支持。
推薦閱讀:
要搶紅包?Python來幫你~
薅羊毛 | 讓Python天天幫你薅一個早餐錢
THANDKS
-End -