python 爬蟲(chóng)如何實(shí)現(xiàn)百度翻譯
環(huán)境
python版本號(hào) 系統(tǒng) 游覽器 python 3.7.2 win7 google chrome
關(guān)于本文
本文將會(huì)通過(guò)爬蟲(chóng)的方式實(shí)現(xiàn)簡(jiǎn)單的百度翻譯。本文中的代碼只供學(xué)習(xí),不允許作為于商務(wù)作用。商務(wù)作用請(qǐng)前往api.fanyi.baidu.com購(gòu)買(mǎi)付費(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檢測(cè) token暗號(hào)在網(wǎng)站文件中找到隱藏的免費(fèi)api
進(jìn)入百度翻譯,隨便輸入一段需要翻譯的文字。當(dāng)翻譯結(jié)果出來(lái)的時(shí)候,按下F12,選擇到NETWORK,最后點(diǎn)進(jìn)XHR文件。這個(gè)時(shí)候,網(wǎng)站文件都已經(jīng)加載完了,所以要F5刷新一下。
刷新了之后,我們就能發(fā)現(xiàn)一個(gè)以v2transapi?開(kāi)頭的文件,沒(méi)錯(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 源語(yǔ)言 to 目標(biāo)語(yǔ)言 query 翻譯文本 sign 由js算法生成的簽名(反爬) token 請(qǐng)求暗號(hào)
開(kāi)始寫(xiě)代碼
導(dǎo)入request和execjs庫(kù)
import requestsimport execjs requests HTTP庫(kù),用于爬蟲(chóng) execjs 用于調(diào)用js代碼
反反爬蟲(chóng)
由于百度翻譯有cookie識(shí)別反爬機(jī)制,所以我們?cè)O(shè)置好我們剛剛獲取到的cookie來(lái)進(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)行爬蟲(chóng)嗎?那我們又不會(huì)js代碼,怎么調(diào)用???還好python有著強(qiáng)大的第三方庫(kù),當(dāng)然也少不了調(diào)用js代碼的庫(kù)。調(diào)用js代碼的庫(kù)很多,但是本人還是推薦大家使用execjs,簡(jiǎn)單功能又完整。
在調(diào)用js算法代碼之前,我們還需要讓用戶(hù)輸入一段譯文。
q = input(’翻譯:’)
之后我們就能使用execjs的compile和call方法來(lái)獲取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)過(guò)一系列的反反爬蟲(chóng)準(zhǔn)備,我們就可以設(shè)置好的“源語(yǔ)言”和“目標(biāo)語(yǔ)言”最后的這兩個(gè)參數(shù)了。
From = ’en’To = ’zh’
(以上代碼代表著英譯中,若要進(jìn)行其它語(yǔ)言的翻譯,請(qǐng)輸入語(yǔ)言對(duì)應(yīng)的英文縮寫(xiě),英文縮寫(xiě)對(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)打印出來(lái)的結(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 requestsimport execjsurl = ’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 = ’源語(yǔ)言’To = ’目標(biāo)語(yǔ)言’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)
語(yǔ)言英文縮寫(xiě)對(duì)應(yīng)表
{’zh’: ’中文’,’jp’: ’日語(yǔ)’,’jpka’: ’日語(yǔ)假名’,’th’: ’泰語(yǔ)’,’fra’: ’法語(yǔ)’,’en’: ’英語(yǔ)’,’spa’: ’西班牙語(yǔ)’,’kor’: ’韓語(yǔ)’,’tr’: ’土耳其語(yǔ)’,’vie’: ’越南語(yǔ)’,’ms’: ’馬來(lái)語(yǔ)’,’de’: ’德語(yǔ)’,’ru’: ’俄語(yǔ)’,’ir’: ’伊朗語(yǔ)’,’ara’: ’阿拉伯語(yǔ)’,’est’: ’愛(ài)沙尼亞語(yǔ)’,’be’: ’白俄羅斯語(yǔ)’,’bul’: ’保加利亞語(yǔ)’,’hi’: ’印地語(yǔ)’,’is’: ’冰島語(yǔ)’,’pl’: ’波蘭語(yǔ)’,’fa’: ’波斯語(yǔ)’,’dan’: ’丹麥語(yǔ)’,’tl’: ’菲律賓語(yǔ)’,’fin’: ’芬蘭語(yǔ)’,’nl’: ’荷蘭語(yǔ)’,’ca’: ’加泰羅尼亞語(yǔ)’,’cs’: ’捷克語(yǔ)’,’hr’: ’克羅地亞語(yǔ)’,’lv’: ’拉脫維亞語(yǔ)’,’lt’: ’立陶宛語(yǔ)’,’rom’: ’羅馬尼亞語(yǔ)’,’af’: ’南非語(yǔ)’,’no’: ’挪威語(yǔ)’,’pt_BR’: ’巴西語(yǔ)’,’pt’: ’葡萄牙語(yǔ)’,’swe’: ’瑞典語(yǔ)’,’sr’: ’塞爾維亞語(yǔ)’,’eo’: ’世界語(yǔ)’,’sk’: ’斯洛伐克語(yǔ)’,’slo’: ’斯洛文尼亞語(yǔ)’,’sw’: ’斯瓦希里語(yǔ)’,’uk’: ’烏克蘭語(yǔ)’,’iw’: ’希伯來(lái)語(yǔ)’,’el’: ’希臘語(yǔ)’,’hu’: ’匈牙利語(yǔ)’,’hy’: ’亞美尼亞語(yǔ)’,’it’: ’意大利語(yǔ)’,’id’: ’印尼語(yǔ)’,’sq’: ’阿爾巴尼亞語(yǔ)’,’am’: ’阿姆哈拉語(yǔ)’,’as’: ’阿薩姆語(yǔ)’,’az’: ’阿塞拜疆語(yǔ)’,’eu’: ’巴斯克語(yǔ)’,’bn’: ’孟加拉語(yǔ)’,’bs’: ’波斯尼亞語(yǔ)’,’gl’: ’加利西亞語(yǔ)’,’ka’: ’格魯吉亞語(yǔ)’,’gu’: ’古吉拉特語(yǔ)’,’ha’: ’豪薩語(yǔ)’,’ig’: ’伊博語(yǔ)’,’iu’: ’因紐特語(yǔ)’,’ga’: ’愛(ài)爾蘭語(yǔ)’,’zu’: ’祖魯語(yǔ)’,’kn’: ’卡納達(dá)語(yǔ)’,’kk’: ’哈薩克語(yǔ)’,’ky’: ’吉爾吉斯語(yǔ)’,’lb’: ’盧森堡語(yǔ)’,’mk’: ’馬其頓語(yǔ)’,’mt’: ’馬耳他語(yǔ)’,’mi’: ’毛利語(yǔ)’,’mr’: ’馬拉提語(yǔ)’,’ne’: ’尼泊爾語(yǔ)’,’or’: ’奧利亞語(yǔ)’,’pa’: ’旁遮普語(yǔ)’,’qu’: ’凱楚亞語(yǔ)’,’tn’: ’塞茨瓦納語(yǔ)’,’si’: ’僧加羅語(yǔ)’,’ta’: ’泰米爾語(yǔ)’,’tt’: ’塔塔爾語(yǔ)’,’te’: ’泰盧固語(yǔ)’,’ur’: ’烏爾都語(yǔ)’,’uz’: ’烏茲別克語(yǔ)’,’cy’: ’威爾士語(yǔ)’,’yo’: ’約魯巴語(yǔ)’,’yue’: ’粵語(yǔ)’,’wyw’: ’文言文’,’cht’: ’中文繁體’ }
以上就是python 爬蟲(chóng)如何實(shí)現(xiàn)百度翻譯的詳細(xì)內(nèi)容,更多關(guān)于python 爬蟲(chóng)實(shí)現(xiàn)百度翻譯的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!
相關(guān)文章:
1. Java8內(nèi)存模型PermGen Metaspace實(shí)例解析2. python excel和yaml文件的讀取封裝3. python如何實(shí)現(xiàn)word批量轉(zhuǎn)HTML4. python3實(shí)現(xiàn)往mysql中插入datetime類(lèi)型的數(shù)據(jù)5. python爬蟲(chóng)實(shí)戰(zhàn)之制作屬于自己的一個(gè)IP代理模塊6. moment轉(zhuǎn)化時(shí)間戳出現(xiàn)Invalid Date的問(wèn)題及解決7. Python中內(nèi)建模塊collections如何使用8. 詳解docker pull 下來(lái)的鏡像都存到了哪里9. 關(guān)于 Android WebView 的內(nèi)存泄露問(wèn)題10. Docker鏡像管理常用操作代碼示例
