1、引言
當前成功時間:2019-6-28java
本人使用環境:python
- Python3.7 (Anaconda)
- IDE:PyCharm
- 系統:mac
2、具體操做
2.1 審查元素
(1)打開有道翻譯網址:http://fanyi.youdao.com/ ,右鍵空白處選擇「審查元素/檢查」,點擊「Network」,選擇「XHR」。jquery
在左側輸入要翻譯內容,好比說「你好」,網站會自動生成翻譯顯示在右側界面,並在XHR中多出一個translate_o文件,點擊「翻譯」按鈕,也會多出一個translate_o文件,不一樣之處在於Form Data中的action參數,前者爲FY_BY_REALTlME,後者是FY_BY_CLICKBUTTION,兩種方法皆可,本文之後者爲例。web
(2)須要記住的內容有:json
Request Headers(請求頭,只須要Cookie,Referer,User-Agent)cookie
Request URL(請求URL地址)app
Form Data(發送的數據)dom
Response(響應內容,可根據其格式取要顯示數據)ide
2.2 破解反爬蟲機制
在無爬蟲機制的狀況下,咱們能夠簡單的使用Form Data中的內容,以及Request Headers請求數據。
Form_Data = { 'i': self.msg, 'from': 'AUTO', 'to': 'AUTO', 'smartresult': 'dict', 'client': 'fanyideskweb', 'salt': '15616860238197', 'sign': '67bf9a6f73b5fc6f3ecc7c14047403f8', 'ts': '1561686023819', 'bv': 'c6b8c998b2cbaa29bd94afc223bc106c', 'doctype': 'json', 'version': '2.1', 'keyfrom': 'fanyi.web', 'action': 'FY_BY_REALTlME' } response = requests.post(self.url, data=Form_Data, headers=headers).text translate_results = json.loads(response)
然而,返回結果倒是{"errorCode":50}。從Form Data中分析緣由得知,salt,sign,ts三個參數值是動態變化的,每次請求其值都不一樣,這代表網站對這三個參數做出了加密反爬蟲機制,若想取得數據,就必須先破解其加密機制。
觀察這幾個參數,猜想salt和ts參數與時間戳有關,具體使用了何種加密方式,還要去看網頁代碼元素。
右鍵,查看網頁源代碼,在html中並無找到對應參數,那麼就可能在js文件中,在網頁的最後一部分代碼,根據js文件的文件名,猜想這幾個參數的獲取方式可能在"fanyi.min.js"文件中。
打開該js文件,發現這個文件是處理過的 js,直接看是難以看出邏輯的,因此能夠把 js 代碼放到一些能夠從新排版的工具中再查看,如在線「站長工具」,最後能夠經過搜索「salt」找到幾個參數的生成位置,具體代碼片斷以下:
define("newweb/common/service", ["./utils", "./md5", "./jquery-1.7"], function(e, t) { var n = e("./jquery-1.7"); e("./utils"); e("./md5"); 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 + "@6f#X3=cCuncYssPsuRUE") } };
從上述參數生成代碼中,可知:
(1)網站採用的是md5加密 (2)ts = "" + (new Date).getTime() ,爲時間戳 (3)salt = "" + (new Date).getTime() + parseInt(10 * Math.random(), 10) (4)sign = n.md5("fanyideskweb" + e + i + "@6f#X3=cCuncYssPsuRUE") 其中,e爲要翻譯內容,i爲時間戳,等於ts,其他爲固定字符串
明確參數獲取方式後,便可編寫python代碼,破解反爬蟲機制。
3、附錄代碼
import hashlib import random import time import requests import json """ 向有道翻譯發送data,獲得翻譯結果 """ class Youdao: def __init__(self, msg): self.msg = msg self.url = 'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule' self.D = "@6f#X3=cCuncYssPsuRUE" self.salt = self.get_salt() self.sign = self.get_sign() self.ts = self.get_ts() def get_md(self, value): # md5加密 m = hashlib.md5() # m.update(value) m.update(value.encode('utf-8')) return m.hexdigest() def get_salt(self): # 根據當前時間戳獲取salt參數 s = int(time.time() * 1000) + random.randint(0, 10) return str(s) def get_sign(self): # 使用md5函數和其餘參數,獲得sign參數 s = "fanyideskweb" + self.msg + self.salt + self.D return self.get_md(s) def get_ts(self): # 根據當前時間戳獲取ts參數 s = int(time.time() * 1000) return str(s) def get_result(self): Form_Data = { 'i': self.msg, 'from': 'AUTO', 'to': 'AUTO', 'smartresult': 'dict', 'client': 'fanyideskweb', 'salt': self.salt, 'sign': self.sign, 'ts': self.ts, 'bv': 'c6b8c998b2cbaa29bd94afc223bc106c', 'doctype': 'json', 'version': '2.1', 'keyfrom': 'fanyi.web', 'action': 'FY_BY_CLICKBUTTION' } headers = { 'Cookie': 'OUTFOX_SEARCH_USER_ID=-368708839@10.108.160.18; JSESSIONID=aaaL2DMAbpTgg8Qpc2xUw; OUTFOX_SEARCH_USER_ID_NCOO=1451460344.418452; ___rl__test__cookies=1561684330987', '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).text translate_results = json.loads(response) # 找到翻譯結果 if 'translateResult' in translate_results: translate_results = translate_results['translateResult'][0][0]['tgt'] print("翻譯的結果是:%s" % translate_results) else: print(translate_results) if __name__ == "__main__": y = Youdao('我成功啦') y.get_result()