有道翻译爬虫
第一步
打开F12, 在页面输入中国 ,然后再开发者工具栏中能看到请求 https://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule
发现是post提交,提交的数据如下
i: 中国
from: AUTO
to: AUTO
smartresult: dict
client: fanyideskweb
salt: 16339419312839
sign: 226d9b242f13e080fc126245875e67dd
lts: 1633941931283
bv: 1f721d7acc6608671b3f5e65c61d232e
doctype: json
version: 2.1
keyfrom: fanyi.web
action: FY_BY_REALTlME
其中salt sign lts bv这四个参数是需要解密的,salt和lts很相似,lts是13位的时间戳,而salt则比lts多一位
第二步
按ctrl+shift+f,分别查找这四个参数,先查找sign,根据sign的长度,初步判断是md5加密,我们再查询结果中找到md5相关的sign计算方法,找到了如下代码
define("newweb/common/service", ["./utils", "./md5", "./jquery-1.7"], function(e, t) {
var n = e("./jquery-1.7");
e("./utils");
e("./md5");
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 + "Y2FYu%TNSbMCxc3t2u^XT")
}
};
我们可以看到sign这个值是md5加密得来的,加密参数除了2个常量以外,还有e和i两个变量,而变量i的值里面包含了变量r,所以我们需要再这几个地方打上断点
然后重新翻译一个文本,它会再断点处停下,我们往下执行发现参数e就是我们要翻译的文本,变量r是当前时间的13位时间戳,变量i是拼接变量r及一个从1到9里面随机的一个数字,然后我们对"fanyideskweb" + e + i + "Y2FYu%TNSbMCxc3t2u^XT" 进行md5计算,得出sign值,同时我们也得到了lts(ts),bv,salt,sign的值,其中bv的值是对user-agent进行加密的,
下来我们用python代码实现
第三步
import requests
import time
import random
import hashlib
def get_sign(word, timesss):
temp = f"fanyideskweb{word}{timesss}Y2FYu%TNSbMCxc3t2u^XT"
m = hashlib.md5()
m.update(temp.encode())
sign = m.hexdigest()
return sign
def get_bv():
temp = "5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36 Edg/94.0.992.31"
m = hashlib.md5()
m.update(temp.encode())
bv = m.hexdigest()
return bv
session = requests.session()
header = {
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36 Edg/94.0.992.31",
'Host': 'fanyi.youdao.com',
'Origin': 'http://fanyi.youdao.com',
'Referer': 'http://fanyi.youdao.com/',
}
api_url = "https://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule"
word = "中国"
salt = int(time.time() * 1000)
lts = str(salt * 10 + random.randint(0, 10))
sign = get_sign(word, times)
data = {
"i": word,
"from": "AUTO",
"to": "AUTO",
"smartresult": "dict",
"client": "fanyideskweb",
"salt": salt,
"sign": sign,
"lts": lts,
"bv": get_bv(),
"doctype": "json",
"version": "2.1",
"keyfrom": "fanyi.web",
"action": "FY_BY_REALTlME",
}
print(data)
response = session.post(url=api_url, data=data, headers=header)
print(response.text)