冲顶,百万答题助手改进(python)

答题游戏现在很火,但是,价值却不如以前了。为什么这么晚才想着去写这种助手呢!烦躁

这次改进主要是让效果更好,操作更为简单(这是最大的改进),现在只需要运行,按回车,就可以了,不再需要外部软件辅助。不过,这里却损失了一点效率,毕竟答题时间就10秒,效率也是很重要的。所以呀,实际上效果不是很好,现在多数娱乐效果吧,有兴趣的小伙伴可以拿去玩玩。

本次程序用到的工具:python3.6,adb驱动,我已经打包成exe了,所以,只是想玩玩的就不必在意这些了,下载链接:链接:https://pan.baidu.com/s/1ggMaOqn 密码:f8eo(csdn上传不了zip文件,莫名其妙)
本次代码相比上次主体部分改动不大,注释我也没做更新,但应该也看得懂的,直接上代码了:

 # _*_ coding:UTF-8 _*_
import numpy as np
import win32con
import ctypes
import ctypes.wintypes
import threading
import time
import os
import subprocess
from PIL import Image
from aip import AipOcr#百度的api,百度官网有教程
import shutil
import string
import urllib


#热键功能,独立的一个线程
class Hotkey(threading.Thread):  #创建一个Thread.threading的扩展类  

    def run(self):  
        global EXIT #定义全局变量,这个可以在不同线程间共用
        global RUN #定义全局变量,这个可以在不同线程间共用
        user32 = ctypes.windll.user32  #加载user32.dll

        try:
            if not user32.RegisterHotKey(None, ID1, 0, HOTKEY_RUN):   # 注册快捷键F10并判断是否成功,该热键用于结束程序,且最好这么结束,否则影响下一次注册热键。  
                print ("Unable to register id"), ID1 # 返回一个错误信息

            if not user32.RegisterHotKey(None, ID2, 0, HOTKEY_EXIT):   # 注册快捷键F10并判断是否成功,该热键用于结束程序,且最好这么结束,否则影响下一次注册热键。  
                print ("Unable to register id"), ID2 # 返回一个错误信息

            #以下为检测热键是否被按下,并在最后释放快捷键  
            msg = ctypes.wintypes.MSG()  

            while True:
                if user32.GetMessageA(ctypes.byref(msg), None, 0, 0) != 0:
                    if msg.message == win32con.WM_HOTKEY:
                        if msg.wParam == ID2:
                            EXIT=True
                            return
                        elif msg.wParam == ID1:
                            RUN=True

                    user32.TranslateMessage(ctypes.byref(msg))  
                    user32.DispatchMessageA(ctypes.byref(msg))   

        finally:
            user32.UnregisterHotKey(None, ID1)#必须得释放热键,否则下次就会注册失败,所以当程序异常退出,没有释放热键,
                                              #那么下次很可能就没办法注册成功了,这时可以换一个热键测试
            user32.UnregisterHotKey(None, ID2)


class Ans():

    def main(self):
        #im_name=os.listdir(filePath)#获取图片名
        self.cut()#对图片进行裁剪

        f=open('im.jpg','rb')#二进制方式打开图文件
        image=f.read()#这里好像必须命名为image,百度的api限定,有点不能理解,有待考察
        #im=base64.b64encode(f.read()) #读取文件内容,转换为base64编码

        #这里是每个百度云账号独立的一些ID
        APP_ID='10687373'
        API_KEY='BIziiO4FQbN7n7iu5kPCuEMF'
        SECRET_KEY='yOxbhG3qZp0KvNkB42hstT4aNWXHOitZ'


        client = AipOcr(APP_ID, API_KEY, SECRET_KEY)#这个就是百度的api,可以获取一个相当于实例对象的东西,可以调用函数
        information=client.basicGeneral(image)#ocr函数,打印出来是json格式的

        #这里是普通版的
        STR=''#存储识别出来的文字
        num=information['words_result_num']
        for i in range(0,num):#根据格式得出来的循环,答案放在前面,题目放在后面,保证题目能完成搜索到
            if i>=0 and i<3:
                STR+=information['words_result'][num-i-1]['words']
                STR+=' '
            else:
                STR+=information['words_result'][i-3]['words']

        #下面几行是对得到的字符串做一些处理,去掉一些符号,因为百度搜索限制38个字以内,个人觉得这里写的很丑,无奈没找到好的方法
        #STR=STR[1:len(STR)]
        STR=STR.translate(string.punctuation)

        DEL=['以下','哪个','是','的','什么','下列','哪种']#这鞋子替换成空格,好处在于百度效果很好吧,亲测结果
        for x in DEL:
            STR = STR.replace(x,' ')

        self.find(STR)#调用百度搜索,并保存到本地,再用默认浏览器打开
        print (STR)
        f.close()#关闭文件,不然后面删除不掉
        #shutil.rmtree(path)#删除之前获得的图片文件以及这个文件夹,以便下次判断是否已经截屏

    #打开图片并裁剪
    def cut(self):
        #im_name=os.listdir(filePath)#获取图片名,因为截屏靠的外部软件,没办法修改截屏图片的名字
        im=Image.open(filePath+'\\'+"screenshot.jpg")
        if len(im.split()) == 4:
            r, g, b, a = im.split()#图片有四通道
            im=Image.merge("RGB",(r,g,b))

        #下面这篇代码也写的不够优雅,可是没找到好的办法
        box=(80,330,1000,1300)
        crop_im=im.crop(box)#裁剪函数
        array_im=np.array(crop_im.convert('L'))
        im.close()
        x=970#记录最下边界
        for i in range(300):
            if array_im[969-i][0]==255:
                x=969-i-50
                break
        crop_im2=crop_im.crop((0,0,919,x))
        crop_im2.save('im.jpg')#保存本地,有不保存就直接用二进制打开的方式吗??求教


    #调用百度搜索,并保存到本地,再用默认浏览器打开,参考百度的资料,具体哪篇忘记了,,如有问题请联系我。。
    def find(self,STR):
        url = "http://www.baidu.com/s"
        search = [('w',STR)]
        getString = url + "?" + urllib.parse.urlencode(search)

        req = urllib.request.Request(getString)
        fd = urllib.request.urlopen(req)
        baiduResponse=fd.read()

        fobj=open("baidu.html",'wb+')
        fobj.write(baiduResponse)
        os.startfile('baidu.html')#这个函数就很刚好的解决了大问题,可以用浏览器打开网页,不然就得手点了
        fobj.close()

    def getPicture(self,filePath,ADBpath):
        #ADBpath=filePath+'\\adb\\adb '
        subprocess.call(ADBpath+"shell /system/bin/screencap -p /sdcard/screenshot.jpg",stdout=subprocess.PIPE, shell=subprocess.PIPE)
        subprocess.call(ADBpath+"pull /sdcard/screenshot.jpg "+filePath+"/screenshot.jpg",stdout=subprocess.PIPE, shell=subprocess.PIPE)

if __name__ == '__main__':
        HOTKEY_RUN=0x0D
        HOTKEY_EXIT=win32con.VK_F8#结束程序的快捷键F6,自行根据需要修改,一定要手动关闭程序,否则下次这个快捷键就用不了了(python3.6没这个问题?)

        EXIT = False #用来传递退出的参数
        RUN = False
        ID1=106 #注册热键的唯一id,用来区分热键
        ID2=105

        filePath=os.path.split(os.path.realpath(__file__))[0]
        ADBpath=filePath+'\\adb\\adb '

        ans=Ans()#创建实例

        hotkey = Hotkey()  
        hotkey.start()#启动线程
        print ("等待手机设备连接USB...如无设备需要连接请按F8结束程序")

        subprocess.call(ADBpath+" wait-for-device",stdout=subprocess.PIPE, shell=subprocess.PIPE)
        print ("截屏快捷键:回车,关闭程序快捷键:F8")
        while(True):
            if RUN==True:
                print ("开始识别")
                start=time.time()
                ans.getPicture(filePath,ADBpath)
                ans.main()
                subprocess.call(ADBpath+' shell rm /sdcard/screenshot.jpg',stdout=subprocess.PIPE, shell=subprocess.PIPE)
                end=time.time()
                print ("一次识别结束,用时:",end-start)
                print ()
                RUN=False

            elif EXIT==True: #退出程序
                break

效率还是这个程序最大的问题,但是,目前没想到解决办法,就先这样吧,不过,还是有那么一点帮助的。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lsjweiyi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值