破解google翻譯API全過程


  ◆版權聲明:本文出自胖喵~的博客,轉載必須注明出處。

  轉載請注明出處:http://www.cnblogs.com/by-dream/p/6554340.html 

 

 

前言


  google的翻譯不得不承認它是比較好的。但是google翻譯對外提供的翻譯接口都是收錢的,做為一名普普通通的開發者,囊中羞澀,因此就需要借助技術的力量來完成免費的翻譯接口的調用。

 

 

git


  首先在github上我們找到了這篇鏈接 https://github.com/ssut/py-googletrans

  

  看介紹免費、無限制,這剛好適合我們來用。於是按照它的操作步驟我們來試試:

  由於它是python的,因此第一步是去下載它的python庫,由於我沒有配置python pip的環境變量,因此我手動進入這個目錄下:

  

  然后運行 pip install googletrans 這個命令,去下載提供的這個庫。

  

  這個時候出錯,提示我們沒有requests庫,因此我們還需要在安裝requests庫。果然文檔里也有些

  

 

  因此我們就安裝把

  

  安裝完后再安裝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官方提供的,並且有的時候這個庫也是不穩定的,因為我決定自己去趟一下這趟渾水。

 

 

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

  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()
getTKKjs.py
#-*- 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()
http.py

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM