python 爬蟲如何實(shí)現(xiàn)百度翻譯
環(huán)境
python版本號(hào) | 系統(tǒng) | 游覽器 |
---|---|---|
python 3.7.2 | win7 | google chrome |
關(guān)于本文
本文將會(huì)通過爬蟲的方式實(shí)現(xiàn)簡單的百度翻譯。本文中的代碼只供學(xué)習(xí),不允許作為于商務(wù)作用。商務(wù)作用請(qǐng)前往api.fanyi.baidu.com購買付費(fèi)的api。若有侵犯,立即刪文!
實(shí)現(xiàn)思路
在網(wǎng)站文件中找到隱藏的免費(fèi)api。傳入api所需要的參數(shù)并對(duì)其發(fā)出請(qǐng)求。在返回的json結(jié)果里找到相應(yīng)的翻譯結(jié)果。
百度翻譯的反爬機(jī)制
- 由js算法生成的sign
- cookie檢測
- token暗號(hào)
在網(wǎng)站文件中找到隱藏的免費(fèi)api
進(jìn)入百度翻譯,隨便輸入一段需要翻譯的文字。當(dāng)翻譯結(jié)果出來的時(shí)候,按下F12,選擇到NETWORK,最后點(diǎn)進(jìn)XHR文件。這個(gè)時(shí)候,網(wǎng)站文件都已經(jīng)加載完了,所以要F5刷新一下。
刷新了之后,我們就能發(fā)現(xiàn)一個(gè)以v2transapi?開頭的文件,沒錯(cuò),它就是我們要找的api接口。讓我們驗(yàn)證一下,點(diǎn)進(jìn)去文件-preview,我們就可以在json格式的數(shù)據(jù)里面找到翻譯結(jié)果,驗(yàn)證成功。
另外,我們還需要獲取我們的cookie和token,在之后的反爬機(jī)制中我們需要用到它們,位置如以下。
cookie位置:
token位置:
api信息
接口:https://fanyi.baidu.com/v2tra...
請(qǐng)求方式:post
請(qǐng)求參數(shù)大全
參數(shù) | 介紹 |
---|---|
from | 源語言 |
to | 目標(biāo)語言 |
query | 翻譯文本 |
sign | 由js算法生成的簽名(反爬) |
token | 請(qǐng)求暗號(hào) |
開始寫代碼
導(dǎo)入request和execjs庫
import requests import execjs
- requests HTTP庫,用于爬蟲
- execjs 用于調(diào)用js代碼
反反爬蟲
由于百度翻譯有cookie識(shí)別反爬機(jī)制,所以我們設(shè)置好我們剛剛獲取到的cookie來進(jìn)行掩護(hù)網(wǎng)絡(luò)蜘蛛身份。
headers = {'cookie':'請(qǐng)?jiān)谶@里輸入你的cookie'}
另外,我們還要設(shè)置好token(暗號(hào))。
token = '請(qǐng)?jiān)谶@里放置你的token'
最后只剩下sign反爬機(jī)制了,sign是由js算法給譯文生成的一個(gè)簽名。我在網(wǎng)上搜了一下,找到了相應(yīng)的js算法,分享給大家。
var i = "320305.131321201" function n(r, o) { for (var t = 0; t < o.length - 2; t += 3) { var a = o.charAt(t + 2); a = a >= "a" ? a.charCodeAt(0) - 87 : Number(a), a = "+" === o.charAt(t + 1) ? r >>> a : r << a, r = "+" === o.charAt(t) ? r + a & 4294967295 : r ^ a } return r } function e(r) { var o = r.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g); if (null === o) { var t = r.length; t > 30 && (r = "" + r.substr(0, 10) + r.substr(Math.floor(t / 2) - 5, 10) + r.substr(-10, 10)) } else { for (var e = r.split(/[\uD800-\uDBFF][\uDC00-\uDFFF]/), C = 0, h = e.length, f = []; h > C; C++) "" !== e[C] && f.push.apply(f, a(e[C].split(""))), C !== h - 1 && f.push(o[C]); var g = f.length; g > 30 && (r = f.slice(0, 10).join("") + f.slice(Math.floor(g / 2) - 5, Math.floor(g / 2) + 5).join("") + f.slice(-10).join("")) } var u = void 0, l = "" + String.fromCharCode(103) + String.fromCharCode(116) + String.fromCharCode(107); u = null !== i ? i : (i = window[l] || "") || ""; for (var d = u.split("."), m = Number(d[0]) || 0, s = Number(d[1]) || 0, S = [], c = 0, v = 0; v < r.length; v++) { var A = r.charCodeAt(v); 128 > A ? S[c++] = A : (2048 > A ? S[c++] = A >> 6 | 192 : (55296 === (64512 & A) && v + 1 < r.length && 56320 === (64512 & r.charCodeAt(v + 1)) ? (A = 65536 + ((1023 & A) << 10) + (1023 & r.charCodeAt(++v)), S[c++] = A >> 18 | 240, S[c++] = A >> 12 & 63 | 128) : S[c++] = A >> 12 | 224, S[c++] = A >> 6 & 63 | 128), S[c++] = 63 & A | 128) } for (var p = m, F = "" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(97) + ("" + String.fromCharCode(94) + String.fromCharCode(43) + String.fromCharCode(54)), D = "" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(51) + ("" + String.fromCharCode(94) + String.fromCharCode(43) + String.fromCharCode(98)) + ("" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(102)), b = 0; b < S.length; b++) p += S[b], p = n(p, F); return p = n(p, D), p ^= s, 0 > p && (p = (2147483647 & p) + 2147483648), p %= 1e6, p.toString() + "." + (p ^ m) }
等等,我們不是在用python進(jìn)行爬蟲嗎?那我們又不會(huì)js代碼,怎么調(diào)用???
還好python有著強(qiáng)大的第三方庫,當(dāng)然也少不了調(diào)用js代碼的庫。調(diào)用js代碼的庫很多,但是本人還是推薦大家使用execjs,簡單功能又完整。
在調(diào)用js算法代碼之前,我們還需要讓用戶輸入一段譯文。
q = input('翻譯:')
之后我們就能使用execjs的compile和call方法來獲取sign了。
js = '''var i = "320305.131321201" function n(r, o) { for (var t = 0; t < o.length - 2; t += 3) { var a = o.charAt(t + 2); a = a >= "a" ? a.charCodeAt(0) - 87 : Number(a), a = "+" === o.charAt(t + 1) ? r >>> a : r << a, r = "+" === o.charAt(t) ? r + a & 4294967295 : r ^ a } return r } function e(r) { var o = r.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g); if (null === o) { var t = r.length; t > 30 && (r = "" + r.substr(0, 10) + r.substr(Math.floor(t / 2) - 5, 10) + r.substr(-10, 10)) } else { for (var e = r.split(/[\uD800-\uDBFF][\uDC00-\uDFFF]/), C = 0, h = e.length, f = []; h > C; C++) "" !== e[C] && f.push.apply(f, a(e[C].split(""))), C !== h - 1 && f.push(o[C]); var g = f.length; g > 30 && (r = f.slice(0, 10).join("") + f.slice(Math.floor(g / 2) - 5, Math.floor(g / 2) + 5).join("") + f.slice(-10).join("")) } var u = void 0, l = "" + String.fromCharCode(103) + String.fromCharCode(116) + String.fromCharCode(107); u = null !== i ? i : (i = window[l] || "") || ""; for (var d = u.split("."), m = Number(d[0]) || 0, s = Number(d[1]) || 0, S = [], c = 0, v = 0; v < r.length; v++) { var A = r.charCodeAt(v); 128 > A ? S[c++] = A : (2048 > A ? S[c++] = A >> 6 | 192 : (55296 === (64512 & A) && v + 1 < r.length && 56320 === (64512 & r.charCodeAt(v + 1)) ? (A = 65536 + ((1023 & A) << 10) + (1023 & r.charCodeAt(++v)), S[c++] = A >> 18 | 240, S[c++] = A >> 12 & 63 | 128) : S[c++] = A >> 12 | 224, S[c++] = A >> 6 & 63 | 128), S[c++] = 63 & A | 128) } for (var p = m, F = "" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(97) + ("" + String.fromCharCode(94) + String.fromCharCode(43) + String.fromCharCode(54)), D = "" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(51) + ("" + String.fromCharCode(94) + String.fromCharCode(43) + String.fromCharCode(98)) + ("" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(102)), b = 0; b < S.length; b++) p += S[b], p = n(p, F); return p = n(p, D), p ^= s, 0 > p && (p = (2147483647 & p) + 2147483648), p %= 1e6, p.toString() + "." + (p ^ m) } ''' sign = execjs.compile(js).call("e",q)
(以上代碼獲取了sign)
經(jīng)過一系列的反反爬蟲準(zhǔn)備,我們就可以設(shè)置好的“源語言”和“目標(biāo)語言”最后的這兩個(gè)參數(shù)了。
From = 'en' To = 'zh'
(以上代碼代表著英譯中,若要進(jìn)行其它語言的翻譯,請(qǐng)輸入語言對(duì)應(yīng)的英文縮寫,英文縮寫對(duì)應(yīng)表將會(huì)放到本文最后)
接著,我們就能構(gòu)建參數(shù)json了。
data = {'from':From, 'to':To, 'query':q, 'sign':sign, 'token':'14b5f31e3c65d89a0b1c3f756e53942e'}
最后,我們就能請(qǐng)求數(shù)據(jù)并打印了。
text = requests.post(url,headers=headers,data=data).json() print(text)
我們發(fā)現(xiàn)打印出來的結(jié)果是個(gè)json字典,翻譯結(jié)果就在其中,我們只需要翻譯結(jié)果,所以我們可以索引翻譯結(jié)果的位置再打印。
text = requests.post(url,headers=headers,data=data).json()['trans_result']['data'][0]['dst'] print(text)
運(yùn)行結(jié)果:
完整代碼:
import requests import execjs url = 'https://fanyi.baidu.com/v2transapi' headers = {'cookie':'你的cookie'} js = '''var i = "320305.131321201" function n(r, o) { for (var t = 0; t < o.length - 2; t += 3) { var a = o.charAt(t + 2); a = a >= "a" ? a.charCodeAt(0) - 87 : Number(a), a = "+" === o.charAt(t + 1) ? r >>> a : r << a, r = "+" === o.charAt(t) ? r + a & 4294967295 : r ^ a } return r } function e(r) { var o = r.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g); if (null === o) { var t = r.length; t > 30 && (r = "" + r.substr(0, 10) + r.substr(Math.floor(t / 2) - 5, 10) + r.substr(-10, 10)) } else { for (var e = r.split(/[\uD800-\uDBFF][\uDC00-\uDFFF]/), C = 0, h = e.length, f = []; h > C; C++) "" !== e[C] && f.push.apply(f, a(e[C].split(""))), C !== h - 1 && f.push(o[C]); var g = f.length; g > 30 && (r = f.slice(0, 10).join("") + f.slice(Math.floor(g / 2) - 5, Math.floor(g / 2) + 5).join("") + f.slice(-10).join("")) } var u = void 0, l = "" + String.fromCharCode(103) + String.fromCharCode(116) + String.fromCharCode(107); u = null !== i ? i : (i = window[l] || "") || ""; for (var d = u.split("."), m = Number(d[0]) || 0, s = Number(d[1]) || 0, S = [], c = 0, v = 0; v < r.length; v++) { var A = r.charCodeAt(v); 128 > A ? S[c++] = A : (2048 > A ? S[c++] = A >> 6 | 192 : (55296 === (64512 & A) && v + 1 < r.length && 56320 === (64512 & r.charCodeAt(v + 1)) ? (A = 65536 + ((1023 & A) << 10) + (1023 & r.charCodeAt(++v)), S[c++] = A >> 18 | 240, S[c++] = A >> 12 & 63 | 128) : S[c++] = A >> 12 | 224, S[c++] = A >> 6 & 63 | 128), S[c++] = 63 & A | 128) } for (var p = m, F = "" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(97) + ("" + String.fromCharCode(94) + String.fromCharCode(43) + String.fromCharCode(54)), D = "" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(51) + ("" + String.fromCharCode(94) + String.fromCharCode(43) + String.fromCharCode(98)) + ("" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(102)), b = 0; b < S.length; b++) p += S[b], p = n(p, F); return p = n(p, D), p ^= s, 0 > p && (p = (2147483647 & p) + 2147483648), p %= 1e6, p.toString() + "." + (p ^ m) } ''' From = '源語言' To = '目標(biāo)語言' token = '你的token' q = input('翻譯:') sign = execjs.compile(js).call("e",q) data = {'from':From, 'to':To, 'query':q, 'sign':sign, 'token':token} text = requests.post(url,headers=headers,data=data).json()['trans_result']['data'][0]['dst'] print(text)
語言英文縮寫對(duì)應(yīng)表
{ 'zh': '中文','jp': '日語','jpka': '日語假名','th': '泰語','fra': '法語','en': '英語','spa': '西班牙語','kor': '韓語','tr': '土耳其語','vie': '越南語','ms': '馬來語','de': '德語','ru': '俄語','ir': '伊朗語','ara': '阿拉伯語','est': '愛沙尼亞語','be': '白俄羅斯語','bul': '保加利亞語','hi': '印地語','is': '冰島語','pl': '波蘭語','fa': '波斯語','dan': '丹麥語','tl': '菲律賓語','fin': '芬蘭語','nl': '荷蘭語','ca': '加泰羅尼亞語','cs': '捷克語','hr': '克羅地亞語','lv': '拉脫維亞語','lt': '立陶宛語','rom': '羅馬尼亞語','af': '南非語','no': '挪威語','pt_BR': '巴西語','pt': '葡萄牙語','swe': '瑞典語','sr': '塞爾維亞語','eo': '世界語','sk': '斯洛伐克語','slo': '斯洛文尼亞語','sw': '斯瓦希里語','uk': '烏克蘭語','iw': '希伯來語','el': '希臘語','hu': '匈牙利語','hy': '亞美尼亞語','it': '意大利語','id': '印尼語','sq': '阿爾巴尼亞語','am': '阿姆哈拉語','as': '阿薩姆語','az': '阿塞拜疆語','eu': '巴斯克語','bn': '孟加拉語','bs': '波斯尼亞語','gl': '加利西亞語','ka': '格魯吉亞語','gu': '古吉拉特語','ha': '豪薩語','ig': '伊博語','iu': '因紐特語','ga': '愛爾蘭語','zu': '祖魯語','kn': '卡納達(dá)語','kk': '哈薩克語','ky': '吉爾吉斯語','lb': '盧森堡語','mk': '馬其頓語','mt': '馬耳他語','mi': '毛利語','mr': '馬拉提語','ne': '尼泊爾語','or': '奧利亞語','pa': '旁遮普語','qu': '凱楚亞語','tn': '塞茨瓦納語','si': '僧加羅語','ta': '泰米爾語','tt': '塔塔爾語','te': '泰盧固語','ur': '烏爾都語','uz': '烏茲別克語','cy': '威爾士語','yo': '約魯巴語','yue': '粵語','wyw': '文言文','cht': '中文繁體' }
以上就是python 爬蟲如何實(shí)現(xiàn)百度翻譯的詳細(xì)內(nèi)容,更多關(guān)于python 爬蟲實(shí)現(xiàn)百度翻譯的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
PyQt5實(shí)現(xiàn)數(shù)據(jù)的增刪改查功能詳解
這篇文章主要為大家介紹了如何使用Python中的PyQt5模塊來實(shí)現(xiàn)數(shù)據(jù)的增、刪、改、查功能,文中示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2022-03-03Python實(shí)戰(zhàn)小游戲飛機(jī)大戰(zhàn)詳解
飛機(jī)大戰(zhàn)想必是很多人童年時(shí)期的經(jīng)典游戲,我們依舊能記得抱個(gè)老人機(jī)娛樂的場景,下面這篇文章主要給大家介紹了關(guān)于如何利用python寫一個(gè)簡單的飛機(jī)大戰(zhàn)小游戲的相關(guān)資料,需要的朋友可以參考下2021-11-11Python數(shù)據(jù)可視化繪圖實(shí)例詳解
數(shù)據(jù)可視化是指用圖形或表格的方式來呈現(xiàn)數(shù)據(jù)。圖表能夠清楚地呈現(xiàn)數(shù)據(jù)性質(zhì), 以及數(shù)據(jù)間或?qū)傩蚤g的關(guān)系。本文為大家分享了幾個(gè)Python數(shù)據(jù)可視化繪圖的實(shí)例,感興趣的可以了解一下2022-05-05聊聊Pytorch torch.cat與torch.stack的區(qū)別
這篇文章主要介紹了Pytorch torch.cat與torch.stack的區(qū)別說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-05-05利用python腳本提取Abaqus場輸出數(shù)據(jù)的代碼
這篇文章主要介紹了利用python腳本提取Abaqus場輸出數(shù)據(jù),利用python腳本對(duì)Abaqus進(jìn)行數(shù)據(jù)提取時(shí),要對(duì)python腳本做前步的導(dǎo)入處理,本文通過實(shí)例代碼詳細(xì)講解需要的朋友可以參考下2022-11-11