王崇剛
摘要:利用Python爬取網(wǎng)頁(yè)數(shù)據(jù)通常使用Python的urllib庫(kù)及第三方requests庫(kù)實(shí)現(xiàn),本文闡述了如何利Python的第三方requests庫(kù)向有道翻譯在線翻譯網(wǎng)站發(fā)送POST請(qǐng)求,并對(duì)有道翻譯網(wǎng)站的加密過程進(jìn)行了分析,最后將網(wǎng)站反饋的翻譯結(jié)果進(jìn)行處理,從而實(shí)現(xiàn)基于Python在線翻譯爬蟲。
關(guān)鍵詞:? Requests ;Python;網(wǎng)絡(luò)爬蟲;在線翻譯
中圖分類號(hào):TP311? ? ? ? 文獻(xiàn)標(biāo)識(shí)碼:A
文章編號(hào):1009-3044(2019)28-0219-03
Abstract:? Usually use Python crawl web data using the Python urllib library and the realization of the third party requests the library, this paper expounds how the third party requests of Python library send a POST request to the translation youdao online translation website, and the encryption process of youdao translation site was analyzed, and finally translated website feedback result, which is based on the Python online translation the crawler.
Key words: Requests;Python;Web crawler;Online translation
有道翻譯網(wǎng)站采用HTTP協(xié)議實(shí)現(xiàn)客戶端瀏覽器與翻譯網(wǎng)站通信,利用Python編寫爬蟲程序偽裝成為瀏覽器與在線翻譯網(wǎng)站通信,從而實(shí)現(xiàn)在線翻譯爬蟲。Python通常使用urllib庫(kù)、requests庫(kù)實(shí)現(xiàn)爬取網(wǎng)站數(shù)據(jù),而requests庫(kù)提供了更高級(jí)的封裝、使用更為簡(jiǎn)潔、更容易理解等優(yōu)勢(shì),從而獲得了更為廣泛的使用。本文將使用requests庫(kù)中的方法實(shí)現(xiàn)在線翻譯爬蟲。
1 在線翻譯爬蟲的實(shí)現(xiàn)準(zhǔn)備
1.1 分析在線翻譯網(wǎng)站前的準(zhǔn)備
打開瀏覽器在瀏覽器地址欄中輸入有道翻譯網(wǎng)站地址(http://fanyi.youdao.com/),同時(shí)打開Fiddler軟件捕獲通信數(shù)據(jù)包,在有道翻譯網(wǎng)站的對(duì)話框中輸入需要翻譯的文字“貴州省貴陽(yáng)市觀山湖區(qū)”,通過翻譯可以得到翻譯后的英文“Guanshanhu district, guiyang city, guizhou province”,該翻譯結(jié)果作為后期爬蟲的驗(yàn)證使用。
1.2 分析請(qǐng)求方式
通過Fiddler軟件分析瀏覽器與有道翻譯網(wǎng)站通信數(shù)據(jù)包,分析瀏覽器與翻譯網(wǎng)站通信中HTTP協(xié)議及參數(shù)含義,通過Fiddler軟件抓取數(shù)據(jù)包分析(如圖 1所示),有道翻譯網(wǎng)站均采用HTTP協(xié)議中的POST方法將需要翻譯的文本提交給服務(wù)器處理。
1.2 與有道翻譯網(wǎng)站通信POST請(qǐng)求參數(shù)的分析
通過圖 2可以得到有道翻譯網(wǎng)站POST請(qǐng)求中的參數(shù),參數(shù)“i”標(biāo)識(shí)需要翻譯的文本,參數(shù)“i”的值為“貴州省貴陽(yáng)市觀山湖區(qū)”;參數(shù)“from”表示翻譯前的文本語言,默認(rèn)值為自動(dòng)檢測(cè)翻譯前的文本語言;參數(shù)“to”表示需要翻譯的目標(biāo)語言,默認(rèn)值為auto語言(默認(rèn)翻譯是中英、英中的翻譯);參數(shù)“salt”表示時(shí)間戳用于加密時(shí)使用;參數(shù)“sign”表示加密驗(yàn)證字段,該加密驗(yàn)證字段根據(jù)需要翻譯文本和時(shí)間戳進(jìn)行加密,所以每次請(qǐng)求不一致。
1.4 有道翻譯網(wǎng)站返回翻譯結(jié)果分析
通過Fiddler軟件分析,有道翻譯網(wǎng)站返回的翻譯結(jié)果均采用JSON格式,JSON是一種簡(jiǎn)單的數(shù)據(jù)交換格式,其優(yōu)點(diǎn)是數(shù)據(jù)格式簡(jiǎn)單,易于讀寫,占用帶寬小;易于解析,支持多種語言。
通過圖 3分析得出,有道翻譯網(wǎng)站返回結(jié)果在translateResult對(duì)象中,在translateResult對(duì)象中“src”為翻譯前文本的key,其key對(duì)應(yīng)的value為貴州省貴陽(yáng)市觀山湖區(qū),“tgt”為翻譯后文本的key,其key對(duì)應(yīng)的value為Guanshanhu district, guiyang city, guizhou province。
2在線翻譯網(wǎng)站加密驗(yàn)證分析
通過Fiddler軟件對(duì)有道翻譯網(wǎng)站HTTP協(xié)議分析,有道翻譯網(wǎng)站為了防止網(wǎng)絡(luò)爬蟲采用了加密驗(yàn)證,通過分析有道翻譯網(wǎng)站上的fanyi.min.js文件,有道翻譯網(wǎng)站加密驗(yàn)證首先需要生成一個(gè)13位salt時(shí)間戳,該時(shí)間戳不僅是POST請(qǐng)求中的salt的值還是計(jì)算sign中的主要參數(shù)之一。其次,通過MD5消息摘要算法生成一個(gè)128位的散列值,消息摘要算法中須要包含“fanyideskweb”、翻譯的文本、有道翻譯網(wǎng)站的加密字符串(該加密字符串每隔一段時(shí)間會(huì)發(fā)生變化,具體加密字符串見fanyi.min.js文件中的sign加密算法)等參數(shù),通過MD5計(jì)算后的散列值就是POST請(qǐng)求中的sign值。具體加密驗(yàn)證流程見圖4所示。
時(shí)間戳參數(shù)算法中的參數(shù)說明:time.time()獲取當(dāng)前時(shí)間的時(shí)間戳,因Python返回的時(shí)間戳是只有10位整數(shù)的浮點(diǎn)數(shù),為獲取13位時(shí)間戳,將時(shí)間戳乘以1000以獲取13位時(shí)間戳值;random.randint(0, 10)是隨機(jī)獲取10以內(nèi)的正整數(shù),最后將13位時(shí)間戳值加上10以內(nèi)的正整數(shù)結(jié)果取整數(shù)部分得到時(shí)間戳參數(shù)salt的值。
sign方法中的參數(shù)說明:get_md5()是Python的MD5的方法,fanyideskweb參數(shù)指的是客戶端類型為網(wǎng)頁(yè),key參數(shù)表示需要翻譯的文本,str(salt)參數(shù)表示將13位整數(shù)時(shí)間戳轉(zhuǎn)換為字符串,加密字符串每隔一段時(shí)間回發(fā)生變化,該字符串可在fanyi.min.js文件中中進(jìn)行通過搜索關(guān)鍵字“sign:n.md5”,查找到如sign:n.md5 (“fanyideskweb”+e+i+”加密字符串”)字樣獲取加密字符串,也可以通過爬蟲查找加密字符串。
Fanyi.min.js 地址如下:http://shared.ydstatic.com/fanyi/newweb/v1.0.18/scripts/newweb/fanyi.min.js
3 在線翻譯爬蟲的實(shí)現(xiàn)
通過分析了在線翻譯網(wǎng)站的請(qǐng)求方法、參數(shù)含義、返回結(jié)果、加密驗(yàn)證后,在線翻譯爬蟲可以依據(jù)圖 5的流程來實(shí)現(xiàn)。
3.1 構(gòu)建HTTP請(qǐng)求Header,偽裝瀏覽器
構(gòu)建http的請(qǐng)求頭部目的在于偽裝成為瀏覽器與翻譯網(wǎng)站進(jìn)行通信,構(gòu)造方法如下:
Httpheaders = {“User-Agent”: “Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:64.0) Gecko/20100101 Firefox/64.0”, “Referer”: “http://fanyi.youdao.com/”},這里以構(gòu)造火狐瀏覽器的請(qǐng)求頭部為例,請(qǐng)求的網(wǎng)址是:http://fanyi.youdao.com/
3.2 構(gòu)建Post請(qǐng)求中data參數(shù)
Post請(qǐng)求參數(shù)中需要包含需要翻譯的文字、salt、sign等主要參數(shù),salt、sign的方法見本文的第三部分,需要構(gòu)建的參數(shù)如圖 2所示。構(gòu)建Post請(qǐng)求中data參數(shù)的方法如下:
WebForms = {“i”: src_word,”from”: “AUTO”, “to”: “AUTO”, “smartresult”: “dict”,? ? ? ? “client”: “fanyideskweb”,”salt”: salt,”sign”: sign,”doctype”: “json”,”version”: “2.1”,? ? ? “keyfrom”: “fanyi.web”,”action”: “FY_BY_REALTIME”,”typoResult”: “false”}
retrun WebForms
3.3 向在線翻譯網(wǎng)站發(fā)送POST請(qǐng)求
在構(gòu)造完P(guān)OST的data后,利用requests庫(kù)中的post方法向有道翻譯網(wǎng)站發(fā)送post請(qǐng)求,其中cookies為http請(qǐng)求中產(chǎn)生的cookies。
Response = requests.post(url, headers=Httpheaders, data=WebForms, cookies=cookies)
3.4 獲取返回的json數(shù)據(jù)
從響應(yīng)中獲取json參數(shù),通過處理提取翻譯結(jié)果并打印,具體代碼如下:
json_str = response.json()? #從響應(yīng)中獲取json字符串
json_str = re.sub(‘\, ‘\”, str(json_str))? # 將單引號(hào)變?yōu)殡p引號(hào)
jsonObj=json.loads(json_str)? #將已編碼的 JSON 字符串解碼為 Python 對(duì)象
tgt_dic=jsonObj[‘translateResult][0][0][‘tgt]? #提取 JSON中的翻譯結(jié)果
print(“翻譯結(jié)果:”+tgt_dic)? #打印翻譯結(jié)果
4 在線翻譯爬蟲的結(jié)果分析
通過有道翻譯網(wǎng)站(如圖 6所示)與基于Python在線翻譯爬蟲程序(如圖 7所示)對(duì)“貴州省貴陽(yáng)市觀山湖區(qū)”和“Guanshanhu district, guiyang city, guizhou province”兩句話翻譯的結(jié)果進(jìn)行對(duì)比分析,翻譯結(jié)果一致,說明基于Python在線翻譯爬蟲已經(jīng)實(shí)現(xiàn)。
參考文獻(xiàn):
[1]夏天琦.Python爬蟲獲取網(wǎng)絡(luò)圖片[J].電子世界,2018(10).
[2]韓前進(jìn).Web在線爬蟲的設(shè)計(jì)與實(shí)現(xiàn)[J].軟件,2018(9).
[3]劉榮欣.基于Apache HttpClient的在線翻譯代理系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)[D].東北大學(xué),2014.
[4]郭麗蓉. 基于Python的網(wǎng)絡(luò)爬蟲程序設(shè)計(jì)[J].電子技術(shù)與軟件工程,2017(23)
[5]施俊龍.動(dòng)態(tài)口令S/KEY認(rèn)證協(xié)議的改進(jìn)與應(yīng)用[D].合肥工業(yè)大學(xué),2010.
[6]網(wǎng)易公司. 有道翻譯API[OL].? http://fanyi.youdao.com/openapi.
【通聯(lián)編輯:唐一東】