python 安卓库_python 库实战 - 安卓简易自动化框架
主要功能:
0、安裝、啟動(dòng)、卸載app
1、模擬點(diǎn)擊(基于坐標(biāo))
2、模擬滑動(dòng)(基于坐標(biāo))
3、文本輸入(支持中文輸入)
4、屏幕截圖
3、文本識別(用于斷言)
4、圖片識別(用于斷言)
廢話不多說,代碼比較清楚
#-- coding: utf-8 --
import sys,os
from PIL import Image
import pytesseract
import time
import cv2 as cv
import numpy as np
"""
使用前提:
1、 本地需要有adb,并且配置了環(huán)境變量
2、 檢查設(shè)備連接狀態(tài)的時(shí)候只檢查了是否有模擬器,并且只能一個(gè)設(shè)備,如果有其他需求可以自行修改 check_devices_state 函數(shù)即可
3、 使用了圖片文字識別工具(安裝好后需要配置環(huán)境變量):http://digi.bib.uni-mannheim.de/tesseract/tesseract-ocr-setup-4.00.00dev.exe 下載好安裝的時(shí)候需要勾選下載所有語言庫。單獨(dú)中文語言庫安裝路徑:https://github.com/tesseract-ocr/tessdata/find/master/chi_sim.traineddata
4、 使用到了第三方庫:PIL(這是一個(gè)圖片處理庫) , 使用 pip install Pillow 命令進(jìn)行安裝
5、 需要使用三方庫:pytesseract(這是一個(gè)圖片文字識別庫), 使用 pip install pytesseract 命令進(jìn)行安裝(如果已經(jīng)配置過tesseract的環(huán)境變量則不需要額外配置)
6、 需要使用第三方庫:numpy和cv2 用于做圖片圖片匹配使用,分別使用領(lǐng)命 pip install opencv-python 和 pip install numpy 進(jìn)行安裝
"""
#-- coding: utf-8 --
import sys,os
from PIL import Image
import pytesseract
import time
import cv2 as cv
import numpy as np
sys.path.append("E:\\myPython\\autoTest")
from printColor import winColor # 導(dǎo)入自己的方法庫
# 安卓基礎(chǔ)類
class Android_auto_test:
# 檢查設(shè)備連接狀態(tài)的函數(shù),只適用于模擬器
def check_devices_state(self):
flag = 0
while flag < 3:
command_result = str(os.popen("adb devices").readlines())
if "127.0.0.1" in command_result or "emulator-5554" in command_result:
return True
else:
print("未檢測到設(shè)備,重啟adb服務(wù)... ...")
os.system("adb kill-server")
os.system("adb start-server")
flag = flag+1
winColor().print_red_text("Error:未找到模擬器設(shè)備,請確認(rèn)模擬器設(shè)備是否存在")
exit(0)
# 安裝apk,傳入apk路徑
def install_apk(self, apkPath):
self.check_devices_state()
try:
os.system("adb install -r {}".format(apkPath))
except:
winColor().print_red_text("Error: install faild")
exit(0)
# 卸載apk,傳入包名進(jìn)行卸載
def uninstall_apk(self, packageName):
self.check_devices_state()
os.system("adb uninstall {}".format(packageName))
# 獲取apk包名。需要使用aapt命令,請確保本地有該命令的運(yùn)行環(huán)境先
def get_package_name(self, apkPath):
command_result_name = os.popen("aapt dump badging {} | findstr name".format(apkPath)).read()
packageName = command_result_name.split()[1].split("'")[1]
command_result_activty = os.popen("aapt dump badging {} | findstr activity".format(apkPath)).read()
launchActivityName = command_result_activty.split()[1].split("'")[1]
return packageName, launchActivityName
# 啟動(dòng)游戲
def launch_game(self, packageName, launchActivity):
self.check_devices_state()
try:
os.system(r"adb shell am start {}/{}".format(packageName, launchActivity))
except:
winColor().print_red_text("Error: 啟動(dòng)失敗, 需要用 包名/包名.activity名 來啟動(dòng)游戲")
X, Y = 0, 0
def __init__(self):
self.check_devices_state()
X, Y = os.popen("adb shell wm size").read().strip().split(":")[-1].strip().split("x") # 獲取模擬器尺寸
# 截圖,返回截圖存放路徑??勺远x截圖尺寸,需要傳入左上角x,y和右下角x,y
def screencap(self, startX = 0, startY = 0, endX = X, endY = Y):
self.check_devices_state()
os.system("adb shell screencap /data/local/tmp/test.png")
os.system("adb pull /data/local/tmp/test.png tmp.png")
if endX != self.X:
img = Image.open("tmp.png")
cropped = img.crop((startX, startY, endX, endY)) # (left, upper, right, lower)
cropped.save("tmp.png")
pypath = os.path.realpath( os.path.dirname(__file__) )
return os.path.join(pypath, "tmp.png")
# 識別圖片中的文字。對圖片進(jìn)行灰度、二化值處理
def get_picture_str(self, picturePath, colorValue = None):
# 實(shí)際多次測試后發(fā)現(xiàn),對于我們游戲內(nèi)字體,無需進(jìn)行二化值處理即可識別,但是需要對要識別的圖片進(jìn)行一下剪裁來提高識別效率
# 圖片灰度處理
picture = Image.open(picturePath).convert('L')
picture.save(picturePath, dpi=(300.0,300.0))
## 二值化,采用閾值分割法,threshold為分割點(diǎn)
if colorValue != None:
winColor().print_green_text("Message: 使用二值化處理, 分割點(diǎn):{}".format(colorValue))
threshold = colorValue
table = []
for j in range(256):
if j < threshold:
table.append(0)
else:
table.append(1)
newPicture = picture.point(table, '1')
## 保存的時(shí)候調(diào)整屏幕分辨率為300,有利于 tesseract 識別
newPicture.save(picturePath, dpi=(300.0,300.0))
# 識別
text=pytesseract.image_to_string(Image.open(picturePath), lang='chi_sim')
return text
# 文字是否在屏幕中 - 檢查5次。
def check_str_exist(self, checkStr, startX = 0, startY = 0, endX = X, endY = Y, times = 5):
flag = 0
while flag < times:
if checkStr in self.get_picture_str(self.screencap(startX, startY, endX, endY), colorValue = None):
return True
flag = flag + 1
time.sleep(1)
return False
# 點(diǎn)擊坐標(biāo), 使用的模擬器屏幕分辨率為 1280x720
def click(self, x, y):
self.check_devices_state()
os.system("adb shell input tap {0} {1}".format(x,y))
time.sleep(0.5)
# 從一個(gè)坐標(biāo)滑動(dòng)到另一個(gè)坐標(biāo),t表示滑動(dòng)耗時(shí)
def swipe(self, oldx, oldy, newx, newy, t):
self.check_devices_state()
cmd = "adb shell input swipe {0} {1} {2} {3} {4}".format(oldx, oldy, newx, newy, t)
os.system(cmd)
time.sleep(1)
# 輸入文本
def set_text(self, s):
self.check_devices_state()
#如果要輸入的文本中包含空格,則必須使用keyevent 62來代替,以下的寫法最后會(huì)多輸入一個(gè)空格;不過對我自己沒什么影響所以就沒處理了
if len(s.split()) == 1:
os.system("adb shell input text '{0}'".format(s) )
else:
for i in s.split():
os.system("adb shell input text '{0}'".format(i))
os.system("adb shell input keyevent 62")
time.sleep(1)
# 輸入含有中文的文本( 需要在模擬器上預(yù)先安裝 ADBKeyBoard.apk)
def set_text_utf8(self, s):
self.check_devices_state()
cmd = "adb shell am broadcast -a ADB_INPUT_TEXT --es msg '%s'" %s
os.system(cmd)
# 圖片識別,根據(jù)傳入的圖片,獲取該圖片在屏幕中的位置, 傳入圖片和相似度(取0-1,最好使用0.99), 還可以傳入需要獲取的point位置,上中下
def get_flagPicture_point(self, flagPicture, precision = 0.99, locationPoint = "center"):
flag1 = 0
while flag1< 5:
screencapPicture = self.screencap()
flag = cv.imread(flagPicture)
screen = cv.imread(screencapPicture)
result = cv.matchTemplate(screen, flag, cv.TM_CCORR_NORMED) #模板匹配,使用cv.TM_SQDIFF_NORMED方法
y, x = flag.shape[:2] #返回圖片的高和寬
min_val, max_val, min_loc, max_loc = cv.minMaxLoc(result)
if max_val >= precision: #這里做一個(gè)判斷,經(jīng)過大量測試,能匹配到的圖片閾值大于0.99的時(shí)候,才是真的匹配到了
tl = max_loc
if locationPoint == "center":
point = (tl[0] + x/2, tl[1] + y/2)
if locationPoint == "bottom": # 1160 439 1160 444
point = (tl[0] + x/2, tl[1] + y)
if locationPoint == "top":
point = (tl[0] + x/2, tl[1])
return point
else:
flag1 = flag1 + 1
time.sleep(2)
return False
"""
# 模板匹配demo
# def find_picture(picture, flag):
# methods = [cv.TM_SQDIFF_NORMED, cv.TM_CCORR_NORMED, cv.TM_CCOEFF_NORMED] #三種比對方式
# x,y = flag.shape[:2] #返回圖片的長和高
# for md in methods:
# result = cv.matchTemplate(picture, flag, md) #模板匹配
# cv.TM_SQDIFF_NORMED: minval越小匹配效果越好
# cv.TM_CCORR_NORMED: max_val越接近1效果越好
# cv.TM_CCOEFF_NORMED: max_val越接近1效果越好
# min_val, max_val, min_loc, max_loc = cv.minMaxLoc(result)
# if md == cv.TM_SQDIFF_NORMED:
# tl = min_loc
# else:
# tl = max_loc
# br = (tl[0]+y, tl[1] + x)
# cv.rectangle(picture, tl, br, [0,0,0])#在picture上畫一個(gè)矩形,參數(shù):原圖,矩陣坐上坐標(biāo),矩陣右下坐標(biāo),劃線的顏色,劃線的寬度
# cv.imshow(np.str(md), picture) #展示圖片(圖片名,原圖)
# picture = cv.imread("C:\\Users\\xuzhonghui\\Desktop\\MyTools\\find\\flag1.png")
# flag = cv.imread("C:\\Users\\xuzhonghui\\Desktop\\MyTools\\find\\picture1.png")
# find_picture(picture, flag)
# cv.waitKey()
# cv.destoryAllWindows()
"""
# 斷言成功則點(diǎn)擊對應(yīng)位置,否則報(bào)錯(cuò)停止腳本運(yùn)行,為了減少代碼量,專門寫的一個(gè)函數(shù)
def click_str(self, checkStr, startX = 0, startY = 0, endX = X, endY = Y, clickX = 0, clickY = 0, ErrorCode = 0):
if self.check_str_exist(checkStr, startX, startY, endX, endY) == True:
self.click(clickX, clickY)
else:
winColor().print_red_text("stepError: errorCode = {}".format(ErrorCode))
exit(0)
總結(jié)
以上是生活随笔為你收集整理的python 安卓库_python 库实战 - 安卓简易自动化框架的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python 数组和列表的区别
- 下一篇: python面试题总结(5)--数据类型