使用python对在线网易有道翻译接口进行分析及破解js加密

Dior ·
更新时间:2024-09-21
· 727 次阅读

文章目录项目目标温馨提示项目分析分析完毕,进行代码模拟加密过程,代码演示 项目目标

对网易有道翻译接口关键参数进行分析,并且进行js加密破解,实质上就是找出网易有道翻译接口对关键参数的加密的详细过程,进行一个模拟加密的过程

温馨提示

这样有什么好处呢,可以再自己网站中使用该接口,进行翻译,意味着你自己也可以搭建一个翻译网站。然而接口却用别人的,这是很不道德的,哈哈,反正笔者内心过不去这个坎,并且如果将你的网站放到服务器上,可能带来法律风险。

项目分析

1.打开谷歌游览器,输入网址:有道翻译
2.键盘按F12进入开发者调试模式,点击Network,选择XHR也就是js发起的异步加载请求获取的网页数据。在本案例中,当你输入python,就会发起异步请求,请求翻译的内容,我们就去找到这个异步请求的并且是翻译内容的文件。
在这里插入图片描述
3.如上图所示,我们找到了这个文件,那么我们看一下,这个异步请求的文件的url,以及请求需要的参数
在这里插入图片描述
如上图红色箭头这是url
在这里插入图片描述
如上图红色框框这是请求头
在这里插入图片描述
如上图红色箭头这是请求参数
4.我们写代码,模拟游览器发起异步请求需要url,请求头,请求参数,这里需要注意看清楚是post请求,还是get请求
代码示例

import requests data = { "i": "python", "from": "AUTO", "to": "AUTO", "smartresult": "dict", "client": "fanyideskweb", "salt": "15820940749399", "sign": "45994e3946b32fea4d9a53065ca6c622", "ts": "1582094074939", "bv": "7bcd9ea3ff9b319782c2a557acee9179", "doctype": "json", "version": "2.1", "keyfrom": "fanyi.web", "action": "FY_BY_REALTlME", } headers = { "Accept": "application/json, text/javascript, */*; q=0.01", "Accept-Encoding": "gzip, deflate", "Accept-Language": "zh-CN,zh;q=0.9", "Connection": "keep-alive", "Content-Length": "239", "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "Cookie": "OUTFOX_SEARCH_USER_ID=1943732077@10.169.0.83; OUTFOX_SEARCH_USER_ID_NCOO=1722240595.3583963; _ntes_nnid=748be7ae4227014517b57740c8415702,1582012592236; JSESSIONID=aaaGbBuv_q8yldGK66Bbx; ___rl__test__cookies=1582094074926", "Host": "fanyi.youdao.com", "Origin": "http://fanyi.youdao.com", "Referer": "http://fanyi.youdao.com/", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36", "X-Requested-With": "XMLHttpRequest", } # 初始url base_url = "http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule" # 进行模拟post请求 response = requests.post(base_url, data=data, headers=headers) # 转换为json格式 json_data = response.json() print(json_data) ''' 运行结果: {'translateResult': [[{'tgt': 'python', 'src': 'python'}]], 'errorCode': 0, 'type': 'en2zh-CHS', 'smartResult': {'entries': ['', 'n. 巨蟒;大蟒\r\n', 'n. (法)皮东(人名)\r\n'], 'type': 1}} '''

5.获取成功,但是我们来试着将一些参数去掉,看哪些参数有用,哪些参数没用,参数有用的去掉了就会报错,这个就可以用来判断的依据。
代码示例:

import requests data = { "i": "python", # "from": "AUTO", # "to": "AUTO", # "smartresult": "dict", "client": "fanyideskweb", "salt": "15820940749399", "sign": "45994e3946b32fea4d9a53065ca6c622", # "ts": "1582094074939", # "bv": "7bcd9ea3ff9b319782c2a557acee9179", # "doctype": "json", # "version": "2.1", "keyfrom": "fanyi.web", # "action": "FY_BY_REALTlME", } headers = { # "Accept": "application/json, text/javascript, */*; q=0.01", # "Accept-Encoding": "gzip, deflate", # "Accept-Language": "zh-CN,zh;q=0.9", # "Connection": "keep-alive", # "Content-Length": "239", # "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "Cookie": "OUTFOX_SEARCH_USER_ID=1943732077@10.169.0.83; OUTFOX_SEARCH_USER_ID_NCOO=1722240595.3583963; _ntes_nnid=748be7ae4227014517b57740c8415702,1582012592236; JSESSIONID=aaaGbBuv_q8yldGK66Bbx; ___rl__test__cookies=1582094074926", # "Host": "fanyi.youdao.com", # "Origin": "http://fanyi.youdao.com", "Referer": "http://fanyi.youdao.com/", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36", # "X-Requested-With": "XMLHttpRequest", } # 初始url base_url = "http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule" # 进行模拟post请求 response = requests.post(base_url, data=data, headers=headers) # 转换为json格式 json_data = response.json() print(json_data) ''' {'translateResult': [[{'tgt': 'python', 'src': 'python'}]], 'errorCode': 0, 'type': 'en2zh-CHS', 'smartResult': {'entries': ['', 'n. 巨蟒;大蟒\r\n', 'n. (法)皮东(人名)\r\n'], 'type': 1}} '''

6.对上述所有参数进行分析:
经过一番折腾发现上面的参数是必要参数,否则得不到想要的结果输出:{“errorCode”:50}或者关键参数不足会报错

{"errorCode":50}

7.经过多次尝试我们可以发现"salt",“sign”,以及“i”是可变参数,并且"i"是要查询的词,那么就剩"salt"跟"sign"了,
提示:如果读者复制我上面这个代码会输出如下语句,这是因为"salt","sign"这两个参数是加密的参数,是网页脚本js生成的。
那么现在我们就来找找这个叫"salt"的参数:

在这里插入图片描述
8.如上图所示,将这个参数放到搜索栏中去搜索,即可找到这个文件叫fanyi.min.js中有这个参数,可以看到这是个js文件,于是我们的猜想是正确的,参数被这个js文件加密了,于是我们打开他。
在这里插入图片描述
9.如上图Response中的数据,我们复制到格式格式化的在线网站上,进行js格式化
在这里插入图片描述
10.如上图,我们格式化成功,将格式化后的代码放到pycharm中去,通过Ctri+f进行代码的查找,找出如何生成,这个参数,搜到有用的代码如下

o = r.generateSaltSign(t); data: { i: e.i, client: e.client, salt: o.salt, sign: o.sign, ts: o.ts, bv: o.bv, tgt: e.tgt, from: e.from, to: e.to, doctype: "json", version: "3.0", cache: !0 } r = "" + (new Date).getTime(), i = r + parseInt(10 * Math.random(), 10); return { ts: r, bv: t, salt: i, sign: n.md5("fanyideskweb" + e + i + "n%A-rKaT5fb[Gy?;N5@Tj") } i = r(t); data: { i: e.i, client: "fanyideskweb", salt: i.salt, sign: i.sign, ts: i.ts, bv: i.bv, tgt: e.tgt, modifiedTgt: e.modifiedTgt, from: e.from, to: e.to } r = v.generateSaltSign(n) { i: n, from: S, to: E, smartresult: "dict", client: k, salt: r.salt, sign: r.sign, ts: r.ts, bv: r.bv, doctype: "json", version: "2.1", keyfrom: "fanyi.web", action: e || "FY_BY_DEFAULT" }

11.根据这些线索我们可以将上述连立起来
salt参数的获取:
因为i=r + parseInt(10 * Math.random(), 10)由于r="" + (new Date).getTime(),所以i就等于
“” + (new Date).getTime()+parseInt(10 * Math.random(), 10)

sign=o.sign=i=r + parseInt(10 * Math.random(), 10) "" + (new Date).getTime()+parseInt(10 * Math.random(), 10)

那这个(new Date).getTime()这个是什么呢?
在这里插入图片描述
如图下图所示,在游览器控制台输入这个(new Date).getTime()发现这好像是一个时间戳,我们就去验证一下
在这里插入图片描述
总结:如上图所示我们成功了,那这个这个(new Date).getTime()就是时间戳
那么还剩下一个我们再去控制台测试一下

在这里插入图片描述
总结:多测试几次发现parseInt(10 * Math.random(), 10)是一个10以内的随机数
13.sign参数的获取:

sign=o.sign=n.md5("fanyideskweb" + e + i + "n%A-rKaT5fb[Gy?;N5@Tj")

我们可以使用谷歌里的js进行调试,首先,根据fanyi.min.js文件的url在Sources中查找sign: n.md5(“fanyideskweb” + e + i + “Nw(nmmbP%A-r6U3EUn]Aj”)这一行,如下图所示
在这里插入图片描述
如下图所示,我们再进行设置断点进行debug调试,黑色的箭头是设置的断点,于是又在网页要翻译的内容的地方又重新输入了python进行翻译,我们可以点击下图黄色框框中的最后一个按钮,进行debug调试,当运行到与代码中红色框框中的下一行,我们可以发现,黑色箭头指向的python与e的值相等,都等于python。这就推出了e这个参数
在这里插入图片描述
总结:e在代码中通过调试发现这是需要翻译的内容,并且i就是salt,将括号里面的所有参数及字符串加在一起,进行md5加密就能得到sign参数

分析完毕,进行代码模拟加密过程,代码演示

代码示例

import requests,random,time import hashlib def md5(value): #创建md加密对象 md5_obj=hashlib.md5() #加密字符串 md5_obj.update(bytes(value,encoding="utf-8")) #进行16位加密 sign=md5_obj.hexdigest() return sign def youdao(kw): #目标url base_url="http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule" #生成salt salt=str(int(time.time()*1000)) +str(random.randint(0,9)) #生成sign sign=md5('fanyideskweb'+kw+salt+"n%A-rKaT5fb[Gy?;N5@Tj") data={ "i":kw, # "from":"AUTO", # "to":"AUTO", # "smartresult":"dict", "client":"fanyideskweb", "salt":salt, "sign":sign, # "ts":"1581937772025", # "bv":"7bcd9ea3ff9b319782c2a557acee9179", # "doctype":"json", # "version":"2.1", "keyfrom":"fanyi.web", # "action":"FY_BY_REALTlME", } headers={ # "Accept":"application/json, text/javascript, */*; q=0.01", # "Accept-Encoding":"gzip, deflate", # "Accept-Language":"zh-CN,zh;q=0.9", # "Connection":"keep-alive", # "Content-Length":"239", # "Content-Type":"application/x-www-form-urlencoded; charset=UTF-8", "Cookie":"OUTFOX_SEARCH_USER_ID=1943732077@10.169.0.83; JSESSIONID=aaaPMpcGOu58rahSSJsbx; OUTFOX_SEARCH_USER_ID_NCOO=1722240595.3583963; ___rl__test__cookies=1581937772017", # "Host":"fanyi.youdao.com", # "Origin":"http://fanyi.youdao.com", "Referer":"http://fanyi.youdao.com/", "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36", # "X-Requested-With":"XMLHttpRequest", } #发起请求 response=requests.post(base_url,data=data,headers=headers) #获取数据 json_data=response.json() data_list=json_data["smartResult"]["entries"] print(data_list) if __name__ == '__main__': kw=input("你要查询的单词") youdao(kw)

控制台输入guess单词,运行结果:

''' ['', 'n. 猜测;推测\r\n', 'vi. 猜;推测;猜中\r\n', 'vt. 猜测;认为;推测;猜中\r\n'] '''

这里就大功告成了,成功破解网易有道接口部分参数js加密

提示一下:
这里的cookie需要你自己在线网易有道词典网页的cookie

来一波,推送吧!
群号:781121386
群名:人生苦短,我学编程
欢迎大家加入我们,一起交流技术!!!


作者:No later



用python 有道 网易 js 接口 Python

需要 登录 后方可回复, 如果你还没有账号请 注册新账号