赞
踩
pip install requests
#安装googletrans,需要安装requests依赖
pip install googletrans
#-*- coding:utf-8 -*- from googletrans import Translator ''' ZH, // 中文 "zh-CN" EN, // 英语 "en" JP, // 日语 "ja" JPKA, // 日语假名 TH, // 泰语 FRA, // 法语 "fr" SPA, // 西班牙语 "es" <--- 添加语种(自定义语种代号) KOR, // 韩语 "ko" ''' # 设置Google翻译服务地址 # translator = Translator(service_urls=[ # 'translate.google.cn' # ]) translator = Translator() print(translator.translate('今天天气不错',dest='en', src='auto').text) print(translator.translate('hello', dest='zh-CN').text) print(translator.translate('今天天气不错', dest='ja').text) print(translator.translate('今天天气不错', dest='ko').text) print(translator.translate('今天天气不错', dest='es').text) print(translator.translate('今天天气不错', dest='fr').text)
首先在github上我们找到了这篇链接 https://github.com/ssut/py-googletrans
然后运行 pip install googletrans
这个命令,去下载提供的这个库。
这个时候出错,提示我们没有requests库,因此我们还需要在安装requests库。果然文档里也有些
这个时候我们调用它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来进行请求了。
这里我用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()
另外一个翻译的项目:https://github.com/IAMABOY/GoogleFreeTrans.git
需要安装几个软件包,如下
pip install pytest;
pip install flake8;
pip install coverage;
pip install PyExecJS
# -*- coding:utf-8 -*- import requests, execjs, json, sys,time,re from GoogleTrans.CalcTk import CalcTk class translator(): headers = { 'Host': 'translate.google.cn', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3', 'Accept-Encoding': 'gzip, deflate, br', 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8', 'Referer': 'https://translate.google.cn/', 'Connection': 'keep-alive', 'Cache-Control': 'max-age=0' } support_lauguage = { 'afrikaans': 'af', 'arabic': 'ar', 'belarusian': 'be', 'bulgarian': 'bg', 'catalan': 'ca', 'czech': 'cs', 'welsh': 'cy', 'danish': 'da', 'german': 'de', 'greek': 'el', 'english': 'en', 'esperanto': 'eo', 'spanish': 'es', 'estonian': 'et', 'persian': 'fa', 'finnish': 'fi', 'french': 'fr', 'irish': 'ga', 'galician': 'gl', 'hindi': 'hi', 'croatian': 'hr', 'hungarian': 'hu', 'indonesian': 'id', 'icelandic': 'is', 'italian': 'it', 'hebrew': 'iw', 'japanese': 'ja', 'korean': 'ko', 'latin': 'la', 'lithuanian': 'lt', 'latvian': 'lv', 'macedonian': 'mk', 'malay': 'ms', 'maltese': 'mt', 'dutch': 'nl', 'norwegian': 'no', 'polish': 'pl', 'portuguese': 'pt', 'romanian': 'ro', 'russian': 'ru', 'slovak': 'sk', 'slovenian': 'sl', 'albanian': 'sq', 'serbian': 'sr', 'swedish': 'sv', 'swahili': 'sw', 'thai': 'th', 'filipino': 'tl', 'turkish': 'tr', 'ukrainian': 'uk', 'vietnamese': 'vi', 'yiddish': 'yi', 'chinese_simplified': 'zh-CN', 'chinese_traditional': 'zh-TW', 'auto': 'auto', } def __init__(self, src='en', dest='fr', updata_time=600): if src not in self.support_lauguage and src not in self.support_lauguage.values(): raise ValueError('source language not support') if dest not in self.support_lauguage and dest not in self.support_lauguage.values(): raise ValueError('destination language not support') self.url = 'https://translate.google.cn/translate_a/single' self.params = { 'client': 't',#webapp t 'sl': src, 'tl': dest, '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', 'source': 'bh', 'ssel': '0', 'tsel': '0', 'kc': '1', 'tk': '376032.257956' } self.updata_time = updata_time self.__updata_tk() def __updata_tk(self): self.__TK = CalcTk() self.__next_up_time = time.time() + self.updata_time def __get_res(self, data): try: res = requests.post(self.url,headers=self.headers,data=data,params=self.params,timeout=6) res.raise_for_status() except Exception as e: print('class translator __get_res [-]ERROR: ' + str(e)) res = '' return res def translate(self, text, multi=False): if time.time() > self.__next_up_time: self.__updata_tk() data = {'q': text} self.params['tk'] = self.__TK.get_tk(text) # 设置最大请求次数为三次,减少因为超时的失败情况 for count in range(0,3): res = self.__get_res(data) if res !='': break if res=='': return res retrunString = '' for item in res.json()[0]: retrunString = retrunString + item[0]#返回的json中按照句子断句翻译,需要进行拼接 return retrunString #ret_list = json.loads(res.text) #return ret_list[0][0][0] if __name__=='__main__': cn = '''您好''' en = ''' 中国 ''' trans = translator(src='zh-CN', dest='en') out = trans.translate(en) print(out)
# -*- coding:utf-8 -*- import requests,re,execjs,time class CalcTk(): def __init__(self): self.tkk = self.get_tkk() #从服务器获取TKK self.ctx = execjs.compile( """ function b(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 } function tk(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) } """ ) # 从服务器获取TKK def get_tkk(self): url = 'https://translate.google.cn/' headers = { 'accept': '*/*', 'accept-encoding': 'gzip, deflate, br', 'accept-language': 'zh-CN,zh;q=0.9', 'referer': 'https//translate.google.cn/', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36', } retry = 3 time_interval = 1 while retry > 0: try: time.sleep(time_interval) response = requests.get(url, headers=headers, timeout=1.5) # result.raise_for_status() # result.encoding = 'utf-8' tkk = re.search(r'tkk\:\'(\d+\.\d+)?\'', response.text).group(1) return tkk except Exception as e: print('function get_tkk [-]ERROR: ' + str(e)) time.sleep(time_interval) time_interval += 1 retry -= 1 return 0.0 def get_tk(self, text): try: return self.ctx.call('tk', text, self.tkk) except Exception as ex: print('class CalcTk function get_tk [-]ERROR: ' + str(ex)) return 0.0
参考:https://www.cnblogs.com/by-dream/p/6554340.html
https://blog.csdn.net/javajiawei/article/details/91456488
https://www.cnblogs.com/sen-c7/p/10070306.html
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。