Python3.5结合Tesseract与ADB实现视频答题辅助自动化
本文介绍基于Python3.5、Tesseract OCR及ADB技术,实现西瓜视频或头脑王者等答题类应用的辅助脚本。通过ADB抓取屏幕图像,利用OCR识别题目与选项,并自动调用浏览器搜索答案,将识别耗时压缩至0.5-0.6秒,显著提升答题效率与胜率。
近期答题赢钱类应用热度极高,笔者也参与了多次。部分题目难度较大,在10秒限时内难以通过百度搜索获取答案。为此,开发了一套辅助脚本,可在题目出现时自动执行百度检索,该过程仅需约2秒,剩余7至8秒可用于分析并作答,从而有效提高获胜概率。
完整源码已托管至GitHub,具体链接见原文。
核心原理如下:利用ADB命令截取手机视频播放界面图像,随后通过Python进行图像截取与OCR文字识别,提取题目及选项内容,最后调用百度搜索获取结果。关于环境搭建,如需协助可联系笔者。由于采用本地OCR解析,无需支付额外费用,且无使用次数限制。
在GitHub提供的代码库中,
ocr_bw.py文件负责根据识别出的题目自动执行百度搜索,并打开浏览器展示检索结果。
# -*- coding: utf-8 -*-
import pytesseract
import time
import webbrowser
import subprocess
from PIL import Image
def main():
"""
主函数
"""
op = yes_or_no('请确保手机打开了 ADB 并连接了电脑,'
'然后打开西瓜视频后再用本程序,确定开始?')
if not op:
print('bye')
return
#核心递归
ocr_subject_parent()
# for root, sub_dirs, files in os.walk('E:/临时接收的文件/知乎答题/百万/'):
# for file in files:
# print('发现图片:' + file)
# img = Image.open('E:/临时接收的文件/知乎答题/百万/'+file)
# ocr_subject(img)
def yes_or_no(prompt, true_value='y', false_value='n', default=True):
"""
检查是否已经为启动程序做好了准备
"""
default_value = true_value if default else false_value
prompt = '{} {}/{} [{}]: '.format(prompt, true_value,
false_value, default_value)
i = input(prompt)
if not i:
return default
while True:
if i == true_value:
return True
elif i == false_value:
return False
prompt = 'Please input {} or {}: '.format(true_value, false_value)
i = input(prompt)
def screenImg(true_value='', default=True):
prompt = '当出现题目时,请按下回车进行识别 '
i = input(prompt)
if not i:
return default
while True:
if i == true_value:
return True
else:
return False
i = input(prompt)
def ocr_subject(p):
# 截取 距离上530开始 940结束
# 截取 距离上260 570结束
p = cut_img(p)
pytesseract.pytesseract.tesseract_cmd = 'E:/Program Files (x86)/Tesseract-OCR/tesseract'
subject = pytesseract.image_to_string(p, lang='chi_sim')
subject = "".join(subject.split())
subject = subject.split('.')[1]
print(subject)
openPage(subject)
ocr_subject_parent()
def ocr_subject_parent():
result = screenImg()
if result:
start = time.time()
# screenshot.check_screenshot()
process = subprocess.Popen(
'adb shell screencap -p',
shell=True, stdout=subprocess.PIPE)
binary_screenshot = process.stdout.read()
binary_screenshot = binary_screenshot.replace(b'\r\n', b'\n')
f = open('autojump.png', 'wb')
f.write(binary_screenshot)
f.close()
# screenshot.pull_screenshot()
img = Image.open('autojump.png')
print("耗时:" + str(time.time() - start))
ocr_subject(img)
def openPage(subject):
url = 'https://www.baidu.com/s?wd={}'.format(
subject)
webbrowser.open(url)
webbrowser.get()
def cut_img(img):
region = img.crop((70, 260, 1025, 570))
#region.save("temp/cut_first.png")
return region
if __name__ == '__main__':
main()
ocr_bw2.py文件则根据题目及选项组合进行百度搜索,通过爬虫抓取百度的收录数量,并在控制台打印相关结果。
__author__ = 'zjy'
# -*- coding:utf-8 -*-
import pytesseract
import time
import webbrowser
import subprocess
from PIL import Image
import urllib
import urllib.request
import threading
from urllib.parse import quote
def main():
"""
主函数
"""
op = yes_or_no('请确保手机打开了 ADB 并连接了电脑,'
'然后打开西瓜视频后再用本程序,确定开始?')
if not op:
print('bye')
return
# 核心递归
ocr_subject_parent()
# for root, sub_dirs, files in os.walk('E:/临时接收的文件/知乎答题/百万/'):
# for file in files:
# print('发现图片:' + file)
# img = Image.open('E:/临时接收的文件/知乎答题/百万/'+file)
# ocr_subject(img)
def yes_or_no(prompt, true_value='y', false_value='n', default=True):
"""
检查是否已经为启动程序做好了准备
"""
default_value = true_value if default else false_value
prompt = '{} {}/{} [{}]: '.format(prompt, true_value,
false_value, default_value)
i = input(prompt)
if not i:
return default
while True:
if i == true_value:
return True
elif i == false_value:
return False
prompt = 'Please input {} or {}: '.format(true_value, false_value)
i = input(prompt)
def screenImg(true_value='', default=True):
prompt = '当出现题目时,请按下回车进行识别 \n'
i = input(prompt)
if not i:
return default
while True:
if i == true_value:
return True
else:
return False
i = input(prompt)
def ocr_subject(p):
# 截取 距离上530开始 940结束
# 截取 距离上260 570结束
subImg = cut_img(p)
pytesseract.pytesseract.tesseract_cmd = 'E:/Program Files (x86)/Tesseract-OCR/tesseract'
subject = pytesseract.image_to_string(subImg, lang='chi_sim')
subject = "".join(subject.split())
subject = subject.split('.')[1].replace("\"", "")
print(subject)
ocr_answer(p, subject)
# openPage(subject)
# print("结束:" + str(time.time()))
ocr_subject_parent()
def getSearchNum(key):
key = quote(key)
# print(key)
url = 'http://www.baidu.com/s?wd={}'.format(key)
# print(url)
response = urllib.request.urlopen(url)
page = response.read().decode("utf-8")
i = int(page.index('百度为您找到相关结果约'))
start = i + 10
end = i + 25
page = page[start: end]
return page
def ocr_answer(p, subject):
list = cut_question(p)
pytesseract.pytesseract.tesseract_cmd = 'E:/Program Files (x86)/Tesseract-OCR/tesseract'
for p in list:
t = threading.Thread(target=ocr_answer_thread, args=(p, subject))
t.start()
def ocr_answer_thread(p, subject):
answer = pytesseract.image_to_string(p, lang='chi_sim')
answer = "".join(answer.split())
v = getSearchNum(subject + ' ' + answer)
print(answer + ' ' + v)
# print(time.time())
def ocr_subject_parent():
result = screenImg()
if result:
start = time.time()
# print("开始:" + str(start))
# screenshot.check_screenshot()
process = subprocess.Popen(
'adb shell screencap -p',
shell=True, stdout=subprocess.PIPE)
binary_screenshot = process.stdout.read()
binary_screenshot = binary_screenshot.replace(b'\r\n', b'\n')
f = open('autojump.png', 'wb')
f.write(binary_screenshot)
f.close()
# screenshot.pull_screenshot()
img = Image.open('autojump.png')
ocr_subject(img)
def openPage(subject):
url = 'https://www.baidu.com/s?wd={}'.format(
subject)
webbrowser.open(url)
webbrowser.get()
def cut_img(img):
region = img.crop((70, 260, 1025, 570))
# region.save("temp/cut_first.png")
return region
def cut_question(img):
list = []
question1 = img.crop((70, 590, 1025, 768))
question2 = img.crop((70, 769, 1025, 947))
question3 = img.crop((70, 948, 1025, 1130))
list.append(question1)
list.append(question2)
list.append(question3)
# question1.save("temp/cut_1.png")
# question2.save("temp/cut_2.png")
# question3.save("temp/cut_3.png")
return list
if __name__ == '__main__':
main()
鉴于大量题目为“下列哪个不是”类型的否定式提问,笔者更倾向于使用第一种方式,其基本识别时间控制在0.5至0.6秒之间。

此外,代码中的ocr_zh.py模块专门用于抓取头脑王者游戏的辅助信息。
以上为本文全部内容,希望对读者的学习有所帮助,也欢迎大家继续支持本站。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









