薅羊毛 | Python 帶你搶視頻紅包,不放過一個紅包!

薅羊毛 | Python 帶你搶視頻紅包,不放過一個紅包!

1


目 標 場 景

現在短視頻橫行的時代,以某短視頻爲首的,背後依靠着強大的資金後盾,瘋狂地對平臺用戶進行紅包轟炸。shell

薅羊毛 | Python 帶你搶視頻紅包,不放過一個紅包!

與傳統的紅包不同,視頻紅包包含位置的不肯定性、大小不肯定性、元素 ID 的不肯定性等......這些不肯定性都會致使搶紅包的操做變得異常的複雜。app

本篇文章的目的是利用 Python 自動化實現「搶視頻紅包」這一騷操做。異步

ps:本文僅用做學習交流,請勿用於其餘用途。ide

2


準 備 工 做

在開始編寫腳本以前,須要作以下準備工具

一、一部 Android 手機,並在 PC 端配置好 ADB 運行環境學習

二、Python 虛擬環境下安裝自動化依賴庫、圖片對比依賴庫測試

三、PS 或者其餘圖片編輯軟件ui

# 自動化依賴
pip3 install pocoui

# 圖片對比依賴
pip3 install aircv

3

編 寫 代 碼

第一步,咱們須要藉助 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)

第一次打開應用的時候,會彈出一個警告對話框。
薅羊毛 | Python 帶你搶視頻紅包,不放過一個紅包!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()

第二步,「判斷」當前播放的視頻是不是一個包含紅包的視頻。

經過對大量視頻的觀察,能夠看出視頻內包含兩類紅包,分別是普通視頻紅包、問答視頻紅包。

薅羊毛 | Python 帶你搶視頻紅包,不放過一個紅包!

經過 Android SDK 自動的工具 Monitor 查看界面元素。

惋惜的是,這個互動紅包元素標識「元素 ID 不存在」,而且 Text 屬性也爲空,無法利用傳統的方式來獲取到。

薅羊毛 | Python 帶你搶視頻紅包,不放過一個紅包!

我換一種方式來實現,利用「圖片對比」技術來判斷互動紅包元素是否存在,進而判斷視頻是不是一個包含紅包的視頻。

利用「PS」把互動紅包元素圖片從屏幕截圖中裁剪出來。

須要注意的是,因爲這個元素形狀不規則,這裏只能裁剪一個規則的矩形區域,不能截取其餘多餘的區域,不然會致使圖片比對會失敗。
薅羊毛 | Python 帶你搶視頻紅包,不放過一個紅包!

接着利用 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 屬性。
薅羊毛 | Python 帶你搶視頻紅包,不放過一個紅包!

而後我首先想到是否能夠利用上面的方式,經過局部圖片匹配去拿到紅包圖片的中心點座標。

薅羊毛 | Python 帶你搶視頻紅包,不放過一個紅包!

但是經過大量的測試發現,視頻中紅包圖片元素的大小「存在不肯定性」,用 PS 截取的圖片不能適用於全部視頻。

薅羊毛 | Python 帶你搶視頻紅包,不放過一個紅包!

最後,只能經過分析元素的層次結構,拿到存在元素 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 屬性以後,就能夠計算出紅包圖片元素的中心點座標。
薅羊毛 | Python 帶你搶視頻紅包,不放過一個紅包!

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]))

4


結 果 結 論

經過上面的操做,完成了搶普通視頻紅包的操做,循環操做就能夠拿到應用內的全部的普通視頻紅包。

針對問答視頻紅包,利用 Monitor 能夠直接拿到題目和答案的文本內容,這須要針對題目內容和答案進行一次匹配。

我已經將源碼上傳到後臺上,關注公衆號後回覆「 ws 」便可得到下載連接。

若是你以爲文章還不錯,請你們點贊分享下。你的確定是我最大的鼓勵和支持。

推薦閱讀:

要搶紅包?Python來幫你~

薅羊毛 | 讓Python天天幫你薅一個早餐錢

THANDKS

-End -

相關文章
相關標籤/搜索