破解有道字典js
1.有道字典网页端url http://fanyi.youdao.com/?keyfrom=dict2.top
2.页面分析
1).先输入chinesse,按下f12查看XHR
2).能看到网页通过ajax通过post提交数据。
3).接口地址是 http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule
4).表单提交的数据查看(salt,sign等这些看起来像时间戳,但实际上不是的)
5).通过用requests库去爬取。
import requests
# 有道字典在线翻译网址 http://fanyi.youdao.com/?keyfrom=dict2.top
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36",
"Referer": "http://cidian.youdao.com/",
"Cookie": "OUTFOX_SEARCH_USER_ID=-942983360@10.108.160.100; OUTFOX_SEARCH_USER_ID_NCOO=2057156209.4123971; DICT_UGC=be3af0da19b5c5e6aa4e17bd8d90b28a|; JSESSIONID=abcaMD5Y8OJe-fhVoZoEx; _ntes_nnid=c749c995036c33e71743bdbaea3bcf7b,1613008521170; SESSION_FROM_COOKIE=www.baidu.com; ___rl__test__cookies=1613011128572",
"Host": "fanyi.youdao.com",
"Origin": "http://fanyi.youdao.com"
}
url = "http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule"
data = {
"i": "chinese",
"from": "AUTO",
"to": "AUTO",
"smartresult": "dict",
"client": "fanyideskweb",
"salt": "16130085918032",
"sign": "10c0853dfa1de41654d85cca5262fe47",
"lts": "1613008591803",
"bv": "83d74b8e1539f0a744f2b3faf5bdded6",
"doctype": "json",
"version": "2.1",
"keyfrom": "fanyi.web",
"action": "FY_BY_REALTlME"
}
def main():
resp = requests.post(url, headers=headers, data=data)
print(resp.text)
if __name__ == '__main__':
main()
6).通过结果可知,提交的数据不是这么简单的,我们需要去破解js。
{"errorCode":50}
3.网页右键查看网页源代码,ctrl+f搜索.js,我们会发现有三个js文件。
1).分别对三个js文件去搜索“sign”,你会发现,只有fanyi.min.js能搜索的到,但是这个js文件看起来很累,我们需要对其进行美化,百度搜索js美化,美化之后,就看的很清晰了。
2).美化后的js,去搜索“sign”,有15处,但是只有这一处好像是符合要求的。
3).分析这个函数,我们发现i,from,to等等这些都是我们提交的数据,那就是这个了。
i是翻译的单词,from和to给固定值AUTO,smartresult给固定值dict,client给固定值fanyideskweb。salt,sign,lts,bv等都是需要我们去分析的。
4).在上图红色方框内,有一个函数r = v.generateSaltSign(n),搜索“generateSaltSign”,会发现t.generateSaltSign = r,说明gen函数是通过函数赋值的,r函数就是gen函数。
5).找到r函数
var r = function(e) {
var t = n.md5(navigator.appVersion), //navigator.appVersion代表浏览的版本,可以把navigator.appVersion复制到浏览器console,就能输出结果
r = "" + (new Date).getTime(), //(new Date).getTime()代表毫秒戳,+空字符串相当于强制类型为str类型
i = r + parseInt(10 * Math.random(), 10); //r加上1-10(10进制)之间的随机数
return {
ts: r,
bv: t,
salt: i,
sign: n.md5("fanyideskweb" + e + i + "Tbh5E8=q6U3EXe+&L[4c@")
}
};
分析后可得
i: n,
from: C,
to: S,
smartresult: "dict",
client: E,
salt: r.salt, //str(毫秒戳)+0-10(10进制的)之间的随机数
sign: r.sign, //md5("fanyideskweb" + 要翻译的单词 + salt + "Tbh5E8=q6U3EXe+&L[4c@")
lts: r.ts, //str(毫秒戳)
bv: r.bv, //md5(浏览器版本)
doctype: "json",
version: "2.1",
keyfrom: "fanyi.web",
action: e || "FY_BY_DEFAULT
"
6).python代码
import requests
import time
import random
import hashlib
# 有道字典在线翻译网址 http://fanyi.youdao.com/?keyfrom=dict2.top
def main():
word = str(input("请输入需要翻译的字:"))
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36",
"Referer": "http://cidian.youdao.com/",
"Cookie": "OUTFOX_SEARCH_USER_ID=-942983360@10.108.160.100; OUTFOX_SEARCH_USER_ID_NCOO=2057156209.4123971; DICT_UGC=be3af0da19b5c5e6aa4e17bd8d90b28a|; JSESSIONID=abcaMD5Y8OJe-fhVoZoEx; _ntes_nnid=c749c995036c33e71743bdbaea3bcf7b,1613008521170; SESSION_FROM_COOKIE=www.baidu.com; ___rl__test__cookies=1613011128572",
"Host": "fanyi.youdao.com",
"Origin": "http://fanyi.youdao.com"
}
url = "http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule"
timestamp = str(time.time() * 100)
salt = timestamp + str(random.randint(0, 10))
temp = "fanyideskweb" + word + salt + "Tbh5E8=q6U3EXe+&L[4c@"
# hashlib.md5里面默认是字节类型,但是我们这是字符串类型,必须先转为utf-8
sign = hashlib.md5(temp.encode("utf-8")).hexdigest()
data = {
"i": word,
"from": "AUTO",
"to": "AUTO",
"smartresult": "dict",
"client": "fanyideskweb",
"salt": salt,
"sign": sign,
"lts": timestamp,
"bv": "83d74b8e1539f0a744f2b3faf5bdded6",
"doctype": "json",
"version": "2.1",
"keyfrom": "fanyi.web",
"action": "FY_BY_REALTlME"
}
resp = requests.post(url, headers=headers, data=data)
# print(resp.text)
print(resp.json()["translateResult"][0][0]["tgt"])
if __name__ == '__main__':
main()
仅供参考学习,请勿用于商业用途上。