0.说明
本篇将详细讲解破解有道翻译接口。
如上图所示,输入hello到左方,右方将显示对应的翻译结果。我们将这一部分的功能用Python实现。
1.分析请求
- 打开Chrome,进入有道翻译页面。
- 在有道翻译页面下按F12按钮,打开开发者工具栏。点击Network按钮,再点击XHR按钮。
- 在有道翻译左方中输入he,在浏览器开发者窗口中可以看到异步加载数据的请求。
- 点击对应的请求查看请求的详细信息。点击详细信息中的Preview查看请求返回的详细信息。如下图所示:
- 通过步骤3后可以看到数据请求是通过http中的post请求获取数据的。但是在post表单数据中存在加密的参数,如图所示:
- 我们可以通过解析JavaScript代码,然后通过Python实现相应的算法获取数据,下面分析JavaScript代码。
根据图片依次点击查找代码,定位JavaScript发起请求的位置。
在搜索栏中输入sign,然后输入回车开始全局查找。点击相应的查找结果跳转到相应的文件
点击Pretty print按钮将压缩后的JavaScript代码格式化显示,方便阅读。
在文件中查找sign,会有很多结果,依次查看,阅读分析代码。
可以给看到与前面Post请求表单中结构一致的数据。
就是此处发起了获取翻译结果的Post请求。我们分析各个参数通过Python模拟就可以实现访问该接口。
通过分析发现加密参数都是通过r对象获取的,r是通过r = g.generateSaltSign(n);这句代码生成的。
我们查找generateSaltSign,可以发现
然后在改行上面一点的地方有定义r函数,
这里就是有道加密参数生成的地方。
navigator.appVersion:可返回浏览器的平台和版本信息。该属性是一个只读的字符串。
getTime():获取时间
parseInt(10 * Math.random(), 10):生成一个随机数
md5():计算字符串的md5值
到此处就分析完毕前端加密参数的生成,我们只需要在Python代码中把相应的加密添加进去。
2.编写代码
#!/usr/bin/env python
#-*- coding:utf8 -*-
# Author:Taoke
# @Time:2019/2/24 14:17
import random
import requests
import time
import hashlib
import json
def translate(endlish):
url = 'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'
headers = {'Host': 'fanyi.youdao.com',
'Accept': 'application/json, text/javascript, */*; q=0.01',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36',
'Referer': 'http://fanyi.youdao.com/',
'Accept-Encoding': 'deflate', }
formdata = {
'i':endlish,
'from':'AUTO',
'to':'AUTO',
'smartresult':'dict',
'client':'fanyideskweb',
'salt':'15316181854457',
'sign':'0 acd4f34bbb7de68ee2aec865a6b6297',
'doctype':'json',
'version':'2.1',
'keyfrom':'fanyi.web' ,
'action':'FY_BY_CLICKBUTTION',
'typoResult':'false',
}
Cookie = { 'OUTFOX_SEARCH_USER_ID':'1483315967@10.169.0.83',
'OUTFOX_SEARCH_USER_ID_NCOO':'140762844.79632822',
'fanyi-ad-id':'46607', 'fanyi-ad-closed':'1',
'JSESSIONID':'aaaJfIzL4g-Ze9BHdOysw',
'___rl__test__cookies':'%s'%str(int(time.time()*1000))}
h = hashlib.md5()
formdata['salt'] = str(int(time.time()*1000))+str((random.randint(0,10)))
s = ("fanyideskweb" + formdata['i'] + formdata['salt'] + "ebSeFb%=XZ%T[KZ)c(sy!").encode('utf-8')
h.update(s)
formdata['sign'] = h.hexdigest()
res = requests.post(url=url,headers=headers,data=formdata,cookies=Cookie).text
jtg = json.loads(res)
return jtg['translateResult'][0][0]['tgt']
if __name__ == "__main__":
'''英翻中'''
t = translate("what's your name?")
print(t)
3.总结
JavaScript解析的基本流程:
- 查看加密参数有哪些
- 在全部文件查找加密参数
- 找到对应请求发起的地方
- 查找加密参数的生成方式
- 将JavaScript加密参数生成方式用Python实现
加密的Http请求基本解析的流程就是这样,有道翻译这个例子只是让读者了解JavaScript加密参数的解析流程,在爬虫工程师的工作中,经常会遇到加密的Http请求,请务必熟悉以上过程。