20192213 《Python程序设计》实验四报告
课程:《Python程序设计》
班级: 1922
姓名: 刘子谦
学号:20192213
实验教师:王志强
实验日期:2020年6月10日
必修/选修: 公选课
1.实验内容
1.程序功能说明
定位:搜索小工具
目标:实现高效搜索,帮助网课学生快速找到答案,实现搜索自动化。
具体功能:有以下四个:
多引擎搜索
上学吧搜索
多引擎翻译
截图文字识别
接口说明:
百度开放平台API提供OCR识别
有道翻译提供翻译
金山翻译提供翻译
腾讯翻译君翻译提供翻译
百度单词提供单词查询
截图功能调用微信截图
上学吧提供部分题目答案
2.程序实现思路
爬取文本 + 接口爬虫 + GUI界面
3.程序效果展示
首页(有我的logo,有使用说明)
多引擎搜索
上学吧搜索
多引擎翻译
截图文字识别
二、实验过程及结果
1.多引擎搜索实现方法
核心使用webbrowser库,打开网页,本功能实现相对容易,不做过多解释,直接上代码
#下面以百度搜索为例
#一个打开百度搜索的函数,传入搜索关键词,打开对应网页
from webbrowser import open as op
def baidu(words):
urlBD = 'https://www.baidu.com/s?isource=infinity&iname=baidu&itype=web&ie=utf-8&wd=' + words
op(urlBD)
2.上学吧搜索
本功能分两步:
先搜索题目,获取id列表
再根据id,遍历所有题目,抓取答案
第一步核心代码如下:
传入关键词,自动搜索,返回题目id列表和题目详情列表
#上学吧的搜索程序
def getIdAndTitel(words,cookie=''):
url = 'https://www.shangxueba.com/ask/search.aspx?key=' + words
if cookie=='':
tk.messagebox.showerror('用户设置错误','请输入cookie\n否则无法爬取信息\nCookie可询问程序开发者')
return False,False
else:
cookie1 = cookie
headers = {
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'zh-CN,zh;q=0.9',
'cookie': cookie1,
'referer': 'https://www.shangxueba.com/',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
}
html = requests.get(url,headers=headers).text
# 通过切片获取列表
try:
detail = html.split('
- ')[1]
detail = detail.split('
')[0:-1]except:
return False,False
idList = []
detailList = []
for n,i in enumerate(detail):
try:
#获取ID:
detail[n] = i.split('.')[0]
idRule = re.compile('
id = idRule.findall(detail[n])[0]
title = i.split('target="_blank">',2)[2]
')[0]title = title.replace('','').replace('','')
idList.append(id)
detailList.append(title)
except:
idList.append('')
detailList.append('')
return idList,detailList
第二步核心代码如下:
传入题目id和cookie,返回答案列表
#上学吧的搜索程序
#下面根据urlList,遍历列表中的题目信息
def getInfoSXB(idList,cookie=''):
if cookie == '':
tk.messagebox.showerror('用户设置错误', '请输入cookie\n否则无法爬取信息\nCookie可询问程序开发者')
return
else:
cookie1 = cookie
headers = {
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'zh-CN,zh;q=0.9',
'cookie': cookie1,
'referer': 'https://www.shangxueba.com/',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
}
answerList = []
for id in idList:
try:
url = 'https://www.shangxueba.com/ask/ajax/zuijiainfo.aspx?id='+id+'&t='+ str(int(t.time() * 1000))
html = requests.get(url,headers=headers)
detail = html.text.split('
',1)[1]
detail = detail.split('',1)[0]
detail = re.sub('
r = requests.get(url,params=data)
result = r.json()
result = result['translateResult'][0][0]['tgt']
print("有道翻译结果:%s" %result)
return result
金山翻译接口抓取
def Jinshan(word,onlyone=0):
def process(Request_URL, Form_Data):
# 使用urlencode方法转换标准格式
data = parse.urlencode(Form_Data).encode('utf-8')
# 传递Request对象和转换完格式的数据
response = request.urlopen(Request_URL, data)
# 读取信息并解码
html = response.read().decode('utf-8')
# 使用JSON
translate_results = json.loads(html)
return translate_results
Request_URL = 'http://fy.iciba.com/ajax.php?a=fy'
# 创建Form_Data字典,存储Form Data
Form_Data = {'f': 'auto',
't': 'auto'}
if onlyone == 0:
Form_Data['w'] = word
translate_results = process(Request_URL, Form_Data)
# 找到翻译结果
if 'out' in translate_results['content']:
translate_results = translate_results['content']['out']
else:
translate_results = translate_results['content']['word_mean']
# 打印翻译信息
print("金山翻译结果:%s" % translate_results)
return translate_results
腾讯翻译君接口抓取
def TencentFY(words):
text = words
a = 0 # 中文数
b = 0 # 非中文数
to = "0"
from_ = "1"
for i in text:
if u'\u4e00' <= i <= u'\u9fff':
a += 1
else:
b += 1
if a > b: # 当中文数量大于非中文数量时,就中文转英文
to = "1"
from_ = "0"
data = {"from": from_,
"to": to,
"sourceText": text,
"type": "1",
"latitude": "1",
"longitude": "1",
"platform": "H5"}
url = "https://m.fanyi.qq.com/translate"
headers = {
"user-agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1"}
response = requests.post(url, headers=headers, data=data)
html = response.content.decode()
html_dict = json.loads(html)
print("腾讯翻译结果:", html_dict["targetText"])
return html_dict["targetText"]
百度单词接口抓取
def baiduWord(keyword):
base_url = 'https://fanyi.baidu.com/sug'
# 构建请求对象
data = {'kw': keyword }
data = parse.urlencode(data)
# 模拟浏览器
header = {"User-Agent": "mozilla/4.0 (compatible; MSIE 5.5; Windows NT)"}
req = request.Request(url=base_url,data=bytes(data,encoding='utf-8'),headers=header)
res = request.urlopen(req)
# 获取响应的json字符串
str_json = res.read().decode('utf-8')
# 把json转换成字典
myjson = json.loads(str_json)
info = myjson['data'][0]['v'].replace('int.','').replace('/n. ','')
print('百度翻译结果:'+info)
return info
4.截图文字识别
百度开放平台提供的多种免费API,其中就有免费文字识别,本程序就是调用了百度的OCR接口,实现截图文字识别。
本功能分三步实现:
第一步:调用微信截图
简单是说就是模拟按键Alt+A
def Alt_A():
import win32api
import win32con
win32api.keybd_event(18, 0, 0, 0) # Alt键位码是18
win32api.keybd_event(65, 0, 0, 0) # v键位码是65
win32api.keybd_event(18, 0, win32con.KEYEVENTF_KEYUP, 0) # 释放按键
win32api.keybd_event(65, 0, win32con.KEYEVENTF_KEYUP, 0)
第二步:从剪切板读取图片(或者从文件中读取)
返回值是图片文件路径(如果是剪切板中读取,会自动将图片保存到本地)
#加载图片
def loadPic(way):#way=0:剪切板读取,way=1:直接上传图片
if way==0:
img = ImageGrab.grabclipboard()
try:
img.save('tmp.png', 'PNG')
except:
return
path = 'tmp.png'
elif way ==1:
path = filedialog.askopenfilename()
第三步:通过百度接口实现文字识别
#文字识别,从剪切板读取图片
def getText(path):
API_KEY ='***' # 百度API秘钥,此处略
SECRECT_KEY = '***' # 百度API秘钥,此处略
# 获取token
url = 'https://aip.baidubce.com/oauth/2.0/token'
body = {'grant_type': 'client_credentials',
'client_id': API_KEY,
'client_secret': SECRECT_KEY
}
req = requests.post(url=url, data=body)
token = json.loads(req.content)['access_token']
# 获取百度api识别结果
ocr_url = 'https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic?access_token=%s'%token
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
# 读取图片并进行base64加密
body = base64.b64encode(open(path ,'rb').read())
# 进行urlencode
data = urllib.parse.urlencode({'image': body})
# post请求
r = requests.post(url=ocr_url, headers=headers, data=data)
# 输出请求结果
print('请求码为: %s' %r.status_code)
res_words = json.loads(r.content)['words_result'][0]['words']
print('识别结果为: %s' % res_words)
return res_words
5.所有函数目录展示
三、实验过程中遇到的问题和解决过程
问题一:OCR接口选择。
查阅各种资料并检测准确率后,选择了百度开发平台API,大厂产品,免费好用。而且使用比较方便。
问题二:上学吧的反爬策略
上学吧的cookie更换速度极快极快,每次都需要重新登录,登录页面有验证码。给爬虫带来了不便,目前此问题仅通过简单的“频繁更换cookie”解决,暂时没有更好的解决方案。
问题三:封装exe后文件过大
虽然是个很简单的小程序,封装以后依然达到了二百多兆字节。启动速度慢,占用内存高。同时,用Python封装的其他程序也存在类似问题,解决方法会慢慢探索……
四、我的感悟与思考
选修Python真是个非常非常正确的选择,简单灵活的语法,丰富的第三方库,让一切都变得有趣简单。
老师的课堂也很热闹,能轻松学到很多东西,整个Python课程范围跨度大,不仅涉及Python基础知识,还有文件操作,数据库,办公自动化,GUI,socket编程,爬虫等知识,在云班课还有pygame相关教程……可以说应有尽有,而且能在短时间内学会,能在短时间内做出一个像样的作品。很有成就感,Python让图形化界面变得简单,也让我爱上了编程。
我觉得编程最重要的往往不是技术,而是想法。只要有了创意,基本都可实现,这一学期,我完成了很多自我感觉良好的项目,和获得了满满的成就感。相信以后能用Python做更多好玩的事。
如果提一提建议的话,我觉得有些地方讲的比较快。而且存在课讲完后,很多同学没有安装库的现象,感觉如果上课的时候,和老师一起敲代码效果会好些,也建议能提前把环境配置好,不然上课很容易跟不上。
感谢Python,感谢这门选修课!