简单方法 —调用开源api
这个比较简单四行代码就可以搞定,先放代码:
1 import requests 2 while True: 3 input_data = input('请输入你要翻译的数据:') 4 print(requests.get('http://fanyi.youdao.com/translate',params={'doctype':'json',"type":'AUTO','i':input_data}).json()['translateResult'][0][0]['tgt'])
复杂一丢丢的JS解析
打开有道翻译官网,输入翻译的数据,鼠标右键检查,点击network,再点击翻译,
点第一个数据包,然后点击preview 或者response都能看到翻译结果,证明这个就是我们需要解析的数据包
重新回到headers里,往下拉到form表单:
我们需要分析这些数据的变化及加密方式,
复制一份:
i: 历史 from: AUTO to: AUTO smartresult: dict client: fanyideskweb salt: 16035204521008 sign: 7a1413f07087cacc38aed4fac47fd403 lts: 1603520452100 bv: 4abf2733c66fbf953861095a23a839a8 doctype: json version: 2.1 keyfrom: fanyi.web action: FY_BY_CLICKBUTTION
再如法翻译一个数据,复制form表单和上面的比较:
i: 文化 from: AUTO to: AUTO smartresult: dict client: fanyideskweb salt: 16035228374568 sign: 62eeb0e657b2d71181d6c87be026bbac lts: 1603522837456 bv: 4abf2733c66fbf953861095a23a839a8 doctype: json version: 2.1 keyfrom: fanyi.web action: FY_BY_CLICKBUTTION
比较得出,动态变化的数据只有四个:
1. i :即我们要翻译的数据
2. salt : 初步推测是以毫秒为单位的时间戳 + 一个随机数字
3. sign :未知的js加密后的数据
4. lts : 以毫秒为单位的时间戳
下面简单介绍一些常用的加密解密方法
常见的加密方法
MD5加密
MD5 是一种单向加密技术(不可逆向解密)。MD5加密算法简单高效且算出的值长度都是固定的, MD5值具有强抗碰撞,对原文件哪怕只修改一个字符,所计算出的MD5值也会发生很大变化。基于这些特性,MD5在数据校验上发挥有很大作用。
在python3中的使用:
1 import hashlib 2 3 a = 'hello!' 4 b = 'abc' 5 m1 = hashlib.md5(a.encode()).hexdigest() 6 m2 = hashlib.md5(b.encode()).hexdigest() 7 print(m1) #aed978dd6dffef14c3188d28cf0a272d 8 print(m2) #900150983cd24fb0d6963f7d28e17f72
base64加密
base64编码方法简单,但是却并不保险,别人很容易就能获取原始数据,通常是用来对文件进行一种格式化的操作,它是一种双向加密(可以逆向解密).
用法如下:
1 import base64 2 3 a = '123' 4 b = '123456789' 5 6 # base64加密 7 base_a = base64.b64encode(a.encode()).decode() 8 base_b = base64.b64encode(b.encode()).decode() 9 print(base_a) # MTIz 10 print(base_b) # MTIzNDU2Nzg5 11 12 # base64解密 13 aa = base64.b64decode('MTIz'.encode()).decode() 14 bb = base64.b64decode('MTIzNDU2Nzg5'.encode()).decode() 15 print(aa) # 123 16 print(bb) # 123456789
HAMC 加密
hamc 同样是基于hash算法,与上面两个加密不同的是,hamc加密是以一个密钥和一个消息作为输入,生成一个消息摘要输出,主要用于身份验证。
用法:
1 import hmac,hashlib 2 h = hmac.new(key='key'.encode(),msg='hello'.encode()) 3 h.update('world!'.encode()) 4 ret = h.hexdigest() 5 print(ret) # 774bd7473ce15ec74c015338cbf2d421
回归正题,目前大概只有一个sign不确定和那个加盐操作是不是加的随机数,接下来我们就需要具体分析网页了:
是四个部分用来做加密的参数
1 . “fanyideskweb”
2 .e : 要被翻译的数据
3 .salt : 毫秒为单位的时间戳 + 随机数字一个
4 . “]BjuETDhU)zqSxf-=B#7m”
至此,所有的参数解密完毕,可以开始编写代码了,具体参考代码如下:
1 import requests # 发送网络请求 2 import time # 导入时间戳 3 import random # 需要产生随机数进行加盐 4 import hashlib # 需要用到md5加密 5 import jsonpath # 解析json格式数据 6 7 # 函数的封装>>> 调用函数就能够得到翻译过后的数据 8 def youdao(): 9 while True: 10 # 确认目标的url 11 url_ = 'http://fanyi.youdao.com/translate_o' 12 # 设置form表单的参数 13 input_data = input('请输入你要翻译的数据:') # 要被翻译的数据 14 15 time_ = str(int(time.time() * 1000)) # 以毫秒为单位的时间戳 16 17 time_salt = time_ + str(random.randint(0, 10)) # salt加盐操作 以毫秒为单位的时间戳 + 随机数字 18 19 # 拼接字符串进行md5加密,生成sign值 20 a = "fanyideskweb" + input_data + time_salt + "Tbh5E8=q6U3EXe+&L[4c@" 21 sign = hashlib.md5(a.encode()).hexdigest() 22 23 # 设置请求头 用户代理, referer跳转, cookie 24 headers = { 25 'Proxy-Connection': 'keep-alive', 26 'Accept': 'application/json, text/javascript, */*; q=0.01', 27 'X-Requested-With': 'XMLHttpRequest', 28 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36', 29 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 30 'Origin': 'http://fanyi.youdao.com', 31 'Referer': 'http://fanyi.youdao.com/', 32 'Accept-Language': 'zh-CN,zh;q=0.9', 33 } 34 # cookie设置 35 cookies = { 36 'OUTFOX_SEARCH_USER_ID': '1994915372@10.108.160.100', 37 'OUTFOX_SEARCH_USER_ID_NCOO': '1497055759.2731764', 38 'JSESSIONID': 'aaa3M3QefQXLQe8TkbwEx', 39 '___rl__test__cookies': time_, 40 } 41 42 params = ( 43 ('smartresult', ['dict', 'rule']), 44 ) 45 46 47 # 发送post请求要携带的表单数据 48 form_data = { 49 "i": input_data, # 要被翻译的数据 50 "from": "AUTO", 51 "to": "AUTO", 52 "smartresult": "dict", 53 "client": "fanyideskweb", 54 "salt": time_salt, # 以毫秒为单位的时间戳 + 随机数字 55 "sign": sign, # 未知的js加密后的数据 56 "lts": time_, # 以毫秒为单位的时间戳 57 "bv": "4abf2733c66fbf953861095a23a839a8", 58 "doctype": "json", 59 "version": "2.1", 60 "keyfrom": "fanyi.web", 61 "action": "FY_BY_REALTlME", 62 } 63 try: 64 # 利用requests发送post请求,得到响应对象 65 response_ =requests.post(url=url_, headers=headers, params=params, cookies=cookies, data=form_data, verify=False) 66 67 # 得到响应对象,数据为json格式数据 68 py_data = response_.json() # 直接转成python数据类型 69 70 # 利用jsonpath解析,得到翻译数据 71 res_ = jsonpath.jsonpath(py_data,'$..tgt')[0] 72 73 print(res_) 74 except: 75 print('请出入正确格式的数据:') 76 continue 77 time.sleep(1) # 降低请求频率 避免被封禁IP 78 79 if __name__ == '__main__': 80 youdao()