python写刷课脚本_python opencv 知到 刷课 脚本

本文介绍了如何利用Python的ADB工具和OpenCV库,实现从手机屏幕截图并进行模板匹配,以自动刷在线课程。通过模板匹配方法找到关闭按钮,并在检测到时模拟点击,实现自动关闭对话框的功能。脚本中还包含了一个阈值避免误判。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

下载adb工具

链接:https://pan.baidu.com/s/1fuobUremdbrs2uQ2Yvo5NQ

提取码:or7m

查看设备

adb devices

a42befe7fe19feb75b8690a7a3846a19.png

测试截图

将截屏文件保存到电脑上

import subprocess

class Screenshot(): # 截取手机屏幕并保存到电脑

def __init__(self):

# 查看连接的手机

connect = subprocess.Popen("adb devices", stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=True)

stdout, stderr = connect.communicate() # 获取返回命令

# 输出执行命令结果结果

stdout = stdout.decode("utf-8")

stderr = stderr.decode("utf-8")

print(stdout)

print(stderr)

def screen(self, cmd): # 在手机上截图

screenExecute = subprocess.Popen(str(cmd), stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=True)

stdout, stderr = screenExecute.communicate()

# 输出执行命令结果结果

stdout = stdout.decode("utf-8")

stderr = stderr.decode("utf-8")

print(stdout)

print(stderr)

def saveComputer(self, cmd): # 将截图保存到电脑

screenExecute = subprocess.Popen(str(cmd), stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=True)

stdout, stderr = screenExecute.communicate()

# 输出调试信息

print(stdout, stderr)

# 先截图保存到手机中保存

cmd1 = r"adb shell /system/bin/screencap -p /sdcard/tmp.png"

# 然后将手机中的图片保存到电脑上

cmd2 = r"adb pull /sdcard/tmp.png tmp.png"

screen = Screenshot()

screen.screen(cmd1)

screen.saveComputer(cmd2)

简化

import subprocess

def get_screen():

# 先截图保存到手机中保存

cmd_screen_cap = "adb shell /system/bin/screencap -p /sdcard/tmp.png"

# 然后将手机中的图片保存到电脑上

cmd_save_computer = "adb pull /sdcard/tmp.png tmp.png"

subprocess.Popen(

cmd_screen_cap,

stderr=subprocess.PIPE,

stdout=subprocess.PIPE,

shell=True

).communicate()

subprocess.Popen(

cmd_save_computer,

stderr=subprocess.PIPE,

stdout=subprocess.PIPE,

shell=True

).communicate()

get_screen()

opencv的模板匹配

import cv2

img = cv2.imread('img.png')

part = cv2.imread('close.png')

cv2.imshow('img', img)

cv2.imshow('close', part)

methods = [cv2.TM_SQDIFF_NORMED, cv2.TM_CCORR_NORMED, cv2.TM_CCOEFF_NORMED]

part_height, part_weight = part.shape[:2]

print(part_height, part_weight)

for method in methods:

# print(method)

result = cv2.matchTemplate(img, part, method)

# print(result)

# 根据不同的公式计算不同的值

min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)

print(min_val, max_val, min_loc, max_loc)

# 根据不同的算法,选择匹配程度最大的区域

if method == cv2.TM_SQDIFF_NORMED:

# 该算法值越小,匹配程度越高

img_loc = min_loc

else:

img_loc = max_loc

br = (img_loc[0] + part_weight, img_loc[1] + part_height)

cv2.rectangle(img, img_loc, br, (0, 0, 255), 2)

cv2.circle(img, (img_loc[0] + part_weight // 2, img_loc[1] + part_height//2), 2, (255, 0, 0))

cv2.imshow("match" + str(method), img)

cv2.imshow("res" + str(method), result)

cv2.waitKey(1000)

cv2.waitKey(0)

可以看到已经能够找到关闭的中心坐标

48b9ee42cfee49f718a9d37d8e8e0307.png

配合到一起

使用第一种匹配方法,值越小匹配程度越高,在实际测试中发现,第二和第三种方法,会对一些符号误判,对展开列表的箭头和类似形状的文字无法分别

e8d84f6ea8b36866fbb1571450458a20.png

import subprocess

import cv2 as cv

import time

import numpy as np

def get_screen():

# 先截图保存到手机中保存

cmd_screen_cap = "adb shell /system/bin/screencap -p /sdcard/tmp.png"

# 然后将手机中的图片保存到电脑上

cmd_save_computer = "adb pull /sdcard/tmp.png tmp.png"

subprocess.Popen(

cmd_screen_cap,

stderr=subprocess.PIPE,

stdout=subprocess.PIPE,

shell=True

).communicate()

subprocess.Popen(

cmd_save_computer,

stderr=subprocess.PIPE,

stdout=subprocess.PIPE,

shell=True

).communicate()

return cv.imread('tmp.png')

# 返回最优匹配图的中心点

def get_center(img, part):

part_height, part_weight = part.shape[:2]

methods = [cv.TM_SQDIFF_NORMED, cv.TM_CCORR_NORMED, cv.TM_CCOEFF_NORMED]

method = methods[0]

result = cv.matchTemplate(img, part, method)

# 根据不同的公式计算不同的值

min_val, max_val, min_loc, max_loc = cv.minMaxLoc(result)

# 根据不同的算法,选择匹配程度最大的区域

if method == cv.TM_SQDIFF_NORMED:

# 该算法值越小,匹配程度越高

img_loc = min_loc

else:

img_loc = max_loc

point = (img_loc[0] + part_weight // 2, img_loc[1] + part_height // 2)

print(np.min(result))

return point if np.min(result) <= .0006 else None

# 点击一个位置

def touch(point):

cmd = f"adb shell input tap {point[0]} {point[1]}"

subprocess.Popen(

cmd,

stderr=subprocess.PIPE,

stdout=subprocess.PIPE,

shell=True

).communicate()

# 关闭按钮

close = cv.imread('close.png')

# 自动关闭对话框

def auto_close():

img = get_screen()

# 关闭按钮所在中心

point = get_center(img, close)

print(point)

if point:

touch(point)

# 每隔五秒点击一次

duration = 5

while True:

auto_close()

time.sleep(duration)

在实际中通过设置一个很小的阈值来避免出现误判,可以看到大多时候都是没有返回值的,只有出现选项时,才会返回关闭按钮所在的位置坐标,然后自动关闭~

703d6d8d788b456166fcde078ac0f887.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值