最近在備考四六級,很多單詞不會,每次都要開啟翻譯軟體就很不方便,就想了一下自己是不是可以用python寫一個翻譯軟體, 查閱了一些資料後, 最後我選擇了有道翻譯的介面,作為本次翻譯網址目標介面,介面選擇了Tkinter作為基礎,最後用python搭建了一個翻譯軟體,本篇文章就是關於這個翻譯軟體的製作教學,喜歡的可以支援一下!
效果圖:
你會收穫百分之八十的js破解,收穫引數的加密方式,收穫Tkinter的基本控制元件操作,收穫python的模組用法,當你看完這篇文章之後!
翻譯小軟體:
-
-
設計思路:
-
js破解:
-
GUI設計:
-
程式碼模組:
-
關於GUI程式碼:
-
關於Js程式碼部分:
-
全部程式碼:
設計思路:
js破解
GUI設計
程式
表單資料
軟體雛形
最終效果
js破解:
首先我們開啟有道網頁:
試著輸入簡單 根據NetWork中,我們檢視這個XHR會發現有一些介面網址
類似這樣的一個POST請求方式,
在響應中,我們可以根據json包就能檢視到翻譯後的結果, 這個將會用來我們解析資料中用到, 在看一張圖:
介面沒有變化, 點選標頭, 游標移到最後,有表單資料,英文應該是data forms, 這裡有一些需要提交的資料,在我們向伺服器後臺傳送一個POST請求的時候,是必須要攜帶的資料, 但是這些資料有些是不會變的, 有些是會變化的, 只需要根據二個不同的介面,對比一下就知道了, 在這裡,我對比之後, 發現有4個引數是會變化的, 如下:
"salt": "15975022964104",
"sign": "7b7db70e0d1a786a43a6905c0daec508",
"lts": "1597502296410",
"bv": "9ef72dd6d1b2c04a72be6b706029503a",1234
所以我們就要知道 這4個引數 是如何生成的, 以及如何加密的, 這裡就需要利用到瀏覽器的DEBUG功能, 比如第一個引數 salt 找一找這個是怎麼來的, 步驟如下:
點選連線 就可以在上面看到 如箭頭 最後點選方框內符號
跳轉之後如下: 這裡需要細心一點, 觀察是否salt 這些引數是否出現了 出現了 就停下來仔細看
然後把游標放到這個函式 ,會立即高亮,顯示一個連結, 點選這個連結,就可以直接跳轉到這個函式,
函式如下:
var r = function(e) {
var t = n.md5(navigator.appVersion)
, r = "" + (new Date).getTime()
, i = r + parseInt(10 * Math.random(), 10);
return {
ts: r,
bv: t,
salt: i,
sign: n.md5("fanyideskweb" + e + i + "]BjuETDhU)zqSxf-=B#7m")
}
};1234567891011
根據這個函式,我們就可以找到引數是如何構造的,具體怎麼構造,下面細講.
GUI設計:
GUI還是用簡單的Tkinter進行設計, 簡單粗暴, 關於輸入的異常,做出了空值的判斷,如下:
然後就是基本的控制元件設定: 這個在程式碼模組中講
你會收穫百分之八十的js破解,收穫引數的加密方式,收穫Tkinter的基本控制元件操作,收穫python的模組用法,當你看完這篇文章之後!
讀後有收穫,點贊,關注,加收藏,共勉!
點我,點我,點我呀!博主其他文章
程式碼模組:
關於GUI程式碼:
用於生成一個GUI介面, 新增一些基本控制元件的操作顯示。
基本程式碼:
def __tkinter(self):
"""using the tkinter get a GUI model """
self.window = Tk() # 生成主題空間
self.window.title("自制有道翻譯小工具")
# 設定基本引數
width = 800
height = 400
# 獲取螢幕尺寸以計算佈局引數,讓視窗位於螢幕中央
screenwidth = self.window.winfo_screenwidth()
screenheight = self.window.winfo_screenheight()
align_str = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)
self.window.geometry(align_str) # 設定視窗大小
# 設定視窗是否可變長、寬,True:可變,False:不可變
self.window.resizable(width=True, height=True)
# 設定一些基本控制元件
self.name = Label(self.window, text="Try to translate !", bg="wheat", fg="black", font=("宋體", 50))
self.name.place(relx=0.15, rely=0.15)
# 下滑線
self.hr = Label(self.window, text=self.GetHr(width=width))
self.hr.place(rely=0.37)
# Help Tip
help_s = "(程式支援中文和英語的轉換 - 請在左邊輸入待翻譯語句 - 按下按鈕後 - 右邊則會顯示翻譯結果)"
self.Tip = Label(self.window, text=help_s, font=('宋體', 12), fg='Tan')
self.Tip.place(rely=0.05)
# InputTextStream
self.InputTextStream = Text(self.window, bg="Pink", font=('宋體', 15))
self.InputTextStream.place(relwidth=0.4, rely=0.4, relheight=0.5)
# OutPutTextStream
self.OutPutTextStream = Text(self.window, bg="Tan", font=('宋體', 15))
self.OutPutTextStream.place(relx=0.6, relwidth=0.4, rely=0.4, relheight=0.5)
# Translate Button
self.Translate = Button(self.window, text="翻譯",
command=lambda: self.start(InputStream=self.InputTextStream.get(1.0, END)))
self.Translate.place(relx=0.42, rely=0.55)
# Exit Button
self.exit = Button(self.window, text="退出", command=self.window.destroy)
self.exit.place(relx=0.52, rely=0.55)
# clean the InputText
self.clean_input = Button(self.window, text="清左", command=lambda: self.clean_all(self.InputTextStream))
self.clean_input.place(relx=0.42, rely=0.7)
# clean the OutputText
self.clean_ouput = Button(self.window, text="清右", command=lambda: self.clean_all(self.OutPutTextStream))
self.clean_ouput.place(relx=0.52, rely=0.7)
self.window.mainloop()1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
異常處理:
def get_messageBox(self, Tips):
"""
params : Tips from other function to using the messageBox
function Used to handle warnings for exceptions
return: the boolean function if using click the yes button return True else return False
"""
tkinter.messagebox.showinfo("提示", Tips)12345678
輸出設定:
def print_OutPut(self, OutPut_i):
"""print the translate on the OutPutText"""
self.OutPutTextStream.delete(1.0, END)
# Line_max = 20
# lens = len(OutPut_i) // Line_max
self.OutPutTextStream.insert(END, OutPut_i)1234567
清空設定:
def clean_all(self, one_text):
one_text.delete(1.0, END)
self.get_messageBox("刪除成功!")1234
關於Js程式碼部分:
用於引數的解密, 表單資料的提交, 關於json的解析。以及tkinter與模組之間的聯絡:
基礎設定:
def __init__(self):
"""
as params: ua is browser user-agent but i like using my function in other package
Cookies of headers maybe abate because time limit
others of headers you should copy the network
"""
self.ua = GetUserAgentCS().get_user()
self.url = ''
self.headers = {
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Accept-Encoding': "gzip, deflate",
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
'Connection': 'keep-alive',
'Content-Type': "application/x-www-form-urlencoded; charset=UTF-8",
'Cookie': 'OUTFOX_SEARCH_USER_ID=1989505748@10.108.160.19; OUTFOX_SEARCH_USER_ID_NCOO=1338955488.841036; DICT_UGC=be3af0da19b5c5e6aa4e17bd8d90b28a|; JSESSIONID=abcwjDskhc0wMbAIKxDrx; ___rl__test__cookies=1599399356674',
'Host': "fanyi.youdao.com",
'Origin': '
"Referer": "
'User-Agent': self.ua,
'X-Requested-With': 'XMLHttpRequest'
}
self.__tkinter()123456789101112131415161718192021222324
js的獲取:
def getJSParams(self, Input_i):
"""
var r = function(e) {
var t = n.md5(navigator.appVersion)
, r = "" + (new Date).getTime()
, i = r + parseInt(10 * Math.random(), 10);
return {
ts: r,
bv: t,
salt: i,
sign: n.md5("fanyideskweb" + e + i + "]BjuETDhU)zqSxf-=B#7m")
}
};
這是後臺關於 一些引數 的加密函式
用python去實現這段js程式碼就可以了
"""
t = md5()
t.update(self.ua.encode("utf8")) # 構造bv引數
r = int(time.time() * 1000) # 構造時間引數r
i = str(r) + str(random.randint(0, 9)) # 構造salt引數r
sign_t = md5()
sign_t.update(("fanyideskweb" + Input_i + i + ']BjuETDhU)zqSxf-=B#7m').encode("utf8")) # 構造sign引數
return {'ts': str(r), 'bv': t.hexdigest(), 'salt': i, "sign": sign_t.hexdigest()}12345678910111213141516171819202122232425262728
表單資料的構造:
def __params(self, item, Input_i):
"""這些引數一定要自己複製的"""
self.params = {
'i': Input_i,
'from': 'AUTO',
'to': 'AUTO',
'smartresult': 'dict',
'client': 'fanyideskweb',
'salt': item.get('salt'),
'sign': item.get('sign'),
'lts': item.get('ts'),
'bv': item.get('bv'),
'doctype': 'json',
'version': '2.1',
'keyfrom': 'fanyi.web',
'action': 'FY_BY_REALTlME'
}12345678910111213141516171819
傳送請求提交資料:
def start(self, InputStream):
"""
Params : InputStream from the Text
"""
if len(InputStream) == 1:
# 判斷輸入為空
self.get_messageBox("你好像還沒有輸入要翻譯的話噢!")
else:
Js_item = self.getJSParams(InputStream.strip())
self.__params(Js_item, InputStream.strip())
# 更改翻譯內容
r = requests.post(self.url, headers=self.headers, params=self.params)
time.sleep(0.7)
if r.status_code == 200:
OutPUt_i = r.json().get('translateResult')[0][0].get('tgt')
print(OutPUt_i)
self.print_OutPut(OutPUt_i)
else:
self.get_messageBox("伺服器繁忙, 請稍後再試!")1234567891011121314151617181920
本篇文章: 關於js解密思路源於: https://blog.csdn.net/llllllkkkkkooooo/article/details/108030148
鳴謝!
你會收穫百分之八十的js破解,收穫引數的加密方式,收穫Tkinter的基本控制元件操作,收穫python的模組用法,當你看完這篇文章之後!
讀後有收穫,點贊,關注,加收藏,共勉!
點我,點我,點我呀!博主其他文章
全部程式碼:
# -*- coding : utf-8 -*-# @Time : 2020/9/2 16:32# @author : 沙漏在下雨# @Software : PyCharm# @CSDN : https://me.csdn.net/qq_45906219import requestsfrom get_useragent import GetUserAgentCSfrom hashlib import md5import timeimport randomimport tkinter.messageboxfrom tkinter import *class makeTranslate():
"""
url:
破解有道翻譯js程式碼
製作一個自動翻譯器 附帶GUI介面
最後將其打包一個小的桌面程式
"""
def __init__(self):
"""
as params: ua is browser user-agent but i like using my function in other package
Cookies of headers maybe abate because time limit
others of headers you should copy the network
"""
self.ua = GetUserAgentCS().get_user()
self.url = ''
self.headers = {
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Accept-Encoding': "gzip, deflate",
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
'Connection': 'keep-alive',
'Content-Type': "application/x-www-form-urlencoded; charset=UTF-8",
'Cookie': 'OUTFOX_SEARCH_USER_ID=1989505748@10.108.160.19; OUTFOX_SEARCH_USER_ID_NCOO=1338955488.841036; DICT_UGC=be3af0da19b5c5e6aa4e17bd8d90b28a|; JSESSIONID=abcwjDskhc0wMbAIKxDrx; ___rl__test__cookies=1599399356674',
'Host': "fanyi.youdao.com",
'Origin': '
"Referer": "
'User-Agent': self.ua,
'X-Requested-With': 'XMLHttpRequest'
}
self.__tkinter()
@staticmethod
def GetHr(width):
"""
return a long size line enough
"""
Max_Line = width return Max_Line * "-"
def __tkinter(self):
"""using the tkinter get a GUI model """
self.window = Tk() # 生成主題空間
self.window.title("自制有道翻譯小工具")
# 設定基本引數
width = 800
height = 400
# 獲取螢幕尺寸以計算佈局引數,讓視窗位於螢幕中央
screenwidth = self.window.winfo_screenwidth()
screenheight = self.window.winfo_screenheight()
align_str = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)
self.window.geometry(align_str) # 設定視窗大小
# 設定視窗是否可變長、寬,True:可變,False:不可變
self.window.resizable(width=True, height=True)
# 設定一些基本控制元件
self.name = Label(self.window, text="Try to translate !", bg="wheat", fg="black", font=("宋體", 50))
self.name.place(relx=0.15, rely=0.15)
# 下滑線
self.hr = Label(self.window, text=self.GetHr(width=width))
self.hr.place(rely=0.37)
# Help Tip
help_s = "(程式支援中文和英語的轉換 - 請在左邊輸入待翻譯語句 - 按下按鈕後 - 右邊則會顯示翻譯結果)"
self.Tip = Label(self.window, text=help_s, font=('宋體', 12), fg='Tan')
self.Tip.place(rely=0.05)
# InputTextStream
self.InputTextStream = Text(self.window, bg="Pink", font=('宋體', 15))
self.InputTextStream.place(relwidth=0.4, rely=0.4, relheight=0.5)
# OutPutTextStream
self.OutPutTextStream = Text(self.window, bg="Tan", font=('宋體', 15))
self.OutPutTextStream.place(relx=0.6, relwidth=0.4, rely=0.4, relheight=0.5)
# Translate Button
self.Translate = Button(self.window, text="翻譯",
command=lambda: self.start(InputStream=self.InputTextStream.get(1.0, END)))
self.Translate.place(relx=0.42, rely=0.55)
# Exit Button
self.exit = Button(self.window, text="退出", command=self.window.destroy)
self.exit.place(relx=0.52, rely=0.55)
# clean the InputText
self.clean_input = Button(self.window, text="清左", command=lambda: self.clean_all(self.InputTextStream))
self.clean_input.place(relx=0.42, rely=0.7)
# clean the OutputText
self.clean_ouput = Button(self.window, text="清右", command=lambda: self.clean_all(self.OutPutTextStream))
self.clean_ouput.place(relx=0.52, rely=0.7)
self.window.mainloop()
def clean_all(self, one_text):
one_text.delete(1.0, END)
self.get_messageBox("刪除成功!")
def __params(self, item, Input_i):
"""這些引數一定要自己複製的"""
self.params = {
'i': Input_i,
'from': 'AUTO',
'to': 'AUTO',
'smartresult': 'dict',
'client': 'fanyideskweb',
'salt': item.get('salt'),
'sign': item.get('sign'),
'lts': item.get('ts'),
'bv': item.get('bv'),
'doctype': 'json',
'version': '2.1',
'keyfrom': 'fanyi.web',
'action': 'FY_BY_REALTlME'
}
def getJSParams(self, Input_i):
"""
var r = function(e) {
var t = n.md5(navigator.appVersion)
, r = "" + (new Date).getTime()
, i = r + parseInt(10 * Math.random(), 10);
return {
ts: r,
bv: t,
salt: i,
sign: n.md5("fanyideskweb" + e + i + "]BjuETDhU)zqSxf-=B#7m")
}
};
這是後臺關於 一些引數 的加密函式
用python去實現這段js程式碼就可以了
"""
t = md5()
t.update(self.ua.encode("utf8")) # 構造bv引數
r = int(time.time() * 1000) # 構造時間引數r
i = str(r) + str(random.randint(0, 9)) # 構造salt引數r
sign_t = md5()
sign_t.update(("fanyideskweb" + Input_i + i + ']BjuETDhU)zqSxf-=B#7m').encode("utf8")) # 構造sign引數
return {'ts': str(r), 'bv': t.hexdigest(), 'salt': i, "sign": sign_t.hexdigest()}
def get_messageBox(self, Tips):
"""
params : Tips from other function to using the messageBox
function Used to handle warnings for exceptions
return: the boolean function if using click the yes button return True else return False
"""
tkinter.messagebox.showinfo("提示", Tips)
def print_OutPut(self, OutPut_i):
"""print the translate on the OutPutText"""
self.OutPutTextStream.delete(1.0, END)
# Line_max = 20
# lens = len(OutPut_i) // Line_max
self.OutPutTextStream.insert(END, OutPut_i)
def start(self, InputStream):
"""
Params : InputStream from the Text
"""
if len(InputStream) == 1:
# 判斷輸入為空
self.get_messageBox("你好像還沒有輸入要翻譯的話噢!")
else:
Js_item = self.getJSParams(InputStream.strip())
self.__params(Js_item, InputStream.strip())
# 更改翻譯內容
r = requests.post(self.url, headers=self.headers, params=self.params)
time.sleep(0.7)
if r.status_code == 200:
OutPUt_i = r.json().get('translateResult')[0][0].get('tgt')
print(OutPUt_i)
self.print_OutPut(OutPUt_i)
else:
self.get_messageBox("伺服器繁忙, 請稍後再試!")if __name__ == '__main__':
makeTranslate()123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
你會收穫百分之八十的js破解,收穫引數的加密方式,收穫Tkinter的基本控制元件操作,收穫python的模組用法,當你看完這篇文章之後!
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/30239065/viewspace-2722139/,如需轉載,請註明出處,否則將追究法律責任。