python利用tkinter开发翻译小工具(基于百度翻译和有道翻译爬虫)

import

import requests
import hashlib
import time
import random
import urllib3
import re
import js2py
import tkinter as tk
from tkinter import *
from tkinter import ttk
import threading

urllib3.disable_warnings()

有道翻译爬虫代码

class YouDaoFanYi:
    def __init__(self):
        self.t = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36"
        self.bv = hashlib.md5(bytes(self.t,encoding="utf-8")).hexdigest()
        self.headers = {"Content-Type": "application/x-www-form-urlencoded",
                       "User-Agent": self.t,
                       "Referer":"http://fanyi.youdao.com/"}
        cookies = self.__get_init_cookies()
        self.session = requests.Session()
        self.session.headers.update(self.headers)
        self.session.cookies.update(cookies)
        self.language = {"中文":"zh-CHS",
                         "英文":"en",
                         "韩文":"ko"}

    def __get_init_cookies(self):
        headers = {"User-Agent": self.t}
        res = requests.get("http://fanyi.youdao.com/",headers=headers)
        assert res.status_code==200
        return res.cookies

    def get_auth_data(self, keyword):
        r = str(int(round(time.time(),3)*1000))
        ts = r      #1585970420994
        i = ts + str(random.randint(1,10))
        salt = i #15859705441292
        sign = hashlib.md5(bytes("fanyideskweb" + keyword + salt +"Nw(nmmbP%A-r6U3EUn]Aj",encoding="utf-8")).hexdigest()
        return ts,salt,sign

    @get_translate_result
    def translate(self, keyword, from_language, to_language):
        from_language = self.language[from_language]
        to_language = self.language[to_language]
        ts,salt,sign = self.get_auth_data(keyword)
        url = "http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule"
        data = {"i": keyword,
                "from": from_language,
                "to": to_language,
                "smartresult": "dict",
                "client": "fanyideskweb",
                "salt": salt,
                "sign": sign,
                "ts": ts,
                "bv": self.bv,
                "doctype": "json",
                "version": "2.1",
                "keyfrom": "fanyi.web",
                "action": "Y_BY_CLICKBUTTION"}
        res = self.session.post(url,params=data)
        assert res.status_code==200
        return res.json()

百度翻译爬虫代码

class BaiDuFanYi:
    def __init__(self):
        self.user_agent = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.81 Safari/537.36'
        self.cookies = None
        self.gtk = None
        self.token = None
        self.__get_init_cookies()
        self.headers = {"Content-Type": "application/x-www-form-urlencoded",
                       "User-Agent": self.user_agent}
        self.session = requests.Session()
        self.session.headers.update(self.headers)
        self.session.cookies.update(self.cookies)
        self.language = {"中文":"zh",
                         "英文":"en",
                         "韩文":"kor"}
    def __get_init_cookies(self):
        headers = {'User-Agent': self.user_agent}
        url = "https://fanyi.baidu.com/"
        res = requests.get(url, verify=False)
        self.cookies = res.cookies
        gtk = re.findall(r";window.gtk = ('.*?');", res.text)[0]
        self.gtk = gtk
        assert res.status_code==200
        res = requests.get(url, headers=headers, cookies=res.cookies, verify=False)
        assert res.status_code==200
        token = re.findall(r"token: '(.*?)'", res.text)[0]
        self.token = token
    
    def __get_sign(self, keyword):
        js = r"""
            function n(r, o) {
                for (var t = 0; t < o.length - 2; t += 3) {
                var a = o.charAt(t + 2);
                a = a >= "a" ? a.charCodeAt(0) - 87 : Number(a), a = "+" === o.charAt(t + 1) ? r >>> a : r << a, r = "+" === o.charAt(t) ? r + a & 4294967295 : r ^ a
                }
                return r
            }
            function e(r) {
                var o = r.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g);
                if (null === o) {
                    var t = r.length;
                    t > 30 && (r = "" + r.substr(0, 10) + r.substr(Math.floor(t / 2) - 5, 10) + r.substr(-10, 10))
                } else {
                    for (var e = r.split(/[\uD800-\uDBFF][\uDC00-\uDFFF]/), C = 0, h = e.length, f = []; h > C; C++) "" !== e[C] && f.push.apply(f, a(e[C].split(""))), C !== h - 1 && f.push(o[C]);
                    var g = f.length;
                    g > 30 && (r = f.slice(0, 10).join("") + f.slice(Math.floor(g / 2) - 5, Math.floor(g / 2) + 5).join("") + f.slice(-10).join(""))
                }
                var u = void 0, l = "" + String.fromCharCode(103) + String.fromCharCode(116) + String.fromCharCode(107);
                u = null !== i ? i : (i = window[l] || "") || "";
                for (var d = u.split("."), m = Number(d[0]) || 0, s = Number(d[1]) || 0, S = [], c = 0, v = 0; v < r.length; v++) {
                    var A = r.charCodeAt(v);
                    128 > A ? S[c++] = A : (2048 > A ? S[c++] = A >> 6 | 192 : (55296 === (64512 & A) && v + 1 < r.length && 56320 === (64512 & r.charCodeAt(v + 1)) ? (A = 65536 + ((1023 & A) << 10) + (1023 & r.charCodeAt(++v)), S[c++] = A >> 18 | 240, S[c++] = A >> 12 & 63 | 128) : S[c++] = A >> 12 | 224, S[c++] = A >> 6 & 63 | 128), S[c++] = 63 & A | 128)
                }
                for (var p = m, F = "" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(97) + ("" + String.fromCharCode(94) + String.fromCharCode(43) + String.fromCharCode(54)), D = "" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(51) + ("" + String.fromCharCode(94) + String.fromCharCode(43) + String.fromCharCode(98)) + ("" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(102)), b = 0; b < S.length; b++) p += S[b], p = n(p, F);
                return p = n(p, D), p ^= s, 0 > p && (p = (2147483647 & p) + 2147483648), p %= 1e6, p.toString() + "." + (p ^ m)
            }"""
        # js中替换gtk
        js = js.replace(r'null !== i ? i : (i = window[l] || "") || ""', self.gtk)
        # 执行js,定义加密函数e(r)
        context = js2py.EvalJs()
        context.execute(js)
        # 执行加密函数e(r),对keywords进行加密
        sign = context.e(keyword)
        return sign
    
    @get_translate_result
    def translate(self, keyword, from_language, to_language):
        from_language = self.language[from_language]
        to_language = self.language[to_language]
        sign = self.__get_sign(keyword)
        data = {
                'from': from_language,
                'to': to_language,
                'query': keyword,
                'transtype': 'translang',
                'simple_means_flag': 3,
                'sign': sign,  # 此参数需破解
                'token': self.token,  # 此参数需破解
                'domain': 'common'
                }
        res = self.session.post("https://fanyi.baidu.com/v2transapi?from=zh&to=en", data=data, verify=False)
        assert res.status_code==200
        return res.json()

获取翻译结果(装饰器)

def get_translate_result(func):
    def inner(word, *arg):
        res_json = func(word, *arg)
        if "trans_result" in res_json.keys():
            result_list = []
            for result in res_json["trans_result"]["data"]:
                result_list.append(result["dst"])
            return "\n".join(result_list)
        elif "translateResult" in res_json.keys():
            result_list = []
            for result in res_json["translateResult"]:
                for info in result:
                    result_list.append(info["tgt"])
            return "\n".join(result_list)
        else:
            return "Translation failed, Please try again later."
    return inner

构造GUI

class CreateGUI:
    def __init__(self):
        self.win = self.__create_win()
        self.setting_frame = tk.Frame(self.win)
        self.translate_frame = tk.Frame(self.win)
        self.select_tool_var = tk.StringVar()
        self.select_from_language_var = tk.StringVar()
        self.select_to_language_var = tk.StringVar()
        self.translate_tag_input = Text(self.translate_frame,
                                        width=60,
                                        height=10,
                                        font=('Arial', 14))
        self.translate_result_input = Text(self.translate_frame,
                                width=60,
                                height=10,
                                font=('Arial', 14))
        self.youdao_obj = YouDaoFanYi()
        self.baidu_obj = BaiDuFanYi()
        
    def __create_win(self):
        win = tk.Tk()
        win.title("翻译工具")
        win.geometry("700x600+300+200")
        win.wm_resizable(False, False)
        return win
    
    def set_base_setting(self):
        self.setting_frame.grid(row=0)
        tk.Label(self.setting_frame, text="请选择工具").grid(row=0, column=0)
        select_tool = ttk.OptionMenu(self.setting_frame, self.select_tool_var, "百度翻译", "有道翻译", "百度翻译")
        select_tool.grid(row=0, column=1)
        tk.Label(self.setting_frame, text="请选择语言").grid(row=1, column=0)
        select_from_language = ttk.OptionMenu(self.setting_frame, self.select_from_language_var, "中文", "英文", "韩文","中文")
        select_from_language.grid(row=1, column=1)
        select_to_language = ttk.OptionMenu(self.setting_frame, self.select_to_language_var, "英文", "中文", "韩文", "英文")
        select_to_language.grid(row=1, column=3)
        #转换语言button
        Button(self.setting_frame, text="交换语言", command=lambda :self.__thread_it(self.exchange_language)).grid(row=1, column=2)
        
    def exchange_language(self):
        from_language = self.select_from_language_var.get()
        to_language = self.select_to_language_var.get()
        self.select_from_language_var.set(to_language)
        self.select_to_language_var.set(from_language)
        
    def set_translate(self):
        self.translate_frame.grid(row=1)
        tk.Label(self.translate_frame, text="目标语句").grid(row=0, column=0)
        self.translate_tag_input.grid(row=1, column=0)
        tk.Label(self.translate_frame, text="翻译结果").grid(row=3, column=0)
        Button(self.translate_frame, text="翻译", command=lambda :self.__thread_it(self.request_translate)).grid(row=3, sticky=tk.E)
        self.translate_result_input.grid(row=4, column=0)
        
    def request_translate(self):
        self.translate_result_input.delete(0.0, END)
        translate_tool = self.select_tool_var.get()
        from_language = self.select_from_language_var.get()
        to_language = self.select_to_language_var.get()
        keyword = self.translate_tag_input.get(0.0, END)
        if translate_tool=="百度翻译":
            result = self.baidu_obj.translate(keyword, from_language, to_language)
        elif translate_tool=="有道翻译":
            result = self.youdao_obj.translate(keyword, from_language, to_language)
        else:
            pass
        self.translate_result_input.insert(0.0, result)
    
    def __thread_it(self, func, *args):
        '''将函数打包进线程'''
        # 创建
        t = threading.Thread(target=func, args=args) 
        # 守护 !!!
        t.setDaemon(True) 
        # 启动
        t.start()
        # 阻塞--卡死界面!
        # t.join()  

def run():
    obj = CreateGUI()
    obj.set_base_setting()
    obj.set_translate()
    tk.mainloop()
    
if __name__=="__main__":
    run()

打包为可执行文件exe

  1. 安装pip install pyinstaller
  2. 打包pyinstaller -F myFanYi.py
  3. 如果在运行exex时不想打开命令行提示窗口,可以修改myFanYi.spec (console=False)
    然后在执行pyinstaller -F myFanYi.py --noconsole
    python利用tkinter开发翻译小工具(基于百度翻译和有道翻译爬虫)_第1张图片
    python利用tkinter开发翻译小工具(基于百度翻译和有道翻译爬虫)_第2张图片

你可能感兴趣的:(测试开发,python,爬虫)