前言
在小甲鱼课程里学习到的python爬取有道词典的翻译,发现一些东西不是很适用于现在,网上给出的答案分为两种
一、去掉 “_o”
import urllib.request
import urllib.parse
import json
key = input("请输入需要翻译的内容:")
url = "http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule"
#url = "http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule"
# 去掉了 _o
data = {
'i' : key,
'from': 'AUTO',
'to': 'AUTO',
'client' : 'fanyideskweb',
'smartresult': 'dict',
'keyfrom': 'fanyi.web',
'smartresult': 'dict',
'doctype': 'json',
'version': '2.1'
}
data = urllib.parse.urlencode(data).encode('utf8')
response = urllib.request.urlopen(url,data)
html = response.read().decode('utf8')
target = json.loads(html)
print("翻译结果:%s" %(target['translateResult'][0][0]['tgt']))
但是这个翻译不是那么灵动。有些结果和网页的结果其实是不一样的,比如翻译:我就是不服啊!
代码爬取结果:
在线翻译结果:
所以这个方法虽然简单,但是不太严谨。
二、JS 加密
在有道翻译的网页上找到这个JS文件:
随后在站长之家等类似的网站对代码进行格式化,在文本编辑器找到这段:
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 + "Tbh5E8=q6U3EXe+&L[4c@")
}
};
可以看到:
它对ts bv salt sign进行了加密处理:
ts: 用new Date.getTime()函数获取当前时间戳,距离1970年的毫秒数,并转换成str类型
bv: 获得浏览器的平台和版本信息的信息然后进行md5加密
salt: 用ts加上一个随机生成的0-10 的十进制数字
sign: 将"fanyideskweb" & 翻译的内容 & salt & ** “Tbh5E8=q6U3EXe+&L[4c@”** 进行md5加密
注 : "Tbh5E8=q6U3EXe+&L[4c@" 这段字符隔断时间会变的,所以如果返回error 50 ,可能是字符改变了,需要重新在headers里面找一下。
下面贴上代码:
import time
import random
import hashlib
import requests
import urllib.request
import urllib.parse
import json
url = 'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'
key = input("输入翻译的内容:")
lts = str(time.time())
#生成时间戳 ts
salt = lts + str(random.randint(0, 10))
# 通过 ts 加 0-10的随机整数字符生成 salt
sec = "fanyideskweb" + key + salt + "Tbh5E8=q6U3EXe+&L[4c@"
md5 = hashlib.md5()
md5.update(sec.encode('utf-8'))
sign = md5.hexdigest()
# md5加密生成 sign
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36',
'Host': 'fanyi.youdao.com',
'Origin': 'http://fanyi.youdao.com',
'Referer': 'http://fanyi.youdao.com/',
'Cookie': 'OUTFOX_SEARCH_USER_ID=559238864@10.168.8.61; OUTFOX_SEARCH_USER_ID_NCOO=2061523511.1027195; _ga=GA1.2.1151109878.1551536968; _ntes_nnid=24fe647fc20f952c4040b25650f75604,1553001083850; JSESSIONID=aaaJIa27BLmlI96aStZRw; ___rl__test__cookies='
}
data = {
'i': key,
'from': 'AUTO',
'to': 'AUTO',
'smartresult': 'dict',
'client': 'fanyideskweb',
'salt': salt,
'sign': sign,
'lts': lts,
'bv': 'e65e8e5642f3c2d719d32db0b5eff1f9',
'doctype': 'json',
'version': '2.1',
'keyfrom': 'fanyi.web',
'action': 'FY_BY_REALTlME'
}
data = urllib.parse.urlencode(data).encode('utf8')
req = urllib.request.Request(url,data,headers = headers)
# req = urllib.request.Request(url,data)
response = urllib.request.urlopen(req)
html = response.read().decode('utf8')
target = json.loads(html)
print("翻译结果:%s" %(target['translateResult'][0][0]['tgt']))
可以用这个在对比一下结果:
尝试翻译:我现在服气了!
代码爬取:
有道在线翻译:
可以看出,结果是一样的。