有道翻译的提交方式是POST,请求内容在form表单里,基本思路就是针对POST请求的普通爬虫,模拟表单的发送,然后问题出现了,{“errorCode”:50}。我记得一年前是可以用这样的思路解决的,结果现在不行了,看来是有道翻译的爬虫机制加了点什么,使用抓包工具抓取多次form表单,对比发现有两个值是变化的
- salt
- sign
这两个是什么东西,一般这种能在页面直接变化的东西都是用JS做的,我去看了看JS代码,在网页源代码最下边
</script><script type="text/javascript" src="http://shared.ydstatic.com/api/fanyi-web/assets/index.min.js" charset="utf-8"></script>
<script type="text/javascript" src="http://shared.ydstatic.com/fanyi/newweb/v1.0.17/scripts/newweb/fanyi.min.js"></script>
</html>
打开发现很乱,找了个JS代码在线格式化的网站,格式化了一下,然后放到sublime编辑器搜索salt,最终找到了这个
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 + "@6f#X3=cCuncYssPsuRUE")
}
};
很显然这段代码用时间戳+随机数生成了salt,又用要翻译的词(e)和salt(i)加上两端固定的字符串拼接成了一个新的字符串,然后再对这个字符串进行MD5加密,最终得到了sign。
知道这个剩下的就简单了,模拟这个加密过程然后加入到form表单里。
以下是源代码;(提醒以下,如果自己写的话在确定salt和sign都模拟成功了但还是报错的话,可以关注一下你写的headers,看里面缺不缺什么,我在这卡了好几个小时,坑啊)
# -*- coding:utf-8 -*-
import urllib
import urllib2
from tieba import createUA
def get_salt():
"""
作用:获取json中的salt值
"""
import random,time
return str(int(time.time()*1000) + random.randint(0,10))
#print(get_salt())
def get_sign(keyword,salt):
"""
作用:获取json中的sign值
"""
import hashlib
# 先拼接sign
sign = "fanyideskweb" + keyword + str(salt) + "@6f#X3=cCuncYssPsuRUE"
md5 = hashlib.md5()
md5.update(sign)
sign = md5.hexdigest()
return sign
def get_fanyi():
"""
作用:得到翻译结果
"""
url = "http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule"
keyword = raw_input("请输入需要翻译的文字:")
header = {
"Accept": "application/json,text/javascript,*/*;q=0.01",
"Accept-Language": "zh-CN,zh;q=0.9",
#"Connection": "keep-alive",
#"Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
"Cookie":"OUTFOX_SEARCH_USER_ID=1076696971@10.168.8.63;JSESSIONID=aaaZ6s5m9DVmYf8g3QoDw;OUTFOX_SEARCH_USER_ID_NCOO=473292646.5080033;___rl__test__cookies=1543228484656",
#"Host": "fanyi.youdao.com",
#"Origin":"http://fanyi.youdao.com",
"Referer":"http://fanyi.youdao.com/",
"User-Agent": "Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/69.0.3497.100Safari/537.36OPR/56.0.3051.104X-Requested-With:XMLHttpRequest"
}
salt = get_salt()
sign = get_sign(keyword,salt)
#print(salt)
#print(sign)
formdata = {
"i": keyword,
"from": "AUTO",
"to": "AUTO",
"smartresult": "dict",
"client": "fanyideskweb",
"salt": str(salt),
"sign": sign,
"doctype": "json",
"version": "2.1",
"keyfrom": "fanyi.web",
"action": "FY_BY_CLICKBUTTION",
"typoResult": "false",
}
data = urllib.urlencode(formdata)
#print(data)
#print("*"*20)
#print(header)
request = urllib2.Request(url, data=data,headers=header)
#print(request)
print(urllib2.urlopen(request).read())
if __name__ == '__main__':
get_fanyi()