本次實戰目標站點:http://fanyi.youdao.com/?keyfrom=fanyi-new.logo ,主要利用HTTP間諜抓包插件分析有道翻譯反爬機制,該抓包能幫我們過濾掉一些不需要的常規請求如圖片,css等。
**1、**首先分析提交翻譯請求後URL的規律。打開chrome的開發者工具,輸入翻譯內容後點擊“翻譯”按鈕,可以看到服務器返回的數據,如下圖所示:
此時我們點擊插件,可以看到其只有一個請求結果,相對與chrome的請求結果更加直觀快速得分析請求規律。從插件返回的結果中我們可以看到請求的URL爲:http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule ,請求時還攜帶了cookies和表單數據,下面我們將其展開:
**2、**經過多次的請求翻譯,並且每次翻譯後都去查看插件返回的數據,比較每次翻譯時發送的表單數據的值可知參數i、salt、sign、bv、ts這些是不同的,其他的數據都是一樣的,因此我們需找到這些參數的賦值規律。以salt爲關鍵詞我們進行全局搜索,如下圖:
搜索結果可知salt在fanyi.min.js文件中,再從該文件中搜索可得到其定義,而且同時我們也得到了其他參數的定義,這裏來做個簡介:
e:代表的是需要翻譯的字符串。
t:代表瀏覽器的版本號md5值,即User-Agent的md5值。
r:當前時間的時間戳。
salt:參數r加上0-10的隨機字符串。
sign:使用的是"fanyideskweb"+e+salt+"p09@Bn{h02_BIEe]$P^nG"的md5值。
知道生成原理後,我們就可以寫Python代碼,以下是全部代碼:
import js2py
import random,time
import hashlib
def set_user_agent():
USER_AGENTS = [
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)",
"Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)",
"Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506.30)",
"Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/523.15 (KHTML, like Gecko, Safari/419.3) Arora/0.3 (Change: 287 c9dfb30)",
"Mozilla/5.0 (X11; U; Linux; en-US) AppleWebKit/527+ (KHTML, like Gecko, Safari/419.3) Arora/0.6",
"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2pre) Gecko/20070215 K-Ninja/2.1.1",
"Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9) Gecko/20080705 Firefox/3.0 Kapiko/3.0",
"Mozilla/5.0 (X11; Linux i686; U;) Gecko/20070322 Kazehakase/0.4.5"
]
user_agent = random.choice(USER_AGENTS)
return user_agent
js_str = """ r = "" + (new Date).getTime()
, i = r + parseInt(10 * Math.random(), 10);"""
js_text = js2py.EvalJs()
js_text.execute(js_str)
def getSalt():
# salt的公式r = "" + ((new Date).getTime() + parseInt(10 * Math.random(), 10))
# 方法1:利用js2py模塊,獲取salt值:
# salt_text = js2py.EvalJs()
# salt_text.execute(js_str)
salt = js_text.i
# 方法2:將js_str翻譯成python代碼獲取salt值:
# salt = int(time.time()*1000) + random.randint(0, 10)
return salt
def getMd5(v):
md5 = hashlib.md5()
md5.update(v.encode("utf-8"))
sign = md5.hexdigest()
return sign
def getSign(key, salt):
sign = "fanyideskweb" + key + str(salt) + "p09@Bn{h02_BIEe]$P^nG"
sign = getMd5(sign)
return sign
class Youdao():
def __init__(self):
self.headers = {
"Accept": "application/json,text/javascript,*/*;q=0.01",
"Accept-Encoding": "gzip,deflate",
"Accept-Language": "zh-CN,zh;q=0.9",
"Connection": "keep-alive",
"Host": "fanyi.youdao.com",
"Origin": "http://fanyi.youdao.com",
"Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
'User-Agent': set_user_agent(),
'Referer': 'http://fanyi.youdao.com/',
'Cookie': '[email protected]; JSESSIONID=aaaBADMLwT0Wj8je4pjKw; OUTFOX_SEARCH_USER_ID_NCOO=1012727192.8548353; YOUDAO_MOBILE_ACCESS_TYPE=0; DICT_UGC=be3af0da19b5c5e6aa4e17bd8d90b28a|; JSESSIONID=abcVeHVPsZKjL9bo6tjKw; user-from=http://www.youdao.com/; from-page=http://www.youdao.com/; ___rl__test__cookies=1550646069714'
}
self.data = {
'i': None,
"from": "AUTO",
"to": "AUTO",
"smartresult": "dict",
'client': 'fanyideskweb',
'keyfrom': 'fanyi.web',
"doctype": "json",
"version": "2.1",
"action": "FY_BY_CLICKBUTTION",
"typoResult": "false",
"bv":getMd5(set_user_agent()),
"ts":js_text.r,
'salt': None,
'sign': None
}
self.url = 'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'
def translate(self, word):
self.data['i'] = word
self.data['salt'] = getSalt()
self.data['sign'] =getSign(word,getSalt())
res = requests.post(self.url, headers=self.headers, data=self.data)
return res.json()['translateResult'][0][0]['tgt']
if __name__ == '__main__':
youdao = Youdao()
while True:
word=input('請輸入要翻譯的內容:')
print("翻譯結果爲:{}".format(youdao.translate(word)))
運行結果如下: