此博客僅爲我業餘記錄文章所用,發佈到此,僅供網友閱讀參考,如有侵權,請通知我,我會刪掉。
打鐵趁熱,姊妹篇傳送門:python爬蟲入門 ✦ 某度翻譯破解
1.本篇文章思路
1.先從抓包裏面Network—XHR裏面的formdata表單分析,需要獲取的參數爲sign和salt等
2.複製sign或salt關鍵字在右上角的search搜索,定位到相關的Js文件
3.嘗試解析sign與salt等參數如何獲取
4.通過分析得出 sign和salt等參數的值,轉換爲python語法執行。
有了思路,接下來就簡單了!
1. 思路分析
1.1 分析url
本次文章鏈接爲 aHR0cCUzQS8vZmFueWkueW91ZGFvLmNvbS8=(base64解密即可)
(1) 進入主題,我們先打開某道翻譯:
細看下圖,然後點擊鍵盤的F12—Network–XHR。
(2) 在下圖畫框的地方輸入任意單詞,查看XHR抓包到的數據,看到右邊的Preview,無疑,這是我輸入的tiger的翻譯結果,這個就是我們需要的獲取的數據。接下來去分析一下這個數據包。
(3) 回到Headers這裏,可以看到請求的Form_Data的表單裏有很多數據,這個時候就需要來分析Form_Data表單了。
(4) 來分析一下 student和teacher的Form_Data表單。
通過比對兩組表單數據,sign和salt,ts(bv的數值不變,獲取與否都可以)是我們所需要獲取的數據。i則爲我們輸入需要的翻譯的單詞,接下來我們看一下如果獲取這幾個參數。
i: tiger # tiger
from: AUTO
to: AUTO
smartresult: dict
client: fanyideskweb
salt: 15662771467120
sign: a0ef696926e6c66ba585c185dd2555b9
ts: 1566277146712
bv: 53539dde41bde18f4a71bb075fcf2e66
doctype: json
version: 2.1
keyfrom: fanyi.web
action: FY_BY_REALTlME
i: dog # dog
from: AUTO
to: AUTO
smartresult: dict
client: fanyideskweb
salt: 15662772255363
sign: 54bb9089dfd67f6902cdc3aa2cbbd0c9
ts: 1566277225536
bv: 53539dde41bde18f4a71bb075fcf2e66
doctype: json
version: 2.1
keyfrom: fanyi.web
action: FY_BY_REALTlME
1.2 定位js
(1) 先來點擊右上角,選擇search會彈出下圖這個界面。這個時候我們需要尋找到該參數的js代碼塊所在,這裏就用瀏覽器自帶的關鍵字搜索。
(2)
- 先在下圖畫框的位置輸入個關鍵字sign:(
任意輸入我們需要的關鍵字) - 輸入關鍵字後會彈出包含該關鍵字的代碼,點擊彈出來的代碼
- 最後點擊畫框的大括號(它的作用是將代碼格式化,變得好看)。
(3) 跳轉到了該頁面,畫框的地方就是我們需要獲取的數據了。下面我們就來着手分析js代碼。
1.3 分析js
(1) 這裏可以看到,我們需要獲取的參數都是被賦值了一大堆我們看不懂的js代碼,但是沒有關係。我們直接將他們複製到隔壁的Console執行一番,看一下到底是何方神聖。
(2) 將複製到Console的js代碼參數執行後,可以看到 t是一個請求頭;r是一個時間戳;i則是時間戳加一個隨機(0~9)的數字。嗯,繼續往下看。
(4) 這裏我們在下圖畫框處打上代碼,然後輸入單詞,看一下變化。可以看到e就是我們輸入的單詞。好,現在我們已經知道所有的需要獲取的參數是如何實現的,接下來就是將Js代碼轉換爲python可執行的代碼。
(5) js轉換爲python語句如下,
# ts = r,轉換爲python語句如下
ts = str(int(time.time() * 1000))
# i爲時間戳 + 一個0~9的隨機數,轉換爲python語句如下
salt = ts + str(random.randint(0, 9))
# e爲我們輸入的單詞
string = ("fanyideskweb" + work + salt + "n%A-rKaT5fb[Gy?;N5@Tj")
s = md5()
s.update(string.encode())
sign = s.hexdigest()
分析完畢,接下來就直接上完整代碼了。
2. 完整代碼
import requests, random, time
from hashlib import md5
class Yd_Spider(object):
def __init__(self):
self.url = 'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'
self.headers = {
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Content-Length': '238',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Cookie': 'JSESSIONID=abc2fCmUbssL5cWnFrtXw; _ntes_nnid=b6d31eb207d41a6cd6feb4794683d10a,1564765173633; OUTFOX_SEARCH_USER_ID_NCOO=489358794.9066813; OUTFOX_SEARCH_USER_ID="[email protected]"; UM_distinctid=16c8a1f7050178-0e5b0c3f7e881d-c343162-144000-16c8a1f70511bc; DICT_UGC=be3af0da19b5c5e6aa4e17bd8d90b28a|; ___rl__test__cookies=1565701019374',
'Host': 'fanyi.youdao.com',
'Origin': 'http://fanyi.youdao.com',
'Proxy-Connection': 'keep-alive',
'Referer': 'http://fanyi.youdao.com/',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36',
'X-Requested-With': 'XMLHttpRequest',
}
def get_salt_sign_ts(self, work):
ts = str(int(time.time() * 1000))
salt = ts + str(random.randint(0, 9))
string = ("fanyideskweb" + work + salt + "n%A-rKaT5fb[Gy?;N5@Tj")
s = md5()
s.update(string.encode())
sign = s.hexdigest()
return ts, salt, sign
def parse_work(self, work):
ts, salt, sign = self.get_salt_sign_ts(work)
# 將參數對應的填好
data = {
'i': work,
'from': 'AUTO',
'to': 'AUTO',
'smartresult': 'dict',
'client': 'fanyideskweb',
'salt': salt,
'sign': sign,
'ts': ts,
'bv': '53539dde41bde18f4a71bb075fcf2e66',
'doctype': 'json',
'version': '2.1',
'keyfrom': 'fanyi.web',
'action': 'FY_BY_REALTlME',
}
res = requests.post(url=self.url, data=data, headers=self.headers).json() # 輸出爲列表,方便後面的提取
# 提取結果
result = res['translateResult'][0][0]['tgt']
# {'translateResult': [[{'tgt': '老虎', 'src': 'tiger'}]]....}
print(result) # 輸出結果
if __name__ == '__main__':
spider = Yd_Spider()
spider.parse_work('tiger')
文章很長,難免有出錯的地方,懇請各位爲我指正錯誤。
有不懂的地方歡迎在下方留言或一起討論。