一、引言
之前做的有道翻译爬虫接口是http://fanyi.youdao.com/translate
这个接口的爬虫当前仍然可用,但为什么还要用最新的http://fanyi.youdao.com/translate_o接口呢?
源于一件非常矛盾的事情,当翻译 【烏節文華BIG Hotel】这个词,本意是翻译成英文,结果翻译成中文,代码中无论怎么改语言翻译结果都是中文
到官网去试试,只要把翻译语言改成中文>>英文即可正常翻译成英文
为什么会出现这种情况呢?
二、操作过程
打开有道翻译网页版的调试模式一看,果然,用的接口不一样,当前有道用的translate_o接口,看来只有这个接口才能得到我想要的结果
于是乎,我的爪爪伸向了translate_o 接口
直接用原接口和参数访问,返回结果却是{"errorCode":50}。从Form Data中分析原因得知,salt,sign,ts三个参数值是动态变化的,每次请求其值都不同,这表明网站对这三个参数作出了加密反爬虫机制,若想取得数据,就必须先破解其加密机制
2.1破解反爬机制
通过观察源代码,发现fanyi.min.js很可疑,打开一看,果然salt和sign的加密位置在这里面
r就是ts参数,是时间戳i是salt,是r加上一个随机数,sign是一个md5加密
看到了吧,就是这么简单
另外,Cookie中的OUTFOX_SEARCH_USER_ID、Referer和User-Agent三个参数也是必须的
最后,把FormData中的from改成zh-CHS,to改成en
OK 成功翻译成我想要的效果
代码
#!/usr/bin/env python # -*- coding: utf-8 –*- # @Time : 2019/12/4 17:00 # @Author : ZhangYuge # @File : translate_yd.py import hashlib import random import time import requests """ 向有道翻译发送data,得到翻译结果 """ class Youdao: def __init__(self, msg): self.url = 'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule' self.msg = msg self.ts = self.get_ts() self.salt = self.get_salt() def get_ts(self): # 根据当前时间戳获取ts参数 s = int(time.time() * 1000) return str(s) def get_salt(self): # 根据当前时间戳获取salt参数 s = int(time.time() * 1000) + random.randint(0, 10) return str(s) def get_sign(self): # 使用md5函数和其他参数,得到sign参数 words = "fanyideskweb" + self.msg + self.salt + "n%A-rKaT5fb[Gy?;N5@Tj" # 对words进行md5加密 m = hashlib.md5() m.update(words.encode('utf-8')) return m.hexdigest() def get_result(self): Form_Data = { 'i': self.msg, 'from': 'zh-CHS', 'to': 'en', 'smartresult': 'dict', 'client': 'fanyideskweb', 'salt': self.salt, 'sign': self.get_sign(), 'ts': self.ts, 'bv': 'a4f4c82afd8bdba188e568d101be3f53', 'doctype': 'json', 'version': '2.1', 'keyfrom': 'fanyi.web', 'action': 'FY_BY_CLICKBUTTION' } headers = { 'Cookie': 'OUTFOX_SEARCH_USER_ID=1389460813@123.125.1.12', 'Referer': 'http://fanyi.youdao.com/', 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OSX10_14_2) AppleWebKit/537.36(KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36' } response = requests.post(self.url, data=Form_Data, headers=headers) translate_results = response.json() # 找到翻译结果 if 'translateResult' in translate_results: translate_results = translate_results['translateResult'][0][0]['tgt'] print(f' 【{self.msg}】 >>> 【{translate_results}】成功!') return translate_results else: print(translate_results) def change_cn2en(keywords): return Youdao(keywords).get_result() if __name__ == "__main__": keywords = '我爱中国' change_cn2en(keywords)