亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Python3爬取有道翻譯的兩種方法

系統(tǒng) 2196 0

一. 破解參數(shù)加密

有道翻譯的請(qǐng)求是post,攜帶一系列參數(shù),直接F12刷新進(jìn)行調(diào)試,如下圖所示:

Python3爬取有道翻譯的兩種方法_第1張圖片

這是一個(gè) post 請(qǐng)求,目標(biāo)網(wǎng)址是

            
              'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'
            
          

接下來(lái)讓我們看看發(fā)送該請(qǐng)求需要攜帶哪些參數(shù)

Python3爬取有道翻譯的兩種方法_第2張圖片

如圖所示,紅色方框里的就是需要攜帶的參數(shù)了。

最后看一看返回的數(shù)據(jù)

Python3爬取有道翻譯的兩種方法_第3張圖片

顯而易見(jiàn),返回的數(shù)據(jù)是json格式的數(shù)據(jù)。

好了,現(xiàn)在我們可以寫程序進(jìn)行爬取了

            
              # -*-coding:utf-8-*-

__Author__ = "Mr.D"
__Date__ = '2019\5\26 0026 16:50'


from faker import Faker
import requests


ua = Faker().user_agent()
url = 'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'


key = input("請(qǐng)輸入你需要翻譯的內(nèi)容: ")


# 請(qǐng)求頭
headers = {
    'User-Agent': ua,
    'Host': 'fanyi.youdao.com',
    'Origin': 'http://fanyi.youdao.com',
    'Referer': 'http://fanyi.youdao.com/',
}


# post請(qǐng)求攜帶的參數(shù)
from_data = {
    'i': key,
    'from': 'UTO',
    'to': 'UTO',
    'smartresult': 'dict',
    'client': 'fanyideskweb',
    'salt': 15588802331547,
    'sign': 3e91f2d8788201c03bfa0a672b116998,
    'ts': 1558880233154,
    'bv': '5504a5c7c19867a06038cf79d29f756a',
    'doctype': 'json',
    'version': '2.1',
    'keyfrom': 'fanyi.web',
    'action': 'FY_BY_REALTlME'
}


response = requests.post(url, headers=headers, data=from_data).json()
print(response)
print(response['translateResult'][0][0]['tgt'])

            
          

運(yùn)行后發(fā)現(xiàn)報(bào)錯(cuò)了,"{errorCode: 50}"

Python3爬取有道翻譯的兩種方法_第4張圖片

什么原因呢? 讓我們分析一下。

可以自己 重新來(lái)翻譯一下? "問(wèn)題" 這個(gè)詞,然后在看一次此次 post 請(qǐng)求與上一次 post 請(qǐng)求有什么不同之處。

經(jīng)過(guò)調(diào)試,我發(fā)現(xiàn) from_data 中的參數(shù)有幾個(gè)是發(fā)生了變化的,分別是 "salt","sign","ts",那么這幾個(gè)參數(shù)是怎么生存的呢?

經(jīng)過(guò)尋找,發(fā)現(xiàn)它們的生存規(guī)律在 "http://shared.ydstatic.com/fanyi/newweb/v1.0.17/scripts/newweb/fanyi.min.js" 這個(gè)? js 文件中,經(jīng)過(guò) json 格式化工具(百度)格式化之后,定位到具體的參數(shù)生成位置,

            
              // e 為下面 r(t) 中的 t ,即我們所需要翻譯的內(nèi)容
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 + "n%A-rKaT5fb[Gy?;N5@Tj")
			}
		};
		t.recordUpdate = function(e) {
            // 將我們所要翻譯的內(nèi)容賦值給 t 
			var t = e.i,
                // 將 t 當(dāng)作參數(shù)傳入 r() 函數(shù)中,返回值賦給 i 
				i = r(t);
			n.ajax({
				type: "POST",
				contentType: "application/x-www-form-urlencoded; charset=UTF-8",
				url: "/bettertranslation",
                // 這里可以看出 data 就是我們post請(qǐng)求攜帶的參數(shù)字典
				data: {
                    // e.i 就是我們所要翻譯的內(nèi)容
					i: e.i,
					client: "fanyideskweb",
					salt: i.salt,
					sign: i.sign,
					ts: i.ts,
					bv: i.bv,
					tgt: e.tgt,
					modifiedTgt: e.modifiedTgt,
					from: e.from,
					to: e.to
				},
				success: function(e) {},
				error: function(e) {}
			})
		}
            
          

從上述代碼中,我們可以得出四個(gè)參數(shù)的信息: ts,bv,salt,sign,他們分別為

            
              ts: "" + (new Date).getTime(),
bv: n.md5(navigator.appVersion),
salt: ts + parseInt(10 * Math.random(), 10),
// e為所需要翻譯的字符串, i 即salt
sign: n.md5("fanyideskweb" + e + salt + "n%A-rKaT5fb[Gy?;N5@Tj")
            
          

分析一波:

bv 是對(duì)? navigator.appVersion(這是個(gè)瀏覽器參數(shù),不是字符串"navigator.appVersion")進(jìn)行 md5 加密,在相同的瀏覽器下,這個(gè)值是固定的(沒(méi)測(cè)試過(guò)),所以直接拿F12調(diào)試出來(lái)的來(lái)用就好了。

ts 是時(shí)間戳

salt 是 ts 加上一個(gè) 0 到 10 的隨機(jī)數(shù)(包括0,不包括10)

sign 是對(duì)?"fanyideskweb" + e + salt + "n%A-rKaT5fb[Gy?;N5@Tj" (這個(gè)字符串是會(huì)更新的,在js文件里可以找到)這個(gè)字符串進(jìn)行 md5 加密

好了,知道以上信息,我們可以進(jìn)一步完善我們的代碼了,如下圖:

            
              # -*-coding:utf-8-*-

__Author__ = "Mr.D"
__Date__ = '2019\5\26 0026 16:50'


import time
from faker import Faker
import random
import hashlib
import requests


ua = Faker().user_agent()
url = 'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'


key = input("請(qǐng)輸入你需要翻譯的內(nèi)容: ")

//生成時(shí)間戳 ts
ts = str(time.time() * 1000)

// 通過(guò) ts 加 0-10的隨機(jī)整數(shù)字符生成 salt
salt = ts + str(random.randint(0, 10))
the_str = "fanyideskweb" + key + salt + "n%A-rKaT5fb[Gy?;N5@Tj"

// md5加密生成 sign
md5 = hashlib.md5()
md5.update(the_str.encode('utf-8'))
sign = md5.hexdigest()


headers = {
  
    'User-Agent': ua,
    'Host': 'fanyi.youdao.com',
    'Origin': 'http://fanyi.youdao.com',
    'Referer': 'http://fanyi.youdao.com/',
   }


from_data = {
    'i': key,
    'from': 'UTO',
    'to': 'UTO',
    'smartresult': 'dict',
    'client': 'fanyideskweb',
    'salt': salt,
    'sign': sign,
    'ts': ts,
    'bv': '5504a5c7c19867a06038cf79d29f756a',
    'doctype': 'json',
    'version': '2.1',
    'keyfrom': 'fanyi.web',
    'action': 'FY_BY_REALTlME'
}


response = requests.post(url, headers=headers, data=from_data).json()
print(response)
print(response['translateResult'][0][0]['tgt'])

            
          

完成之后再次爬取,發(fā)現(xiàn)還是報(bào)一樣的錯(cuò)誤。

納尼!! 再三檢查代碼,沒(méi)有發(fā)現(xiàn)有寫錯(cuò)任何地方啊

既然? from_data 沒(méi)有寫錯(cuò),那么問(wèn)題可能是出現(xiàn)在了 headers 上了

經(jīng)過(guò)調(diào)試,發(fā)現(xiàn)每次 headers 都會(huì)攜帶 cookie ,而且 cookie 的值每次都不一樣

'Cookie': 'OUTFOX_SEARCH_USER_ID=559238864@10.168.8.61; OUTFOX_SEARCH_USER_ID_NCOO=2061523511.1027195; _ga=GA1.2.1151109878.1551536968; _ntes_nnid=24fe647fc20f952c4040b25650f75604,1553001083850; JSESSIONID=aaaJIa27BLmlI96aStZRw; ___rl__test__cookies=1558881656766'

不一樣的地方在于最后的那個(gè) "__rl__test__cookies=" 后面的字符串不一樣,然后去找到它是怎么生成的,最后終于在

"http://shared.ydstatic.com/js/rlog/v1.js" 這個(gè)js文件中找到了它

Python3爬取有道翻譯的兩種方法_第5張圖片

原來(lái)它也是時(shí)間戳,怪不得看起來(lái)有點(diǎn)像

繼續(xù)完善代碼

            
              # -*-coding:utf-8-*-

__Author__ = "Mr.D"
__Date__ = '2019\5\26 0026 16:50'


import time
from faker import Faker
import random
import hashlib
import requests


ua = Faker().user_agent()
url = 'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'


key = input("請(qǐng)輸入你需要翻譯的內(nèi)容: ")

//生成時(shí)間戳 ts
ts = str(time.time() * 1000)

// 通過(guò) ts 加 0-10的隨機(jī)整數(shù)字符生成 salt
salt = ts + str(random.randint(0, 10))
the_str = "fanyideskweb" + key + salt + "@6f#X3=cCuncYssPsuRUE"

// md5加密生成 sign
md5 = hashlib.md5()
md5.update(the_str.encode('utf-8'))
sign = md5.hexdigest()


headers = {
    'User-Agent': ua,
    'Host': 'fanyi.youdao.com',
    'Origin': 'http://fanyi.youdao.com',
    'Referer': 'http://fanyi.youdao.com/',
    'Cookie': 'OUTFOX_SEARCH_USER_ID=559238864@10.168.8.61; OUTFOX_SEARCH_USER_ID_NCOO=2061523511.1027195; _ga=GA1.2.1151109878.1551536968; _ntes_nnid=24fe647fc20f952c4040b25650f75604,1553001083850; JSESSIONID=aaaJIa27BLmlI96aStZRw; ___rl__test__cookies=' + ts
}

from_data = {
    'i': key,
    'from': 'UTO',
    'to': 'UTO',
    'smartresult': 'dict',
    'client': 'fanyideskweb',
    'salt': salt,
    'sign': sign,
    'ts': ts,
    'bv': '5504a5c7c19867a06038cf79d29f756a',
    'doctype': 'json',
    'version': '2.1',
    'keyfrom': 'fanyi.web',
    'action': 'FY_BY_REALTlME'
}


response = requests.post(url, headers=headers, data=from_data).json()
print(response)
print(response['translateResult'][0][0]['tgt'])

            
          

好了,讓我們運(yùn)行代碼看看

Python3爬取有道翻譯的兩種方法_第6張圖片

大功告成。

附使用 urllib 庫(kù)的代碼
?

            
              # -*-coding:utf-8-*-

__Author__ = "Mr.D"
__Date__ = '2019\5\26 0026 18:07'

import urllib.request
import urllib.parse
import json
import time
import random
import hashlib
from faker import Faker


url = 'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'
ua = Faker().user_agent()

key = input("請(qǐng)輸入你需要翻譯的內(nèi)容: ")
ts = str(time.time() * 1000)

salt = ts + str(random.randint(0, 10))
the_str = "fanyideskweb" + key + salt + "@6f#X3=cCuncYssPsuRUE"

md5 = hashlib.md5()
md5.update(the_str.encode('utf-8'))
sign = md5.hexdigest()

# 請(qǐng)求頭
headers = {
    'User-Agent': ua,
    'Host': 'fanyi.youdao.com',
    'Origin': 'http://fanyi.youdao.com',
    'Referer': 'http://fanyi.youdao.com/',
    'Cookie': 'OUTFOX_SEARCH_USER_ID=559238864@10.168.8.61; OUTFOX_SEARCH_USER_ID_NCOO=2061523511.1027195; _ga=GA1.2.1151109878.1551536968; _ntes_nnid=24fe647fc20f952c4040b25650f75604,1553001083850; JSESSIONID=aaaJIa27BLmlI96aStZRw; ___rl__test__cookies=' + ts
}


# 表單數(shù)據(jù)
from_data = {
    'i': key,
    'from': 'UTO',
    'to': 'UTO',
    'smartresult': 'dict',
    'client': 'fanyideskweb',
    'salt': salt,
    'sign': sign,
    'ts': ts,
    'bv': '5504a5c7c19867a06038cf79d29f756a',
    'doctype': 'json',
    'version': '2.1',
    'keyfrom': 'fanyi.web',
    'action': 'FY_BY_REALTlME'
}

from_data = urllib.parse.urlencode(from_data).encode('utf-8')
request = urllib.request.Request(url, from_data, headers)
response = urllib.request.urlopen(request).read().decode("utf-8")

target = json.loads(response)
result = target['translateResult'][0][0]['tgt']

print(result)

            
          

總結(jié)

用到的知識(shí)點(diǎn):

1. faker庫(kù)隨機(jī)生成 ua

2. time()函數(shù)生成時(shí)間戳

3. hashlib庫(kù)進(jìn)行md5加密

4. js基礎(chǔ)知識(shí)的掌握

5. requests庫(kù)的使用

其中,第四點(diǎn)最為重要

?

二.繞過(guò)js加密

代碼這個(gè)方法非常簡(jiǎn)單,只需要將 url 中的 _o 去掉就可以了,在傳遞的from_data中不再需要上述幾個(gè)加密的參數(shù),只需要我們所要翻譯的內(nèi)容 就可以進(jìn)行數(shù)據(jù)獲取了

urllib 庫(kù)的爬取代碼如下

            
              # -*-coding:utf-8-*-

__Author__ = "Mr.D"
__Date__ = '2019\5\26 0026 18:07'

import urllib.request
import urllib.parse
import json
from faker import Faker


// 去掉_o
url = 'http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule'
ua = Faker().user_agent()

key = input("請(qǐng)輸入你需要翻譯的內(nèi)容: ")

# 請(qǐng)求頭
headers = {
    'User-Agent': ua,
    'Host': 'fanyi.youdao.com',
    'Origin': 'http://fanyi.youdao.com',
    'Referer': 'http://fanyi.youdao.com/',

}


# 表單數(shù)據(jù)
from_data = {
    'i': key,
    'from': 'UTO',
    'to': 'UTO',
    'smartresult': 'dict',
    'client': 'fanyideskweb',
    'doctype': 'json',
    'version': '2.1',
    'keyfrom': 'fanyi.web',
    'action': 'FY_BY_REALTlME'
}

from_data = urllib.parse.urlencode(from_data).encode('utf-8')
request = urllib.request.Request(url, from_data, headers)
response = urllib.request.urlopen(request).read().decode("utf-8")

target = json.loads(response)
result = target['translateResult'][0][0]['tgt']

print(result)

            
          

?

在看完上面的代碼之后,可以自己嘗試著寫出使用第二種方法和requests庫(kù)進(jìn)行有道翻譯的爬取,來(lái)驗(yàn)證代碼是否正確

最后,歡迎大家提問(wèn)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 狠狠干狠狠色 | 美女被爆羞羞网站 | 亚洲精品色综合色在线观看 | 日韩毛片在线影视 | 中文日本在线 | 91精品国产91久久久久福利 | 欧美日韩亚洲视频 | 97在线观看免费版 | 中文成人在线 | 亚洲视频一二 | 久久这里一区二区精品 | 日韩欧美高清在线 | 中文字幕免费观看视频 | 成人美女隐私免费 | 国产日韩精品欧美一区色 | 久久久久欧美精品网站 | 午夜情趣视频 | 中文字幕区 | 国产精品高清全国免费观看 | 欧美亚洲国产精品第一页 | 久久精品视频一区二区三区 | 国产色综合久久无码有码 | 免费在线观看黄色小视频 | 福利视频免费看 | 国内外一级毛片 | 久久是精品 | 一级特黄aaa大片免费看 | 午夜男人影院 | 热re99久久精品国产99热 | 凹凸精品视频分类国产品免费 | 站长推荐国产精品视频 | 国产激情视频趣趣在线观看的 | 奇米第| 在线精品国产一区二区 | 99久久免费国产精品 | 性欧美video另类hd亚洲人 | 亚洲国产精品综合欧美 | 国产欧美日韩精品a在线观看高清 | 黄页网站 播放器 日本 | 天天操网 | www.亚洲一区二区三区 |