(七)Python爬虫------有道翻译JS(JavaScript)参数分析,实现在线实时翻译(2020年1月16日)

最近工作有点忙,也就没有太多时间去学习Python爬虫,感觉身体好累,可能是想偷懒了吧!不说那么多了,回归本源,学习,搞起!!

今天爬取有道翻译词典数据,实现一个小小的在线实时翻译功能,那就开始干!

有道翻译官方网站:http://fanyi.youdao.com/

一、抓包分析,有道翻译是否是通过JS文件加载的数据

1.在有道中不输入任何关键字时,打开谷歌浏览器的开发者工具(按F12),这是点击XHR,发现没有请求下任何数据,再次刷新网页,依然没有请求到任何数据,如图所示:

(七)Python爬虫------有道翻译JS(JavaScript)参数分析,实现在线实时翻译(2020年1月16日)

 

2.先打开谷歌浏览器的开发者工具(按F12),再在有道中输入关键字:China,进行翻译,结果翻译成了中国,,页面中翻译的关键字和翻译结果显示出来了,其他页面几乎没有改变,这说明是使用了AJAX技术动态加载了数据,这时点击XHR,加载了一个translate_o?smartresult=dict&smartresult=rule的文件,点击该文件,再点击Headers,在General项中,出现了如下信息:

(七)Python爬虫------有道翻译JS(JavaScript)参数分析,实现在线实时翻译(2020年1月16日)

难道这个就是请求翻译数据的URL???

http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule

还是个POST请求,请求数据肯定需要将各种参数传进去,才可以

再点击response,发现响应的是一个JSON格式数据,里面有“中国”翻译结果,可以确定这就是我们要的URL.如下图:

(七)Python爬虫------有道翻译JS(JavaScript)参数分析,实现在线实时翻译(2020年1月16日)

3.再点击Headers,在Form Data项中,出现了如下信息:i:CHINA,这个不是刚才要输入的词吗?不懂不要着急,没事,继续干!!!

 

(七)Python爬虫------有道翻译JS(JavaScript)参数分析,实现在线实时翻译(2020年1月16日)

4.再将页面刷新一下,再在有道中输入关键字:good,进行翻译,结果翻译成了"好“”,这时再点击一下XHR,加载了一个translate_o?smartresult=dict&smartresult=rule的文件,点击该文件,再点击Headers,在Form Data项中,出现了如下信息:

(七)Python爬虫------有道翻译JS(JavaScript)参数分析,实现在线实时翻译(2020年1月16日)

 

5.这个翻译good的页面的Form Data项中数据和翻译CHINA的 页面的Form Data项中数据作对比,你会发现,salt,sign,ts这三个参数的值每次都不一样,其他参数都是一样的,这参数让人头疼啊!!!

那只能通过其他方法去获取这些参数了,固定不变的参数不用管,不用管,只管每次变化的参数,动态的!!!

再点击下network中的JS,加载了几个JS文件,说明有部分页面的数据是JS文件提供的,

那就放大招了,按鍵Shift+Ctrl+F进行全局搜索salt,果然在salt这个参数存在于JS文件中。说明是通过JS控制参数变化使的,所以说明有道翻译的数据是通过JS加密传输的。先鼠标点击以下JS代码,再按鍵Shift+F进行局部搜索salt,再点击上下箭头,最终找到了这个salt参数,如下图:

(七)Python爬虫------有道翻译JS(JavaScript)参数分析,实现在线实时翻译(2020年1月16日)

二、接下来就是着手对SJ参数salt,sign,ts 进行**了。

1.先看看刚才参数的JS函数,发现salt,sign,ts参数都在同一个函数里,那这个可以省力了

 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 + "n%A-rKaT5fb[Gy?;[email protected]")
        }
    };

刚才翻译的是good,在8371处打个断点,点击翻译,即可出现以下参数的值。发现e='good',原来是我们翻译的词啊,全选navigator.appVersion,出现了User-Agent

 

 

(七)Python爬虫------有道翻译JS(JavaScript)参数分析,实现在线实时翻译(2020年1月16日)

2.参数salt,sign,ts值分析获取

(七)Python爬虫------有道翻译JS(JavaScript)参数分析,实现在线实时翻译(2020年1月16日)

 r = "" + (new Date).getTime()    r显示为 r = "1579126629622"

ts=r      (getTime(),又是ts(timestamp时间戳))可以确定是时间戳

ts: 表示当前的时间戳的字符串, 注意js的时间戳和python的时间的有区别, js的时间戳是ms级的, 所以每次用python获得的时间戳都要*1000

获取ts:

import time
r= str((int(time.time()*1000)))
print("*******r**********",r)
ts=r

获取salt:

 i = r + parseInt(10 * Math.random(), 10);  i显示为 i = "15791266296224"

salt: 是字符串ts加上一个随机的范围为[0-9]的出现的整数4拼接成的字符串

import random
i=r+str(random.randint(0,10))
print(i)
salt=i

获取sign:

sign: n.md5("fanyideskweb" + e + i + "n%A-rKaT5fb[Gy?;[email protected]")

sign: 也是一个经过md5加密的字符串, e 表示翻译框内输入的内容good

import hashlib
sign_str="fanyideskweb" + input_data + salt + "n%A-rKaT5fb[Gy?;[email protected]"
sign0 = hashlib.md5()
sign0.update(sign_str.encode('utf-8'))
sign=sign0.hexdigest()

所有动态参数已经获取,下面进行网络请求就可以了

url = 'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'
response = requests.post(url=url, data=data, headers=headers).json()
print("***********response**************", response,"*************"+response["translateResult"][0][0]["tgt"])

三、完整代码如下:

import hashlib
import requests
import time
import random
import json

# hashlib 库, 用来 md5 加密
#input_key为需要翻译的词]

class YouDao_Translate(object):
    def __init__(self,input_data,ts,salt,bv,sign):
        self.input_data=input_data
        self.ts=ts
        self.salt=salt
        self.bv=bv
        self.sign=sign

    def get_TranslateData(self):
        headers = {
            'Cookie': '[email protected]; JSESSIONID=aaa8_mjwXyTIZ-5ULyQ_w; OUTFOX_SEARCH_USER_ID_NCOO=2040382756.2131336; ___rl__test__cookies=1579117111479',
            'Referer': 'http://fanyi.youdao.com/',
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36',
            'X-Requested-With': 'XMLHttpRequest'
        }
        data = {

            'i': self.input_data,
            'from': 'AUTO',
            'to': 'AUTO',
            'smartresult': 'dict',
            'client': 'fanyideskweb',
            'salt':self.salt,
            'sign':self.sign,
            'ts': self.ts,
            'bv': self.bv,
            'doctype': 'json',
            'version': '2.1',
            'keyfrom': 'fanyi.web',
            'action': 'FY_BY_REALTlME'
        }
        url = 'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'
        response = requests.post(url=url, data=data, headers=headers).json()
        print("***********response**************", response,"*************"+response["translateResult"][0][0]["tgt"])

input_data=input("输入翻译的数据:")
r= str((int(time.time()*1000)))
print("*******r**********",r)
ts=r

i=r+str(random.randint(0,10))
print(i)
salt=i
#d7923968d7ea53caf8c2c98c014700ff
str_data='5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36'
t0 = hashlib.md5()
t0.update(str_data.encode('utf-8'))
t=t0.hexdigest()
print("***********t**************",t)
bv=t
sign_str="fanyideskweb" + input_data + salt + "n%A-rKaT5fb[Gy?;[email protected]"
sign0 = hashlib.md5()
sign0.update(sign_str.encode('utf-8'))
sign=sign0.hexdigest()
print("***********sign**************",sign)

youdao_T=YouDao_Translate(input_data,ts,salt,bv,sign)

youdao_T.get_TranslateData()