python实现多接口翻译软件
本实验用pyqt5做了一个小软件,里面使用了市面上主流的6种翻译软件接口:谷歌、百度、有道、金山词霸、腾讯、必应,界面如图所示:
以下是程序代码:
import time,sys,os,hashlib,json,re
import requests,execjs,random,js2py
from PyQt5 import QtWidgets,sip
from PyQt5.QtWidgets import QApplication,QWidget,QLabel,QLineEdit,QPushButton,QGridLayout
from PyQt5.QtGui import *
import urllib.request
import urllib.parse
import PyQt5
#检验是否含有中文字符
def language(strs):
for char in strs:
if (u'\u4e00' <= char and char <= u'\u9fff'):
return 'zh','en'#含有中文
return 'en','zh'#不含有中文
class Baidu():
def __init__(self):
self.url = 'https://fanyi.baidu.com/v2transapi?from=zh&to=en'
self.header = {
'content-type': 'application/x-www-form-urlencoded;charset=UTF-8',
'origin': 'https://fanyi.baidu.com',
'referer': 'https://fanyi.baidu.com/?aldtype=16047',
'user-agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36",
'x-requested-with': 'XMLHttpRequest',
'cookie': 'BIDUPSID=D3290C65C03AEF0E98D97B8641DFFB15; PSTM=1570785944; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; BAIDUID=0CC6F13854E81A68D3C564D36E7C8A03:FG=1; APPGUIDE_8_2_2=1; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; BDSFRCVID=wt_OJeC626EDLgju-c_JbHce7gSxbKcTH6aoxbIy4_AgXmAxrp74EG0PJf8g0Ku-dWitogKKBmOTHg-F_2uxOjjg8UtVJeC6EG0Ptf8g0M5; H_BDCLCKID_SF=JJkO_D_atKvjDbTnMITHh-F-5fIX5-RLf5TuLPOF5lOTJh0RbtOkjnQD-UL82bT2fRcQ0tJLb4DaStJbLjbke6cbDa_fJ5Fs-I5O0R4854QqqR5R5bOq-PvHhxoJqbbJX2OZ0l8KtDQpshRTMR_V-p4p-472K6bML5baabOmWIQHDPnPyJuMBU_sWMcChnjjJbn4KKJxWJLWeIJo5Dcf3PF3hUJiBMjLBan7056IXKohJh7FM4tW3J0ZyxomtfQxtNRJ0DnjtpChbRO4-TF-D5jXeMK; delPer=0; PSINO=2; H_PS_PSSID=1435_21104_18560_26350; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1580216234,1580216243,1580458514,1580458537; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1580458539; __yjsv5_shitong=1.0_7_ed303110bee0e644d4985049ba8a5cd1f28d_300_1580458537306_120.10.109.208_66a3b40c; yjs_js_security_passport=630340c0505f771135167fa6df3e5215699dcf0b_1580458538_js; to_lang_often=%5B%7B%22value%22%3A%22zh%22%2C%22text%22%3A%22%u4E2D%u6587%22%7D%2C%7B%22value%22%3A%22en%22%2C%22text%22%3A%22%u82F1%u8BED%22%7D%5D; from_lang_often=%5B%7B%22value%22%3A%22vie%22%2C%22text%22%3A%22%u8D8A%u5357%u8BED%22%7D%2C%7B%22value%22%3A%22en%22%2C%22text%22%3A%22%u82F1%u8BED%22%7D%2C%7B%22value%22%3A%22zh%22%2C%22text%22%3A%22%u4E2D%u6587%22%7D%5D'
}
self.data = None
def get_sign_ctx(self):
ctx = execjs.compile(
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 =' """ + str(self.get_gtk()) + r""" ';
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)
}
"""
)
return ctx
def get_sign(self, text):
ctx = self.get_sign_ctx()
sign = ctx.call("e", text)
# print(sign)
return sign
def get_token(self):
s = requests.session()
url = 'https://fanyi.baidu.com/'
html = requests.get(url, headers=self.header)
html = html.text
# print(html)
raw_tk_str = str(re.search('token:.*,', html))
token = raw_tk_str.split('\'')[1]
# print(token)
return token
def get_cookie(self):
import urllib.request
import http.cookiejar
cookie = http.cookiejar.CookieJar()
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler)
response = opener.open('https://fanyi.baidu.com/?aldtype=16047#zh/en/aa%E9%80%9F%E5%BA%A6')
# print(response)
for item in cookie:
print('%s = %s' % (item.name, item.value))
def get_gtk(self):
url = 'https://fanyi.baidu.com/'
html = requests.get(url)
html = html.text
raw_gtk_str = str(re.search('window.gtk = .*;', html))
gtk = raw_gtk_str.split('\'')[1]
# print('gtk '+gtk)
return gtk
def get_data(self, text,from_lan, to_lan):
data = {}
data['from'] = from_lan
data['to'] = to_lan
data['query'] = text
data['simple_means_flag'] = 3
data['transtype'] = 'realtime'
data['sign'] = self.get_sign(text)
data['token'] = self.get_token()
return data
def translate(self, text, from_lan, to_lan):
try:
self.data = self.get_data(text, from_lan, to_lan)
response = requests.post(self.url, headers=self.header, data=self.data)
#print('百度翻译结果为:',response.json()['trans_result']['data'][0]['dst'])
return response.json()['trans_result']['data'][0]['dst']
except:
return '程序出现了一点小问题,无法翻译'
class Bing():
def __init__(self):
self.url = "http://api.microsofttranslator.com/v2/ajax.svc/TranslateArray2?"
def translate(self,content,from_lan, to_lan):
try:
data = {}
data['from'] = '"' + from_lan + '"'
data['to'] = '"' + to_lan + '"'
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')
strUrl = self.url + data.decode() + "&appId=%223DAEE5B978BA031557E739EE1E2A68CB1FAD5909%22"
response = urllib.request.urlopen(strUrl)
str_data = response.read().decode('utf-8')
#print(str_data)
tmp, str_data = str_data.split('"TranslatedText":')
translate_data = str_data[1:str_data.find('"', 1)]
#print('必应翻译结果为:',translate_data)
return translate_data
except:
return '程序出现了一点小问题,无法翻译'
class Ciba():
def __init__(self, word,lan,tolan):
self.word = word
self.url = 'http://fy.iciba.com/ajax.php?a=fy'
self.headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) '
'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36'
}
# 构造post请求的参数
self.post_data = {
'f': lan,
't': tolan,
'w': self.word
}
# 发送请求
def request_post(self):
res = requests.post(url=self.url, headers=self.headers, data=self.post_data)
# print(res.content.decode())
return res.content.decode()
# 解析数据
@staticmethod
def parse_data(data):
dict_data = json.loads(data)
if 'out' in dict_data['content']:
return dict_data['content']['out']
elif 'word_mean' in dict_data['content']:
return dict_data['content']['word_mean']
def translate(self):
data = self.request_post()
try:
#print('词霸翻译结果为:',self.parse_data(data))
return self.parse_data(data)
except:
return '程序出现了一点小问题,无法翻译'
class Youdao():
def translate(self,content,lan,tolan):
try:
# 解决反爬机制
u = 'fanyideskweb'
d = content
url = 'http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule'
f = str(int(time.time()*1000) + random.randint(1,10)) # 时间戳
c= 'rY0D^0\'nM0}g5Mm1z%1G4'
sign = hashlib.md5((u + d + f + c).encode('utf-8')).hexdigest() # md5加密,生成一个随机数
head={}
head['User-Agent'] = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'
data = {}
# data 有道翻译数据表单
data['i'] = content
data['from'] = lan#'AUTO'
data['to'] = tolan#'AUTO'
data['smartresult'] = 'dict'
data['client'] = 'fanyideskweb'
data['salt'] = f # salt 与 sign 反爬机制 ,每次都会变化 salt就是时间戳
data['sign'] = sign # 使用的是u + d + f + c的md5的值。
data['ts'] = '1551506287219'
data['bv'] = '97ba7c7fb78632ae9b11dcf6be726aee'
data['doctype'] = 'json'
data['version'] = '2.1'
data['keyfrom'] = 'fanyi.web'
data['action'] = 'FY_BY_REALTIME'
data['typoResult'] = 'False'
data = urllib.parse.urlencode(data).encode('utf-8')
request = urllib.request.Request(url=url,data=data,headers=head, method='POST')
response = urllib.request.urlopen(request)
line = json.load(response) # 将得到的字符串转换成json格式
text=''
for x in line['translateResult']:
text += x[0]['tgt']
#print('有道翻译结果为:',text)
return text
except:
return '程序出现了一点小问题,无法翻译'
class Google():
def __init__(self):
self.ctx = execjs.compile("""
function TL(a) {
var k = "";
var b = 406644;
var b1 = 3293161072;
var jd = ".";
var $b = "+-a^+6";
var Zb = "+-3^+b+-f";
for (var e = [], f = 0, g = 0; g < a.length; g++) {
var m = a.charCodeAt(g);
128 > m ? e[f++] = m : (2048 > m ? e[f++] = m >> 6 | 192 : (55296 == (m & 64512) && g + 1 < a.length && 56320 == (a.charCodeAt(g + 1) & 64512) ? (m = 65536 + ((m & 1023) << 10) + (a.charCodeAt(++g) & 1023),
e[f++] = m >> 18 | 240,
e[f++] = m >> 12 & 63 | 128) : e[f++] = m >> 12 | 224,
e[f++] = m >> 6 & 63 | 128),
e[f++] = m & 63 | 128)
}
a = b;
for (f = 0; f < e.length; f++) a += e[f],
a = RL(a, $b);
a = RL(a, Zb);
a ^= b1 || 0;
0 > a && (a = (a & 2147483647) + 2147483648);
a %= 1E6;
return a.toString() + jd + (a ^ b)
};
function RL(a, b) {
var t = "a";
var Yb = "+";
for (var c = 0; c < b.length - 2; c += 3) {
var d = b.charAt(c + 2),
d = d >= t ? d.charCodeAt(0) - 87 : Number(d),
d = b.charAt(c + 1) == Yb ? a >>> d: a << d;
a = b.charAt(c) == Yb ? a + d & 4294967295 : a ^ d
}
return a
}
""")
def getTk(self,text):
return self.ctx.call("TL",text)
def translate(self,content,lan,tolan):
tk = self.getTk(content)
try:
if len(content) > 4891:
print("翻译的长度超过限制!!!")
return
param = {'tk': tk, 'q': content}
# 英译中url
if(lan == 'en'):
result = requests.get("""http://translate.google.cn/translate_a/single?client=t&sl=en
&tl=zh-CN&hl=zh-CN&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss
&dt=t&ie=UTF-8&oe=UTF-8&clearbtn=1&otf=1&pc=1&srcrom=0&ssel=0&tsel=0&kc=2""",params=param)
# 中译英url
else:
result = requests.get("""https://translate.google.cn/translate_a/single?client=webapp
&sl=zh-CN&tl=en&hl=zh-CN&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca
&dt=rw&dt=rm&dt=ss&dt=t&swap=1&otf=2&ssel=5&tsel=5&kc=1&""", params=param)
# print(result.json())
text=''
data=result.json()[0]
for vlue in data:
if not vlue[0] is None:
text+=vlue[0]
#print('谷歌翻译结果为:',text)
return text
except :
return '程序出现了一点小问题,无法翻译'
class Tencent():
def __init__(self):
self.api_url = 'https://fanyi.qq.com/api/translate'
self.headers = {
'Cookie': 'fy_guid=605ead81-f210-47eb-bd80-ac6ae5e7a2d8; '
'qtv=ed286a053ae88763; '
'qtk=wfMmjh3k/7Sr2xVNg/LtITgPRlnvGWBzP9a4FN0dn9PE7L5jDYiYJnW03MJLRUGHEFNCRhTfrp/V+wUj0dun1KkKNUUmS86A/wGVf6ydzhwboelTOs0hfHuF0ndtSoX+N3486tUMlm62VU4i856mqw==; ',
'Host': 'fanyi.qq.com',
'Origin': 'https://fanyi.qq.com',
'Referer': 'https://fanyi.qq.com/',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, '
'like Gecko) Chrome/73.0.3683.86 Safari/537.36', }
self.fromlang = 'auto'
self.text=''
self.tolang = 'en' # 设置默认为英语
self.sessionUuid = str(int(time.time() * 1000))
self.fy_guid, self.qtv, self.qtk = self.get_qtv_qtk()
self.headers['Cookie'] = self.headers['Cookie'].replace(
'605ead81-f210-47eb-bd80-ac6ae5e7a2d8', self.fy_guid)
self.headers['Cookie'] = self.headers['Cookie'].replace(
'ed286a053ae88763', self.qtv)
self.headers['Cookie'] = self.headers['Cookie'].replace(
'wfMmjh3k/7Sr2xVNg/LtITgPRlnvGWBzP9a4FN0dn9PE7L5jDYiYJnW03MJLRUGHEFNCRhTfrp/V+wUj0dun1KkKNUUmS86A/wGVf6ydzhwboelTOs0hfHuF0ndtSoX+N3486tUMlm62VU4i856mqw==',
self.qtk)
def get_filter(self,text):
if isinstance(text, list):
text = ''.join(text)
text = str(text)
text = text.strip()
filter_list = [
'\r', '\n', '\t', '\u3000', '\xa0', '\u2002',
'<br>', '<br/>', ' ', ' ', ' ', '>>', '"',
'展开全部', ' '
]
for fl in filter_list:
text = text.replace(fl, '')
return text
def get_qtv_qtk(self):
api_url = 'https://fanyi.qq.com/'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, '
'like Gecko) Chrome/73.0.3683.86 Safari/537.36', }
res = requests.get(api_url, headers=headers)
data = res.text
fy_guid = res.cookies.get('fy_guid')
reg = re.compile(r'var qtv = "(.*?)"')
qtv = reg.search(data).group(1)
reg = re.compile(r'var qtk = "(.*?)"')
qtk = reg.search(data).group(1)
return fy_guid, qtv, qtk
def getHtml(self,url,headers,data):
try:
html= requests.post(url=url,data= data,headers=headers)
#print(html.text)
datas = html.json()['translate']['records']
if html!=None and datas != None :
# 以文本的形式打印结果
trans_result = ''.join([data['targetText'] for data in datas])
return trans_result
except Exception:
return None
def translate(self,text):
data = {
'source': self.fromlang,
'target': self.tolang,
'sourceText': text,
'qtv': self.qtv,
'qtk': self.qtk,
'sessionUuid': self.sessionUuid, }
try:
result = self.getHtml(self.api_url,self.headers,data)
#print('腾讯翻译结果为:',result)
return result
except:
return '程序出现了一点小问题,无法翻译'
class Translator(QWidget):
def __init__(self, parent=None, **kwargs):
super(Translator, self).__init__(parent)
self.setWindowTitle('翻译软件')
self.setWindowIcon(QIcon('data/icon.jpg'))
self.Label1 = QLabel('原文')
self.Label2 = QLabel('译文')
self.LineEdit1 = QLineEdit()
self.LineEdit2 = QLineEdit()
self.translateButton1 = QPushButton()
self.translateButton2 = QPushButton()
self.translateButton3 = QPushButton()
self.translateButton4 = QPushButton()
self.translateButton5 = QPushButton()
self.translateButton6 = QPushButton()
self.translateButton1.setText('百度翻译')
self.translateButton2.setText('有道翻译')
self.translateButton3.setText('谷歌翻译')
self.translateButton4.setText('词霸翻译')
self.translateButton5.setText('必应翻译')
self.translateButton6.setText('腾讯翻译')
self.grid = QGridLayout()
self.grid.setSpacing(12)
self.grid.addWidget(self.Label1, 1, 0)
self.grid.addWidget(self.Label2, 2, 0)
self.grid.addWidget(self.LineEdit1, 1, 1,1,2)
self.grid.addWidget(self.LineEdit2, 2, 1,1,2)
self.grid.addWidget(self.translateButton1, 3, 0)
self.grid.addWidget(self.translateButton2, 3, 1)
self.grid.addWidget(self.translateButton3, 3, 2)
self.grid.addWidget(self.translateButton4, 4, 0)
self.grid.addWidget(self.translateButton5, 4, 1)
self.grid.addWidget(self.translateButton6, 4, 2)
self.setLayout(self.grid)
self.resize(400, 150)
self.translateButton1.clicked.connect(lambda : self.translate(api='baidu'))
self.translateButton2.clicked.connect(lambda : self.translate(api='youdao'))
self.translateButton3.clicked.connect(lambda : self.translate(api='google'))
self.translateButton4.clicked.connect(lambda : self.translate(api='Ciba'))
self.translateButton5.clicked.connect(lambda : self.translate(api='bing'))
self.translateButton6.clicked.connect(lambda : self.translate(api='tencent'))
def translate(self, api='baidu'):
content = self.LineEdit1.text()
lan,tolan = language(content)
if not content:
return
if api == 'baidu':
results = Baidu().translate(content,lan,tolan)
elif api == 'youdao':
results = Youdao().translate(content,lan,tolan)
elif api == 'google':
results = Google().translate(content,lan,tolan)
elif api == 'Ciba':
results = Ciba(content,lan,tolan).translate()
elif api == 'bing':
results = Bing().translate(content,lan,tolan)
elif api =='tencent':
results = Tencent().translate(content)
self.LineEdit2.setText(results)
if __name__ == "__main__":
app = QApplication(sys.argv)
QApplication.processEvents()
demo = Translator()
demo.show()
sys.exit(app.exec_())
然后在cmd输入pyinstaller -F -w translate.py
即可打包得到一个多接口翻译软件
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗