Python爬蟲(五)——小小翻譯機(數據源來自有道翻譯)

我們之前已經講過了ajax的相關知識,現在我們來試試模擬js,破解有道翻譯做一個桌面級的翻譯機;

開發環境:

  1. Python3.6
  2. 谷歌瀏覽器

首先我們還是先分析一下網站:

  1. 首先我們先打開網站,調出“檢查”-“Network”,然後先把所有的數據先清空,然後選中 XHR,這就是我們異步請求交換的數據包:
  2. 我們往網站輸入我們想翻譯的內容,看看會出現什麼:
  3. 我們發現出現了兩個數據,我們先把第一個數據點開看一下,發現裏面就有我們剛纔輸入的內容,那麼這個就是我們需要的,數據進行交互的地方(一般來講都是第一個,如果不是一個個找一下,看開頭,有經驗之後很快會找到的),我們看看他的Headers裏面有什麼:

    從這裏我們可以看到兩點:
     1)實際請求的網址是:http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule
     2)請求方式是 POST
  4. 那麼有了這兩點,我們就可以發出請求了,但是還有一點,數據,沒有數據哪來的交互:
     
    我們往下來,發現有這麼一塊數據,這就是我們需要發送給服務器的數據,一堆東西,還有什麼神奇的字符,根本不知道是什麼意思,那我們乾脆再發送一個請求,看看有什麼變量:
    通過兩次的請求,我們發現中間的:salt、sign、ts,有變化,其他的都沒變,那麼這三項的值是怎麼得來的呢?我們又怎麼知道他們怎麼變化的呢?
  5. 我們點右上角的三點,選擇 “Search”,進行全局搜索,搜索上面三個變量的任意一個,看看他們在什麼地方出現過:


    我們發現有一個js文件裏面有相關的字段,我們單機一下,看看這個js文件的內容(點擊花括號格式化內容,我們可以看得舒服一點)
  6. 我們在這裏面再搜索一下salt,看看會發現什麼端倪:

    我們發現查找到了四處,我們一個一個看過去,看看那裏是這些值生成出來的地方,我們發現第二個貌似是的,我們詳細看一下;
  7. 這麼一坨東西,沒有基礎的話不一定能看得懂,那麼我們鼠標在行號那裏點一下,打一個斷點,重新發送一個請求,我們看看每個對應着什麼:

    我們發現:
     e 對應我們想要翻譯的內容
     t 是什麼我們暫且不知道,但是能看出來的是,它進行了md5加密
     r 我們可以看出來,它獲取了當前的時間,是一個時間戳
     i 我們看見它是在r的基礎上添加了一個隨機數
     最後 r->ts , t->bv , i->salt , sign這裏它還對字符串重新組合再進行了加密
  8. 現在我們已經知道了對應的關係,現在我們看下每一項是怎麼生成的:
    上面我們還不知道t是怎麼來的,我們把鼠標移到md5()裏面的參數上,看看這個參數是個啥:

    我們發現,這就是我們的數據頭裏面用戶代理的信息,它就是對這個信息進行了加密,因爲我們兩次都是同一臺機器發出的請求,所以在上面兩次的值都是一樣的;
    其他的我們貌似已經全部分析出來了,接下來我們就開始寫代碼,一步一步實現它;

代碼實現:

import requests     # 發出訪問請求
import hashlib      # md5加密
import time         # 生成時間戳
import random       # 生成隨機數

i = input('請輸入你想要翻譯的內容:')   # 我們通過input來動態輸入需要翻譯的內容

# 定義md5加密方法
def get_md5(str):
    str = str.encode('utf-8')    # 首先確定編碼格式
    md5 = hashlib.md5(str).hexdigest()    # 然後調用方法對數據進行加密
    return md5    # 返回加密結果
bv = get_md5('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36')

# ts = time.time()
# 1576496918.7001328    生成的時間戳是這樣的
# 1576495638700         這是我們需要的
ts = str(int(time.time()*1000))     # 將小數點往後移三位然後取整,最後轉換成字符串
# 1576497033075

salt = ts + str(random.randint(0,9))    # 在ts的基礎上,添加一位隨機數
# 15764971520279

# sign是一個組合字符串的md5加密
sign = get_md5('fanyideskweb{}{}n%A-rKaT5fb[Gy?;N5@Tj'.format(i,salt))

# 發送的數據字典
data ={
	'i':i,
	'from':'AUTO',
	'to':'AUTO',
	'smartresult':'dict',
	'client':'fanyideskweb',
	'salt':salt,
	'sign':sign,
	'ts':ts,
	'bv':bv,
	'doctype':'json',
	'version':'2.1',
	'keyfrom':'fanyi.web',
	'action':'FY_BY_REALTlME',
}

# 頭信息,不然會判斷是爬蟲,直接不給訪問
header = {
	'Accept':'application/json, text/javascript, */*; q=0.01',
	'Accept-Encoding':'gzip, deflate',
	'Accept-Language':'zh-CN,zh;q=0.9',
	'Connection':'keep-alive',
	'Content-Length':'251',
	'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8',
	'Cookie':'[email protected]; JSESSIONID=aaalVecYWkv0U69kSgo8w; OUTFOX_SEARCH_USER_ID_NCOO=1719213539.8631594; UM_distinctid=16f0e1ae29842c-027d1b22b4a1bb-2393f61-1fa400-16f0e1ae299441; ___rl__test__cookies=1576489665039',
	'Host':'fanyi.youdao.com',
	'Origin':'http://fanyi.youdao.com',
	'Referer':'http://fanyi.youdao.com/',
	'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36',
	'X-Requested-With':'XMLHttpRequest',
}

result = requests.post('http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule',headers=header,data=data).json()    # 發出請求,返回json格式數據
# 請輸入你想要翻譯的內容:天氣
# {'translateResult': [[{'tgt': 'The weather', 'src': '天氣'}]], 'errorCode': 0, 'type': 'zh-CHS2en', 'smartResult': {'entries': ['', '[氣象] weather\r\n'], 'type': 1}}

# 下面我們就是需要對獲得的數據進行提取:
print(result['translateResult'][0][0]['tgt'])

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章