用python包装一个翻译工具
用python包装一个翻译工具
嘻嘻哥 发表于2年前
用python包装一个翻译工具
  • 发表于 2年前
  • 阅读 19
  • 收藏 0
  • 点赞 0
  • 评论 0

腾讯云 学生专属云服务套餐 10元起购>>>   

摘要: 最近在学习python,所以找了个可能用得到的小工具来检测这段时间的学习成果,代码可能会比较冗余,仅供自己学习用 这个翻译工具主要就是模拟网站翻译,不过目前效率比较差,初学也不清楚http的访问怎么优化,以后有时间了再慢慢修改 修改: 界面代码同步调用会卡死,加入多线程处理

下面附上最近两个版本的改动,v0、v1就不上传了

v2版代码如下:

import urllib.request
import urllib.parse
import json
import random

"""V2 相比V1版本,增加伪装功能-->使用代理服务器"""
#当前不使用代理,可以跳过代理部分
bUseProxy = 0
ipLists = ['183.203.208.166:8118', '114.215.108.155:9999', '218.78.210.190:8080', '124.202.175.70:8118']

def testProxy():
    """测试代理ip是否生效"""
    bUseProxy = 1
    url = 'http://www.whatismyip.com.tw'
    response = openUrlByProxy(url)
    html = response.read().decode('utf-8')
    print(html)
    

def openUrlByProxy(url, data = None):
    """
    url(which can be a request object or a string)
    使用代理(如果使能)打开url地址,返回response对象
    """
    response = 0
    global bUseProxy
    if bUseProxy == 1:
        proxyIp = {"http" : random.choice(ipLists)}
        proxy_support = urllib.request.ProxyHandler(proxyIp)
        opener = urllib.request.build_opener(proxy_support)

        #这种方式是替换系统默认的opener,后续所有打印的url都是通过代理打开
        #urllib.request.install_opener(opener)
        #response = urllib.request.urlopen(url, data)

        #这种方式是由自己创建的代理opener来打开url,不会影响后续的非代理打开
        response = opener.open(url, data)
    else:
        response = urllib.request.urlopen(url, data)
    return response

def parseUrl(strurl, data = None):
    #修改header里的User-Agent,伪装成浏览器访问,下面两种方式均可以
    header = {"User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Maxthon/4.4.5.1000 Chrome/30.0.1599.101 Safari/537.36"}
    req = urllib.request.Request(strurl, headers = header)
    #req.add_header("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Maxthon/4.4.5.1000 Chrome/30.0.1599.101 Safari/537.36")
    #print(req.headers)
    
    #也可以直接省去上面这句Request调用,直接将strurl传给urlopen替换参数req
    #response = urllib.request.urlopen(req, data)

    #v2版本增加了使用代理功能
    response = openUrlByProxy(req, data)
    
    #type(response)  <class 'http.client.HTTPResponse'>
    #print(response.info())#  查看信息
    html = response.read().decode('utf-8')
    #type(html) <class 'str'>
    return json.loads(html)

def baiduTranslate(content, _from_, _to_):
    if (_from_ == 'auto'):
        _from_ = ''
    if (_to_ == 'auto'):
        _to_ = 'zh' if content[0] < chr(127) else 'en'
    data = {}
    data['from'] = _from_
    data['to'] = _to_
    data['query'] = content
    data['transtype'] = 'trans'
    data['simple_means_flag'] = '3'

    data = urllib.parse.urlencode(data).encode('utf-8')

    target = parseUrl("http://fanyi.baidu.com/v2transapi", data)
    return target['trans_result']['data'][0]['dst']

def youdaoTranslate(content, _from_, _to_):
    data = {}
    data['type'] = 'AUTO' if _from_ == 'auto' else _from_ + "2" + _to_
    data['i'] = content
    data['doctype'] = 'json'
    data['xmlVersion'] = '1.6'
    data['keyfrom'] = 'fanyi.web'
    data['ue'] = 'UTF-8'
    data['typoResult'] = 'true'
    data = urllib.parse.urlencode(data).encode('utf-8')
    
    target = parseUrl("http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule&smartresult=ugc&sessionFrom=http://www.youdao.com/", data)
    return target['translateResult'][0][0]['tgt']

def bingTranslate(content, _from_, _to_):
    """ 自动:auto, 中文:zh, 英文:en """
    if (_from_ == 'auto'):
        _from_ = ''
    if (_to_ == 'auto'):
        _to_ = 'zh' if content[0] < chr(127) else 'en'
        
    data = {}
    data['from'] = '"' + _from_ + '"'
    data['to'] = '"' + _to_ + '"'
    data['texts'] = '["'
    data['texts'] += content
    data['texts'] += '"]'
    data['options'] = "{}"
    data['oncomplete'] = 'onComplete_3'
    data['onerror'] = 'onError_3'
    data['_'] = '1430745999189'
    data = urllib.parse.urlencode(data).encode('utf-8')
    #appid需要去申请,暂时先用网上别人提供的
    strUrl = "http://api.microsofttranslator.com/v2/ajax.svc/TranslateArray2?" + data.decode() + "&appId=%223DAEE5B978BA031557E739EE1E2A68CB1FAD5909%22"

    response = urllib.request.urlopen(strUrl)
    #通过response.info()查看Content-Type: application/x-javascript
    #不能通过json.loads(),到时候查看如何解析,显示使用老土的方法
    str_data = response.read().decode('utf-8')
    tmp,str_data = str_data.split('"TranslatedText":')
    translate_data = str_data[1:str_data.find('"', 1)]
    return translate_data

def googleTranslate(content, _from_, _to_):
    """ 自动:auto, 中文:zh, 英文:en """
    if (_to_ == 'auto'):
        _to_ = 'zh' if content[0] < chr(127) else 'en'
    data = {}
    data['from'] = _from_
    data['to'] = _to_
    data['text'] = content
    data = urllib.parse.urlencode(data).encode('utf-8')

    target = parseUrl("http://brisk.eu.org/api/translate.php?" + data.decode())
    return target['res']

if __name__ == "__main__":
    select = int(input("请选择翻译工具:1.百度,2.有道,3.必应, 4.谷歌, 5.全部:"))
    content = input('请输入要翻译的内容:')
    data = {}

    """
    data字典里填的数据和url可以在具体的翻译网页,右键点击审查元素(inspect element),然后再点击网络(network)
    然后点击左右的列表项,看右边的预览(preview)是否有结果,如果有结果,则点击预览(preview)旁边的http头(headers)
    最开始的Request URL即我们需要传给urlopen的,然后下面的表单数据(from data)就是需要传给服务器的字典数据结构
    """

    if select == 1:
        print(baiduTranslate(content, 'auto', 'auto'))
    elif select == 2:
        print(youdaoTranslate(content, 'auto', 'auto'))
    elif select == 3:
        print(bingTranslate(content, 'auto', 'auto'))
    elif select == 4:
        print(googleTranslate(content, 'auto', 'auto'))
    elif select == 10000:
        print("百度:" + baiduTranslate(content, 'zh', 'en'))
        print("有道:" + youdaoTranslate(content, 'zh', 'en'))
        print("必应:" + bingTranslate(content, 'zh', 'en'))
        print("谷歌:" + googleTranslate(content, 'zh', 'en'))
    elif select == 10001:
        print("百度:" + baiduTranslate(content, 'en', 'zh'))
        print("有道:" + youdaoTranslate(content, 'en', 'zh'))
        print("必应:" + bingTranslate(content, 'en', 'zh'))
        print("谷歌:" + googleTranslate(content, 'en', 'zh'))
    else:
        print("百度:" + baiduTranslate(content, 'auto', 'auto'))
        print("有道:" + youdaoTranslate(content, 'auto', 'auto'))
        print("必应:" + bingTranslate(content, 'auto', 'auto'))
        print("谷歌:" + googleTranslate(content, 'auto', 'auto'))

最新版上增加了界面操作,代码如下(需要import v2版的包,界面也是边学边用,以前写过其它界面代码,所以学起来比较快)

import tkinter as tk
import TranslateEngine.translation_v2 as te
import threading

class myTranslator:
    def __init__(self, root):
        self.typeList = []
        self.typeVal = 0
        self.inputEntry = 0

        self.baiduText = ""
        self.youdaoText = ""
        self.googleText = ""
        self.bingText = ""
        
        self.root = root
        self.root.geometry("500x500+700+300")
        self.root.minsize(width=500, height=500)
        self.root.title('富哥的翻译器')
        self.initInputLayout()
        self.initDisplayLayout()
    
    #界面代码同步调用会卡死,加入多线程处理
    def __AsyncCallTranslate(self, *args, **kwargs):
        if (kwargs['name'] == 'baidu'):
            self.baiduText.set(te.baiduTranslate(*args))
        elif (kwargs['name'] == 'youdao'):
            self.youdaoText.set(te.youdaoTranslate(*args))
        elif (kwargs['name'] == 'bing'):
            self.bingText.set(te.bingTranslate(*args))
        elif (kwargs['name'] == 'google'):
            self.googleText.set(te.googleTranslate(*args))
    
    def TranslateButtonCallback(self):
        selectedType = self.typeVal.get()
        _from_, to = ('auto', 'auto') if selectedType[0] == '自' else ('en', 'zh') if selectedType[0] == '英' else ('zh', 'en')
        content = self.inputEntry.get()
        threading.Thread(target=self.__AsyncCallTranslate, args=(content, _from_, to), kwargs={'name':'baidu'}).start()
        threading.Thread(target=self.__AsyncCallTranslate, args=(content, _from_, to), kwargs={'name':'youdao'}).start()
        threading.Thread(target=self.__AsyncCallTranslate, args=(content, _from_, to), kwargs={'name':'bing'}).start()
        threading.Thread(target=self.__AsyncCallTranslate, args=(content, _from_, to), kwargs={'name':'google'}).start()
        #self.baiduText.set(te.baiduTranslate(content, _from_, to))
        #self.youdaoText.set(te.youdaoTranslate(content, _from_, to))
        #self.bingText.set(te.bingTranslate(content, _from_, to))
        #self.googleText.set(te.googleTranslate(content, _from_, to))

    def EnterReturnCallback(self, event):
        self.TranslateButtonCallback()

    def initInputLayout(self):
        self.inputFrame = tk.Frame(self.root, height=50)

        self.typeList = ['自  动', '中->英', '英->中']
        self.typeVal = tk.StringVar()
        self.typeVal.set(self.typeList[0])
        tk.OptionMenu(self.inputFrame, self.typeVal, *self.typeList).pack(fill='y', side='left', ipadx=10)

        self.inputEntry = tk.Entry(self.inputFrame)
        self.inputEntry.bind('<Key-Return>', self.EnterReturnCallback)
        self.inputEntry.pack(fill='both', side='left', expand=1)
        self.inputEntry.focus_set()
            
        tk.Button(self.inputFrame, text="翻译", bg='green', command=self.TranslateButtonCallback).pack(fill='y', side='right', ipadx=10)
        self.inputFrame.pack(fill='x')


    def initDisplayLayout(self):
        displayFrame = tk.Frame(self.root)

        #添加分割线
        tk.Frame(displayFrame, height=2, bd=1, relief='sunken').pack(fill='x', pady=5)

        tk.Label(displayFrame, text="百度翻译:", height=1, anchor='w').pack(fill='x')
        self.baiduText = tk.StringVar()
        tk.Label(displayFrame, textvariable = self.baiduText, anchor='nw', fg='blue').pack(fill='both', expand=1)
        #添加分割线
        tk.Frame(displayFrame, height=2, bd=1, relief='sunken').pack(fill='x')

        tk.Label(displayFrame, text="有道翻译:", height=1, anchor='w').pack(fill='x')
        self.youdaoText = tk.StringVar()
        tk.Label(displayFrame, textvariable = self.youdaoText, anchor='nw', fg='blue').pack(fill='both', expand=1)
        #添加分割线
        tk.Frame(displayFrame, height=2, bd=1, relief='sunken').pack(fill='x')

        tk.Label(displayFrame, text="谷歌翻译:", height=1, anchor='w').pack(fill='x')
        self.googleText = tk.StringVar()
        tk.Label(displayFrame, textvariable = self.googleText, anchor='nw', fg='blue').pack(fill='both', expand=1)
        #添加分割线
        tk.Frame(displayFrame, height=2, bd=1, relief='sunken').pack(fill='x')

        tk.Label(displayFrame, text="必应翻译:", height=1, anchor='w').pack(fill='x')
        self.bingText = tk.StringVar()
        tk.Label(displayFrame, textvariable = self.bingText, anchor='nw', fg='blue').pack(fill='both', expand=1)
        #添加分割线
        tk.Frame(displayFrame, height=2, bd=1, relief='sunken').pack(fill='x')

        displayFrame.pack(fill='both', expand=1)


if __name__ == '__main__':
    root = tk.Tk()
    myTranslator(root)
    tk.mainloop()

最后的效果如下:

共有 人打赏支持
粉丝 0
博文 6
码字总数 8981
×
嘻嘻哥
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: