首先拿到这个网站, 按照正常的流程, 带上请求的header和Form Data部分, 但是每次response都是errorcode50
在左边翻译框输入一个测试字符串,接下来注意这个请求是由那个js发起的
发现这个js文件fanyi.min.js, 注意min.js这是一个压缩版js文件
右键这个js文件 - Reveal in Sources panel, 会自动跳到Source栏 如下图
每次在翻译框输入一个内容, XHR一栏里都会异步得到一个返回结果,查看这个请求的response里可以得到我们的翻译结果
找到这条请求的header部分,发现每次请求的Form Data的这几个参数都是变化的,js加密也往往是在这个地对传输的数据进行加密
尝试在刚才的fanyi.min.js文件中搜索这几个参数
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 + "n%A-rKaT5fb[Gy?;N5@Tj")
}
};
查看和测试已经大概知道这几个参数的作用了:
ts: 表示当前的时间戳的字符串, 注意js的时间戳和python的时间的有区别, js的时间戳是ms级的, 所以每次用python获得的时间戳都要*1000
bv: 是一个经过md5加密的navigator.appVersion, 在控制台的调试窗口输入navigator.appVersion,发现和User-agent几乎相同, 但是不同
salt: 是字符串ts加上一个随机的范围为[0-9]的整数拼接成的字符串
sign: 也是一个经过md5加密的字符串, e 表示翻译框内输入的内容
我们已经差不多知道原理了, 我们在翻译框内每次输入的内容, 被经过简单js加密发送到服务端验证, 才能得到我们想要的内容
首先把上面比较重要的几个参数通过python代码实现
因为js学的比较浅,转变为python代码调试了很多次.
# 得到当前时间戳
# r = "" + (new Date).getTime()
ts = r = str(int(round(time.time(), 3) * 1000))
print(ts)
# 时间戳和0-10按照字符串拼接
# salt = i = r + parseInt(10 * Math.random(), 10)
i = r + str(random.randint(0, 9))
salt = int(i)
print(salt)
# bv = t = n.md5(navigator.appVersion)
# app_version = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36"
app_version = "5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36"
bv = hashlib.md5(app_version.encode(encoding="utf-8")).hexdigest()
print(bv)
# 得到sign值
# sign: n.md5("fanyideskweb" + e + i + "n%A-rKaT5fb[Gy?;N5@Tj")
sign = hashlib.md5(("fanyideskweb" + "翻译" + i + "n%A-rKaT5fb[Gy?;N5@Tj").encode(encoding="utf-8")).hexdigest()
print(sign)
最后拼接data和header部分,然后通过requests.post方法拿到返回值,得到的想要的结果
import time
import random
import hashlib
import requests
class YouDao:
def __init__(self, url):
self.url = url
def get_data(self, content):
# 得到当前时间戳
# r = "" + (new Date).getTime()
ts = r = str(int(round(time.time(), 3) * 1000))
print(ts)
# 时间戳和0-10按照字符串拼接
# salt = i = r + parseInt(10 * Math.random(), 10)
i = r + str(random.randint(0, 9))
salt = int(i)
print(salt)
# bv = t = n.md5(navigator.appVersion)
# app_version = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36"
app_version = "5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36"
bv = hashlib.md5(app_version.encode(encoding="utf-8")).hexdigest()
print(bv)
# 得到sign值
# sign: n.md5("fanyideskweb" + e + i + "n%A-rKaT5fb[Gy?;N5@Tj")
sign = hashlib.md5(("fanyideskweb" + content + i + "n%A-rKaT5fb[Gy?;N5@Tj").encode(encoding="utf-8")).hexdigest()
print(sign)
data = {
'i': content,
'from': "AUTO",
'to': "AUTO",
'smartresult': "dict",
'client': "fanyideskweb",
'salt': salt,
'sign': sign,
'ts': ts,
'bv': bv,
'doctype': "json",
'version': "2.1",
'keyfrom': "fanyi.web",
'action': "FY_BY_REALTlME",
'cache-control': "no-cache",
'typoResult': 'false'
}
headers = {
"Cookie": 'OUTFOX_SEARCH_USER_ID_NCOO=152157970.25320017; OUTFOX_SEARCH_USER_ID="[email protected]"; _ga=GA1.2.2012357562.1553937054; _ntes_nnid=6497242c22b4e2ef0d2f403b1c6b7bf2,1560146318693; JSESSIONID=aaarX_cgU_By9_aKjPkXw; ___rl__test__cookies={}'.format(ts),
'Accept': "application/json, text/javascript, */*; q=0.01",
'Origin': "http://fanyi.youdao.com",
'User-Agent': "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36",
'Referer': "http://fanyi.youdao.com/",
'X-Requested-With': "XMLHttpRequest"
}
return data, headers
def translate(self, content):
data, headers = self.get_data(content)
response = requests.post(self.url, data=data, headers=headers)
print(response.text)
if __name__ == "__main__":
url = "http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule"
instance = YouDao(url)
instance.translate("good")
该文章主要提供交流学习使用,请勿利用其进行不当行为。
爬虫刚入门,有不对的地方欢迎指正。