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

项目目标

对网易有道翻译接口关键参数进行分析,并且进行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": "[email protected]; 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": "[email protected]; 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":"[email protected]; 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
群名:人生苦短,我学编程
欢迎大家加入我们,一起交流技术!!!

发布了38 篇原创文章 · 获赞 128 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/lujiangyang123/article/details/104391784