Browse Source

增加python代码。

liuyuqi-dellpc 7 years ago
parent
commit
8ba702f065

+ 7 - 0
.gitignore

@@ -0,0 +1,7 @@
+################################################################################
+# 此 .gitignore 文件已由 Microsoft(R) Visual Studio 自动创建。
+################################################################################
+
+/.vs
+/.pydevproject
+/.project

+ 59 - 0
README.md

@@ -0,0 +1,59 @@
+LiveAnsweringAssistant
+
+百万英雄(西瓜视频)/芝士超人/花椒直播/冲顶大会/一直播/YY 答题赢现金奖励 自动搜索答案
+
+安装环境
+
+安装Java
+安装adb
+
+填写配置文件
+
+target目录里有打包好的money.jar,首次运行需要生成配置文件, 运行以下命令:
+
+java -jar money.jar
+会在同目录生成config.properties,然后填写相应的配置。
+
+配置内容如下所示:
+
+SCREEN_WIDTH = 手机屏幕分辨率宽
+SCREEN_HEIGHT = 手机屏幕分辨率高
+PROBLEM_AREA_X = 答题区域(可自动生成)
+PROBLEM_AREA_Y = 答题区域(可自动生成)
+PROBLEM_AREA_WIDTH = 答题区域(可自动生成)
+PROBLEM_AREA_HEIGHT = 答题区域(可自动生成)
+ADB_PATH = adb完整安装路径(Windows用户注意转义字符)
+IMAGE_TEMP_PATH = 图片缓存路径(Windows用户注意转义字符)
+BD_OCR_APP_ID = 百度OCR AppID
+BD_OCR_API_KEY = 百度OCR API Key
+BD_OCR_API_TOKEN = 百度OCR Secret Key
+百度OCR
+
+识别答题区域
+
+java -jar money.jar -auto-config 图片路径
+图片为答题时的截图,请发送到电脑上进行配置。也可以使用默认配置,提取答题区域是为了让OCR更快的识别出文字。
+
+也可以不指定图片路径,需要手机停留在答题页面,数据线连接着电脑,然后回车。
+
+java -jar money.jar -auto-config
+运行
+
+请打开手机USB调试。
+
+在命令行输入:
+
+java -jar money.jar
+运行后程序会等待用户输入,题目出来的时候输入 p ,敲回车,会展示搜索结果并打开浏览器百度搜索。
+
+根据搜索的 问题+选项 的结果个数进行排序,并输出。这样的方法往往不太准确,后期打算对字符串进行匹配,提高准确率。
+
+输入exit终止程序。
+
+BTW
+
+此程序只是简单的搜索,结果仅做参考。
+
+省去的主要是手动打字进行搜索的时间。
+
+自己测试基本都是五秒内出结果。

+ 70 - 0
src/server/python/engine.py

@@ -0,0 +1,70 @@
+import urllib.request,time,_thread,urllib.parse
+from PIL import Image, ImageFilter
+
+class AnswerQuery:
+
+    def __init__(self,question,answers):
+        self.question=question['query_value']
+        self.coefficent=question['coeff']
+        self.answers=answers
+        self.tread_stamp=[]
+
+    def query_count_thread(self,url):
+        self.get_answer_count(self.get_query_result(url))
+        self.tread_stamp.append(time.time())
+
+    def get_query_result(self,url):
+        opener = urllib.request.build_opener()
+        opener.addheaders = [('User-Agent','Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19')]
+        try:
+            queryResult = opener.open(url).read()
+        except:
+            print ('Unexpected error:', sys.exc_info()[0])
+            continue
+
+        if '=gbk' in url:
+            queryResult=queryResult.decode('gbk').encode('utf-8').decode('utf-8')
+        else:
+            queryResult=str(queryResult,'utf-8')
+        return queryResult
+
+    def get_answer_count(self,result):
+        for answer in self.answers:
+            answer['count']+=result.count(answer['value'])*self.coefficent
+
+    def create_thread(self,url):
+        try:
+            _thread.start_new_thread(self.query_count_thread,(url,))
+        except:
+            print('Error: unable to start thread')
+
+    def search(self):
+        sources={}
+        sources['baidu']='https://zhidao.baidu.com/search?lm=0&rn=10&pn=0&fr=search&ie=gbk&word='+urllib.parse.quote(self.question,encoding='gbk')
+        sources['sogou']='http://wenwen.sogou.com/s/?w='+urllib.parse.quote(self.question)+'&ch=ww.header.ssda'
+        sources['sina']='https://iask.sina.com.cn/search?searchWord='+urllib.parse.quote(self.question)+'&record=1'
+        sources['so']='https://wenda.so.com/search/?q='+urllib.parse.quote(self.question)
+
+        for source in list(sources.values()):
+            self.create_thread(source)
+        while True:
+            if len(self.tread_stamp)==len(list(sources.values())):
+                break
+
+        return self.answers
+
+
+class AreaBlur(ImageFilter.Filter):
+    name = "GaussianBlur"
+
+    def __init__(self, radius=20, bounds=None):
+        self.radius = radius
+        self.bounds = bounds
+
+    def filter(self, image):
+        if self.bounds:
+            clips = image.crop(self.bounds).gaussian_blur(self.radius)
+            image.paste(clips, self.bounds)
+            return image
+        else:
+            return image.gaussian_blur(self.radius)

+ 14 - 0
src/server/python/environment.txt

@@ -0,0 +1,14 @@
+# This file may be used to create an environment using:
+# $ conda create --name <env> --file <this file>
+# platform: osx-64
+certifi=2016.2.28=py36_0
+openssl=1.0.2l=0
+pip=9.0.1=py36_1
+python=3.6.2=0
+readline=6.2=2
+setuptools=36.4.0=py36_1
+sqlite=3.13.0=0
+tk=8.5.18=0
+wheel=0.29.0=py36_0
+xz=5.2.3=0
+zlib=1.2.11=0

+ 111 - 0
src/server/python/main.py

@@ -0,0 +1,111 @@
+import urllib.request,sys,base64,json,os,time,string,re,os,string
+from configparser import ConfigParser
+from PIL import Image
+from aip import AipOcr
+from zhon import hanzi
+from engine import AnswerQuery,AreaBlur
+
+# Parameter
+QUIZ_APPS=[
+{'app_name':'冲顶大会',
+ 'answer_count':3,
+ 'crop_area':(45,190,450,580), #iPhone 6,6s,7 on 1440*900 display resolution Mac
+ 'mask_area':[]},
+
+{'app_name':'芝士超人',
+ 'answer_count':3,
+ 'crop_area':(24,120,470,500), #iPhone 6,6s,7 on 1440*900 display resolution Mac
+ 'mask_area':[]},
+
+{'app_name':'头脑王者',
+ 'answer_count':4,
+ 'crop_area':(65,250,430,810), #iPhone 6,6s,7 on 1440*900 display resolution Mac
+ 'mask_area':[(25,435,85,465),(410,435,470,465)]}, #iPhone 6,6s,7 on 1440*900 display resolution Mac
+
+ {'app_name':'头脑王者(iPhone X)',
+  'answer_count':4,
+  'crop_area':(50,250,350,825), #iPhone X on 1440*900 display resolution Mac
+  'mask_area':[(20,520,70,540),(340,520,390,540)]} #iPhone X on 1440*900 display resolution Mac
+]
+
+NEG_KEYWORDS=['不','没']
+
+# Configuration
+cfg = ConfigParser()
+cfg.read('secret.ini')
+client = AipOcr(cfg.get('BAIDU_OCR','APP_ID'), cfg.get('BAIDU_OCR','API_KEY'), cfg.get('BAIDU_OCR','SECRET_KEY'))
+
+def get_file_content(filePath):
+    with open(filePath, 'rb') as fp:
+        return fp.read()
+
+def is_contain_keywords(text,keywords):
+    for word in keywords:
+        if text.count(word)>0:
+            return True
+    return False
+
+def clear_keywords(text,keywords):
+    for word in keywords:
+        text=text.replace(word,'')
+    return text
+
+# Select quiz app
+print('---------------------------------')
+print('The supported quiz app are as below:')
+for appSeq in range(len(QUIZ_APPS)):
+    print(appSeq+1, QUIZ_APPS[appSeq]['app_name'])
+selectedSeq=input(r'Press No. to select your app. Press other key to exit: ')
+try:
+    selectedSeq=int(selectedSeq)-1
+    if not selectedSeq in range(len(QUIZ_APPS)):
+        raise ValueError()
+except:
+    exit()
+print('[',QUIZ_APPS[selectedSeq]['app_name'],']','has been selected')
+
+while True:
+    nextStep=input('Press [Enter] to pick answer. Press other key to exit: ')
+    if nextStep=='':
+        startTime = time.time()
+
+        # Capture, crop image, and mask noise
+        fullCapFileName=r'./sreenshot/full_'+str(int(startTime))+'.png'
+        subjectCapFileName=r'./sreenshot/subject_'+str(int(startTime))+'.png'
+        os.system('screencapture '+fullCapFileName)
+        fullCap=Image.open(fullCapFileName)
+        if len(QUIZ_APPS[selectedSeq]['mask_area'])>0:
+            for area in QUIZ_APPS[selectedSeq]['mask_area']:
+                fullCap=fullCap.filter(AreaBlur(bounds=area))
+        fullCap.crop(QUIZ_APPS[selectedSeq]['crop_area']).save(subjectCapFileName)
+
+        # Read cropped image
+        image = get_file_content(subjectCapFileName)
+        response = client.basicGeneral(image)
+        wordsResult=response['words_result']
+
+        # Store recognized text in dict
+        answerCount=QUIZ_APPS[selectedSeq]['answer_count']
+        subject={}
+        subject['question']={'value':''.join([seg['words'] for seg in wordsResult[0:len(wordsResult)-answerCount]])}
+        if is_contain_keywords(subject['question']['value'],NEG_KEYWORDS):
+            subject['question']['coeff']=-1
+            subject['question']['query_value']=clear_keywords(subject['question']['value'],NEG_KEYWORDS)
+        else:
+            subject['question']['coeff']=1
+            subject['question']['query_value']=subject['question']['value']
+        subject['answers']=[{'value':seg['words'].strip(string.punctuation).strip(hanzi.punctuation),'count':0} for seg in wordsResult[len(wordsResult)-answerCount:]]
+
+        # Query question and obtain each of answer frequency
+        query=AnswerQuery(subject['question'],subject['answers'])
+        subject['answers']=query.search()
+
+        # Print the result
+        print('---------------------------------')
+        print(subject['question']['value'])
+        for answer in subject['answers']:
+            print (('>>' if answer['count']== max([answer['count'] for answer in subject['answers']]) else '  '),answer['value'],'[',answer['count'],']')
+        print('---------------------------------')
+        print('time cost: '+str(time.time()-startTime)+'s')
+    else:
+        exit()

+ 14 - 0
src/server/python/requirement.txt

@@ -0,0 +1,14 @@
+# This file may be used to install all required package using:
+# $ pip install --requirement <this file> -yes
+# platform: osx-64
+baidu-aip==2.1.0.0
+certifi==2017.11.5
+chardet==3.0.4
+idna==2.6
+Pillow==5.0.0
+pip==9.0.1
+requests==2.18.4
+setuptools==36.4.0
+urllib3==1.22
+wheel==0.29.0
+zhon==1.1.5

+ 6 - 0
src/server/python/secret.ini.template

@@ -0,0 +1,6 @@
+[BAIDU_OCR]
+# BAIDU_OCR OCR Configuration
+# NO quote needed
+APP_ID = #REPLACE_THIS_WITH_YOUR_APP_ID
+API_KEY = #REPLACE_THIS_WITH_YOUR_API_KEY
+SECRET_KEY = #REPLACE_THIS_WITH_YOUR_SECRET_KEY