如何在百万英雄直播答题中使用Python辅助?

首先写这个辅助的想法来源于之前微信小游戏“跳一跳”的辅助,使用到了adb来获得手机的截图等,而直播答题碰到不会的题遇到的困难主要就是没时间去打字搜索,如果用同样的方法得到了题目相关的文字信息自动去搜索,成功率不就大大提高了嘛!再有很自然想到的一点就是一道题就3个选项,3台手机不就肯定能保证对一道吗?因此如何快速操作多个手机模拟器也需要考虑。

效果图

Ref

人人都能看懂的“跳一跳”平民算法
冲顶大会也可以这样玩

思路

开启多个手机模拟器,题目出现时启动Python程序,截图并进行OCR识别出文字,获得各个选项,接着对问题以及各个选项分别进行搜索,获得前几条搜索结果或者页面数量等进行判断。

手机模拟器

在这里我用的是夜神手机模拟器,需要用到一个分辨率、DPI较高的模拟器用于OCR识别,剩下的配置尽量调低降低硬件开销。


手机模拟器多开

adb

由于需要操作多个模拟器,我们首先需要知道如何连接各个模拟器。下载好adb包之后将其配置到环境变量中,然后adb devices查询在线的模拟器即可。然而有时候模拟器抽风,这个命令不起作用,这个时候需要先adb connect之后adb devices才有用(神设定),查看对应安装目录,Nox\bin\debug.bat发现查找对应模拟器的端口的方法是通过查找配置文件的5555端口实现的,依葫芦画瓢,来到Nox\bin\BignoxVMS查看各个副本的配置文件即可得到端口。这里总结一下用到的adb命令

//输入adb可查看相关命令用法
 //存在多个模拟器时需要用-s 指定操作的目标
adb -s 127.0.0.1:62001  shell screencap -p /sdcard/n.png //截屏
adb -s 127.0.0.1:62001 pull /sdcard/n.png ./n.png //传到电脑

//输入adb shell input可查看相关命令用法
adb -s 127.0.0.1:62001 shell input tap x y //点击(x,y)位置 用以点击问题的选项

确定题目与选项位置

经过测试题目选项出现的位置是固定的,所以这里的问题主要是将分辨率较高的模拟器上选项的位置对应到低分辨率模拟器上。

分辨率480X800 DPI 160

分辨率480X800 DPI 60

分辨率240X400 DPI 60

从以上3张图可以得到,分辨率相同的话,题目区域大小与DPI成正比;DPI相同的话,整个题目占用的像素点是相同的,题目区域大小与分辨率成反比。所以假如在480X800 DPI 160的模拟器上位置为(x,y),在240X400 DPI 60的模拟器上位置为(x,y*2*60/160)=(x,0.75y)

相对关系

OCR

从固定位置中裁剪出问题的图像,再OCR识别为文字。这里用到的是tesseract-ocr,同样需要配置环境变量。
系统变量下添加变量TESSDATA_PREFIX值为E:\Tesseract-OCR\tessdata
PATH下添加E:\Tesseract-OCR
还需要下载一个中文的数据包chi_sim.traineddata放到E:\Tesseract-OCR\tessdata
cmd下输入tesseract test.png out.txt -l chi_sim生成的out.txt即为test.png的识别结果。需要注意这个test.png需要裁剪出待识别的区域,否则效果很差。
以上步骤成功后就可以用Python的pytesseract库来返回结果了。

    # 保存问题
    cropped_img = im[y_start:y_end, x_start:x_end]
    cv2.imwrite("total.bmp" , cropped_img)
    # 这里直接使用cropped_img不行,需要保存后再用PIL.Image打开
    text_result=pytesseract.image_to_string(Image.open("total.bmp"), lang="chi_sim"a

搜索策略

文本拿到就很好做了。预处理一下,然后用jieba获取问题的关键词,再进行搜索就行啦。这里我用的是根据搜索结果的数目来判断的。这里请参考Wikipedia ——Pointwise mutual information

           divided=text.replace(" ","").split("\n")
            for i in divided:
                if (i=="" or i=="\n"):
                    divided.remove(i)
            question=divided[0]
            del divided[0]
            print("Question: %s"%question)
            keywords=jieba.analyse.extract_tags(question,topK=2,withWeight=True)
            print("Keywords:")
            for i in keywords:
                print i
            totalweight=0
            print ("Options: ")
            print("\n".join(divided))

至于说获得搜索结果的数量,用一个Xpath来提取就好啦,相信大家写过爬虫之后很容易搞定的。

def get_search_nums(word):
    # url="https://www.baidu.com/s?wd="+unicode(word,"utf-8")
    #需要先转为utf8才能进行quote
    url="https://www.baidu.com/s?wd="+urllib2.quote(word.encode("utf8"))
    myheaders = {
        'User-Agent': "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1"}  # 浏览器请求头
    request=urllib2.Request(url,headers=myheaders)
    response=urllib2.urlopen(request)
    source=response.read()
    html=etree.HTML(source)
    result=html.xpath('''//*[@id="container"]/div[2]/div/div[2]/text()''')
    result=result[0]
    pattern=re.compile(u".*约([\d,]+)个")
    #!!!注意这里编码和网页返回的编码要对应才可以进行查找!!大坑!
    num=re.findall(pattern,result)
    num=int(num[0].replace(",",""))
    return num

结果

嗯…用这种PMI算法得到的结果还是不太靠谱,按照整个问题来搜索AC选项差异不大,按照“电影”这个关键词应该选B……(正确答案是C)所以还是需要把搜索结果的前几条给展示出来的。获得正确答案之后朝着各个模拟器发送一个对应位置的adb shell input去点击选项即可。

答案应该为第七艺术

改进

  • OCR效果太差导致搜索出错。如上图的“第六艺术”识别为“第大艺术”(啥玩意儿啊)在Ref中的第二篇文章中用到了百度的OCR,不知道效果如何。
  • 搜索多个页面由于网络速度的限制还是比较费时间的。
  • “跳一跳”中曾出现直接抓包分析并提交结果的方法,不知道在西瓜视频里面能否用上。
  • 使用多个模拟器测试的过程中发现各个问题在模拟器上的出现是有时差的,延后出现对作答是有利的,能否在可接受的范围内加大这个时差?
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容