◆版權聲明:本文出自胖喵~的博客,轉載必須註明出處。html
轉載請註明出處:http://www.cnblogs.com/by-dream/p/6554340.html node
前言python
google的翻譯不得不認可它是比較好的。可是google翻譯對外提供的翻譯接口都是收錢的,作爲一名普普統統的開發者,囊中羞澀,所以就須要藉助技術的力量來完成免費的翻譯接口的調用。git
gitgithub
首先在github上咱們找到了這篇連接 https://github.com/ssut/py-googletransweb
看介紹免費、無限制,這恰好適合咱們來用。因而按照它的操做步驟咱們來試試:瀏覽器
因爲它是python的,所以第一步是去下載它的python庫,因爲我沒有配置python pip的環境變量,所以我手動進入這個目錄下:ide
而後運行 pip install googletrans 這個命令,去下載提供的這個庫。函數
這個時候出錯,提示咱們沒有requests庫,所以咱們還須要在安裝requests庫。果真文檔裏也有些ui
所以咱們就安裝把
安裝完後再安裝googletrans 就能夠了:
這個時候咱們調用它API提供的方法試試,代碼以下:
#-*- coding:utf-8 -*- from googletrans import Translator import sys reload(sys) sys.setdefaultencoding( "utf-8" ) translator = Translator() print translator.translate('今每天氣不錯').text print translator.translate('今每天氣不錯', dest='ja').text print translator.translate('今每天氣不錯', dest='ko').text
這個時候就能夠看到輸出結果:
the weather is nice today
今日天気がいいです
오늘 날씨가 좋은
一個簡單的翻譯demo就實現了。是否是很是的簡單
然而,這個庫並非google官方提供的,而且有的時候這個庫也是不穩定的,由於我決定本身去趟一下這趟渾水。
第一步固然是抓取它的請求,看看它是怎麼請求的。按下F12進入瀏覽器調試模式,眼睛盯緊network:
接着咱們輸入一句話,看看它會產生什麼消息包。
竟然有這麼多的消息包,咱們一個一個找,直到找到Response中有翻譯內容的。這個時候咱們去看一下它的header:
能夠看到是get方式,因而咱們能夠瀏覽器裏直接去請求這個url。
果真咱們的獲得了一個文件,這個時候打開文件,文件裏就是請求回來的翻譯結果:
這時候咱們去分析一下請求的參數,看看咱們是否能夠構造,能夠看到原來要翻譯的文本,就是跟着q這個參數出去的:
只不過在請求的時候,文字被encode成了%**%**,這時候咱們試着換一個文字去請求,結果發現返回:
仔細上網查過以後,每次翻譯的文字不一樣,參數中的tk值就會不一樣,ticket這種策略就是google用來防爬蟲的。
tk和文字以及TKK有關,TKK也是實時變化的,具體怎麼拿到是在 translate.google.cn 這個網頁源代碼中有一段js代碼:
咱們直接運行這段js,會獲得一個值,這個值就是 TKK值:
那麼如何根據TKK和文本算出tk值呢,網上有大神已經實現了js的代碼,直接拿過來用了:
var b = function (a, b) { for (var d = 0; d < b.length - 2; d += 3) { var c = b.charAt(d + 2), c = "a" <= c ? c.charCodeAt(0) - 87 : Number(c), c = "+" == b.charAt(d + 1) ? a >>> c : a << c; a = "+" == b.charAt(d) ? a + c & 4294967295 : a ^ c } return a } var tk = function (a,TKK) { for (var e = TKK.split("."), h = Number(e[0]) || 0, g = [], d = 0, f = 0; f < a.length; f++) { var c = a.charCodeAt(f); 128 > c ? g[d++] = c : (2048 > c ? g[d++] = c >> 6 | 192 : (55296 == (c & 64512) && f + 1 < a.length && 56320 == (a.charCodeAt(f + 1) & 64512) ? (c = 65536 + ((c & 1023) << 10) + (a.charCodeAt(++f) & 1023), g[d++] = c >> 18 | 240, g[d++] = c >> 12 & 63 | 128) : g[d++] = c >> 12 | 224, g[d++] = c >> 6 & 63 | 128), g[d++] = c & 63 | 128) } a = h; for (d = 0; d < g.length; d++) a += g[d], a = b(a, "+-a^+6"); a = b(a, "+-3^+b+-f"); a ^= Number(e[1]) || 0; 0 > a && (a = (a & 2147483647) + 2147483648); a %= 1E6; return a.toString() + "." + (a ^ h) }
這段代碼只須要直接調用 tk這個函數就能夠獲得tk值,獲得tk值以後,咱們就能夠拼接出url來進行請求了。
Demo
這裏我用Python和node一塊兒完成了一個小的demo,你們能夠下載個人代碼。我簡單介紹一下腳本的原理。
首先入口是用node完成的:
// 導入translate var trans= require('./translate.js'); // 調用翻譯結果 trans.gettrans('你好')
直接調用了 translate.js,咱們看看這個文件:
// 獲得TKK var exec = require('child_process').exec; var cmdStr = 'getTKK.py'; exec(cmdStr, function(err,stdout,stderr){ if(err) { console.log('get TKK is error' + stderr); } else { //console.log(stdout); } }); // 讀取TKK var rf=require("fs"); var tkk=rf.readFileSync("TKK","utf-8"); //console.log(tkk); var gettrans=function(text){ var gettk= require('./gettk.js') res=gettk.tk(text, tkk.toString()) //console.log(res) var testenc = encodeURI(text) //console.log(encodeURI(text)) var exec2 = require('child_process').exec; var cmdStr2 = 'http.py '+testenc+' '+res+' '; //console.log('http.py '+testenc+' '+res) exec2(cmdStr2, function(err,stdout,stderr){ if(err) { //console.log('http is error' + stderr); } else { // 最終的結果 console.log(stdout); } }); } module.exports.gettrans=gettrans;
translate.js 當中融合了比較多的內容,首先是調用Python的getTKK.py。
#-*- coding:utf-8 -*- import os # 爬取網頁拿到TKK的js代碼 os.system('getTKKjs.py > getTKK.js') # 執行TKKjs代碼拿到TKK值 os.system('node getTKK.js > TKK')
咱們能夠看到原理很簡單,先調用 getTKKjs.py 利用爬蟲先將剛纔咱們分析的那段網頁代碼給爬取下來,而後生成js文件,接着調用這個js文件,將結果寫入到本地一個文件TKK當中。緊接着translate.js讀取了TKK值以後,調用咱們前面提到的那段node的接口,就能夠獲得tk值了,這個時候再調用http.py送給Python進行請求,將結果回傳給node。
#-*- coding:utf-8 -*- import urllib2 from bs4 import BeautifulSoup # 要爬取的總url weburl='http://translate.google.cn/' class Climbing(): # 設置代理開關 enable_proxy = False # 總url url = '' # 初始化 def __init__(self, url): self.url = url proxy_handler = urllib2.ProxyHandler({"http" : 'web-proxy.oa.com:8080'}) null_proxy_handler = urllib2.ProxyHandler({}) if self.enable_proxy: opener = urllib2.build_opener(proxy_handler) else: opener = urllib2.build_opener(null_proxy_handler) urllib2.install_opener(opener) # 根據url,獲得請求返回內容的soup對象 def __getResponseSoup(self, url): request = urllib2.Request(url) request.add_header('User-Agent', "Mozilla/5.0") #request.add_header('Accept-Language', 'zh-ch,zh;q=0.5') response = urllib2.urlopen(request) resault = response.read() soup = BeautifulSoup(resault, "html.parser") return soup # 爬取TKK def getTKK(self): soup = self.__getResponseSoup(self.url) allinfo = soup.find_all('script') for info in allinfo: chinese = info.get_text().encode('utf-8') #print chinese if chinese.find("TKK") > 0: #print chinese res = chinese.split("TKK")[1] res = res.split(");")[0] print "TKK"+res+");" print "console.log(TKK);" c = Climbing(weburl) c.getTKK()
#-*- coding:utf-8 -*- import time import urllib2 import urllib from sys import argv script,zh,tk = argv url='http://translate.google.cn/translate_a/single?client=t&sl=zh-CN&tl=en&hl=zh-CN&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t&ie=UTF-8&oe=UTF-8&pc=1&otf=1&ssel=6&tsel=3&kc=0&tk='+ tk +'&q=' + zh def getRes(): #print 'chinese is :'+urllib.unquote(first) null_proxy_handler = urllib2.ProxyHandler({}) opener = urllib2.build_opener(null_proxy_handler) urllib2.install_opener(opener) req = urllib2.Request(url) req.add_header('User-Agent', "Mozilla/5.0") response = urllib2.urlopen(req) print response.read() print getRes()