《Python程序设计》实验四报告_搜索小助手

20192213 《Python程序设计》实验四报告

课程:《Python程序设计》
班级: 1922
姓名: 刘子谦
学号:20192213
实验教师:王志强
实验日期:2020年6月10日
必修/选修: 公选课

1.实验内容

1.程序功能说明

  • 定位:搜索小工具

  • 目标:实现高效搜索,帮助网课学生快速找到答案,实现搜索自动化。

  • 具体功能:有以下四个:

    • 多引擎搜索
    • 上学吧搜索
    • 多引擎翻译
    • 截图文字识别
  • 接口说明:

    • 百度开放平台API提供OCR识别
    • 有道翻译提供翻译
    • 金山翻译提供翻译
    • 腾讯翻译君翻译提供翻译
    • 百度单词提供单词查询
    • 截图功能调用微信截图
    • 上学吧提供部分题目答案

2.程序实现思路

爬取文本 + 接口爬虫 + GUI界面

3.程序效果展示

  • 首页(有我的logo,有使用说明)
    《Python程序设计》实验四报告_搜索小助手_第1张图片

  • 多引擎搜索
    《Python程序设计》实验四报告_搜索小助手_第2张图片

  • 上学吧搜索
    《Python程序设计》实验四报告_搜索小助手_第3张图片

  • 多引擎翻译
    《Python程序设计》实验四报告_搜索小助手_第4张图片

  • 截图文字识别
    《Python程序设计》实验四报告_搜索小助手_第5张图片

二、实验过程及结果

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('
  • ',2)[2] title = title.split('')[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('3.多引擎翻译

    本功能实际是四个接口爬虫,爬取有道、金山、腾讯、百度的翻译接口,仅供个人使用。
    上述四大网站,都很有社会责任感,无偿将接口贡献出来,而且接口本身几乎无任何反爬,通过简单的程序即可抓取

    • 有道翻译接口抓取
    def youdao(words):  
        string = words  
        data = {  
        'doctype': 'json',  
        'type': 'AUTO',  
        'i':string  
        }  
        url = "http://fanyi.youdao.com/translate"  
        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.所有函数目录展示

    《Python程序设计》实验四报告_搜索小助手_第6张图片

    三、实验过程中遇到的问题和解决过程

    问题一:OCR接口选择。

    查阅各种资料并检测准确率后,选择了百度开发平台API,大厂产品,免费好用。而且使用比较方便。

    问题二:上学吧的反爬策略

    上学吧的cookie更换速度极快极快,每次都需要重新登录,登录页面有验证码。给爬虫带来了不便,目前此问题仅通过简单的“频繁更换cookie”解决,暂时没有更好的解决方案。

    问题三:封装exe后文件过大

    虽然是个很简单的小程序,封装以后依然达到了二百多兆字节。启动速度慢,占用内存高。同时,用Python封装的其他程序也存在类似问题,解决方法会慢慢探索……

    四、我的感悟与思考

    选修Python真是个非常非常正确的选择,简单灵活的语法,丰富的第三方库,让一切都变得有趣简单。

    老师的课堂也很热闹,能轻松学到很多东西,整个Python课程范围跨度大,不仅涉及Python基础知识,还有文件操作,数据库,办公自动化,GUI,socket编程,爬虫等知识,在云班课还有pygame相关教程……可以说应有尽有,而且能在短时间内学会,能在短时间内做出一个像样的作品。很有成就感,Python让图形化界面变得简单,也让我爱上了编程。

    我觉得编程最重要的往往不是技术,而是想法。只要有了创意,基本都可实现,这一学期,我完成了很多自我感觉良好的项目,和获得了满满的成就感。相信以后能用Python做更多好玩的事。

    如果提一提建议的话,我觉得有些地方讲的比较快。而且存在课讲完后,很多同学没有安装库的现象,感觉如果上课的时候,和老师一起敲代码效果会好些,也建议能提前把环境配置好,不然上课很容易跟不上。

    感谢Python,感谢这门选修课!

    你可能感兴趣的:(《Python程序设计》实验四报告_搜索小助手)