是我小看這臺(tái)舊手機(jī)了!
大家好,我是 Jack。
上個(gè)月發(fā)布了一期視頻,里面用到了代碼操控手機(jī)的自動(dòng)化技巧。
今天就詳細(xì)聊下,我是怎么做的。
Scrcpy
Scrcpy,全稱 screen copy,是一款開源的手機(jī)無線投屏軟件。

而且還是跨平臺(tái)的,無論是在 Linux、Windows 還是 macOS 上都能使用。
項(xiàng)目地址:
https://github.com/Genymobile/scrcpy
這里以 Windows 為例,安裝起來非常簡(jiǎn)單:

直接下載安裝包并解壓就行,里面還帶了adb調(diào)試工具。
然后添加一下系統(tǒng)的環(huán)境變量。

用 USB 線連接手機(jī)和電腦,將手機(jī)調(diào)整為開發(fā)者模式。

這樣,在電腦上運(yùn)行 Scrcpy 指令:
scrcpy
就能將手機(jī)畫面投放到電腦上了。

我們可以通過這個(gè)投放的畫面,在電腦上,操縱這臺(tái)手機(jī)。
但是,如果想要讓代碼自動(dòng)化控制,那就還需要另外一款工具。
uiautomator2
UiAutomator 是 Google 提供的用來做安卓自動(dòng)化測(cè)試的一個(gè) Java 庫(kù),基于 Accessibility 服務(wù)。功能很強(qiáng),可以對(duì)第三方 App 進(jìn)行測(cè)試,獲取屏幕上任意一個(gè) APP 的任意一個(gè)控件屬性,并對(duì)其進(jìn)行任意操作,但有兩個(gè)限制:
測(cè)試腳本只能使用 Java 語(yǔ)言 測(cè)試腳本要打包成 jar 或者 apk 包上傳到設(shè)備上才能運(yùn)行
于是有了 UiAutomator2,邏輯可以用 Python 編寫,能夠在電腦上控制手機(jī)。
項(xiàng)目地址:
https://github.com/openatx/uiautomator2
安裝方法也非常簡(jiǎn)單,直接 pip 安裝即可,不過為了方便環(huán)境的管理,還是先創(chuàng)建一個(gè) Conda 虛擬環(huán)境。
conda create -n android
然后激活這個(gè)虛擬環(huán)境:
conda activate android
安裝 uiautomator2 和 weditor。
python -m pip install uiautomator2 weditor
然后用手機(jī)打開想要操控的 App,比如 BiliBili,打開軟件后,使用 Weditor 審查元素。
python -m weditor
這樣就開啟了一個(gè) Web 界面,在這個(gè)界面里,能夠?qū)彶樵兀?strong>定位一些想要點(diǎn)擊的點(diǎn)。

比如我想要給一個(gè)視頻三連,那就審查三連的元素,然后將操作用代碼流程化。
import uiautomator2 as u2
import time
from PIL import Image
import cv2
import numpy as np
all_videos = []
def get_images(device):
views = device.xpath('//*[@resource-id="tv.danmaku.bili:id/recycler_view"]/android.view.ViewGroup/android.widget.FrameLayout[1]')
for idx, view_box in enumerate(views.all()[:5]):
print("視頻{} 封面的中心坐標(biāo):".format(idx+1), view_box.center())
image = view_box.screenshot()
image.save("{}.jpg".format(idx+1))
all_videos.append(view_box)
def refresh(device):
device.swipe_ext("down")
def like_the_video(device):
like_icon = device.xpath('//*[@resource-id="tv.danmaku.bili:id/recommend_icon"]')
like_icon.click()
print("視頻點(diǎn)贊成功")
def pay_for_the_video(device):
coin_icon = device.xpath('//*[@resource-id="tv.danmaku.bili:id/coin_icon"]')
coin_icon.click()
time.sleep(0.1)
pay_icon = device.xpath('//*[@resource-id="tv.danmaku.bili:id/pay_coins"]')
pay_icon.click()
print("視頻投幣成功")
def follow_the_up(device):
follow_icon = device.xpath('//*[@resource-id="tv.danmaku.bili:id/follow"]')
follow_icon.click()
print("關(guān)注成功")
def back(device):
back_icon = device.xpath('//*[@content-desc="轉(zhuǎn)到上一層級(jí)"]')
back_icon.click()
print("已退出視頻")
if __name__ == "__main__":
_DEVICE_ID = 'da317199'
d = u2.connect(_DEVICE_ID) # connect to device
get_images(d)
all_videos[3].click()
print("點(diǎn)進(jìn)去了!")
time.sleep(0.1)
like_the_video(d)
time.sleep(0.1)
pay_for_the_video(d)
time.sleep(0.1)
follow_the_up(d)
效果是這樣的:

代碼里有個(gè) device_id 可以通過 adb 工具查詢,手機(jī)連接電腦后,再用如下指令查詢:
adb devices
根據(jù)這個(gè)設(shè)備號(hào),就能操縱這臺(tái)手機(jī)。
絮叨
這東西,還能用來做什么?
你知道,為啥搶茅臺(tái)你總搶不到嗎?搶個(gè)演唱會(huì)門票搶不到?掛號(hào)掛不到?
票販子為啥總能搶到票?
很多平臺(tái)限制必須手機(jī)上搶,這個(gè)時(shí)候,這項(xiàng)技術(shù)就能排上用場(chǎng)了。
我只能幫你到這了,剩下的,可以自己慢慢體驗(yàn)。
所以,家里的舊手機(jī)不要扔!寫個(gè)腳本,能幫你干很多事~
對(duì)了,上周說會(huì)出一期新視頻,這個(gè)周末應(yīng)該能做完。
上個(gè)周末高中老同學(xué)聚會(huì),都是“小鎮(zhèn)做題家”,來到北京工作,一晃也都老大不小了。
有在國(guó)企工作的,錢雖少點(diǎn),但很安逸,沒有裁員。有在私企打拼的,錢雖多點(diǎn),但頻繁跳槽,壓力也蠻大。
能聚一次,很不容易,所以耽擱了點(diǎn)時(shí)間,望海涵~
好了,今天就聊這么多吧。
我是 Jack,我們下期見~

推薦閱讀
? AI殺瘋了,NovelAI開源? 巧了,這幾個(gè)項(xiàng)目,我王多魚投(喂)了!? 今年這情況。。咱還是留個(gè)心眼吧
