目录
概述
爬取谷歌翻译,根据提供的文字进行翻译。
准备
所需模块
- urllib.request
- execjs:执行JS代码的模块
涉及知识点
- python基础
- urllib模块基础
运行效果
控制台打印:
完成爬虫
1. 分析网页
打开谷歌翻译,按F12查看网页
把URL复制到代码中,
import urllib.request
url="https://translate.google.cn/translate_a/single?client=webapp&sl=en&tl=zh-CN&hl=zh-CN&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t&source=bh&ssel=0&tsel=0&kc=1&tk=459678.110220" \
"&q=hello"
# 请求头
header = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36",
}
# 获取request对象
req = urllib.request.Request(url, headers=header)
# 响应的数据是通过Ajax返回的JSON格式数据,注意编码问题
resp = urllib.request.urlopen(req).read().decode("utf-8")
# 打印
print(resp)
运行程序:
现在换个单词试试,比如说word
再次去谷歌翻译,查看URL
比较下两者的URL:
# 失败URL:url="https://translate.google.cn/translate_a/single?client=webapp&sl=en&tl=zh-CN&hl=zh-CN&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t&source=bh&ssel=0&tsel=0&kc=1&tk=459678.110220&q=word"
# 成功URL:url="https://translate.google.cn/translate_a/single?client=webapp&sl=en&tl=zh-CN&hl=zh-CN&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t&otf=1&ssel=0&tsel=0&kc=1&tk=892279.733285&q=word"
比较了发现其中的tk值是在变化的,不是同一个tk参数值。
注意了参数tk是根据JavaScript代码计算出来的,不同的翻译内容,计算的值不一样。
在网上查找了下,发现有大神已经把提取该tk值的算法分享出来了,其GitHub地址为:
https://github.com/cocoa520/Google_TK
可以在这个地址https://github.com/cocoa520/Google_TK/blob/master/google_tk.htmlJavaScript代码
因此计算tk值的python代码为:
import execjs
class Py4Js():
def __init__(self):
self.ctx = execjs.compile("""
function TL(a) {
var k = "";
var b = 406644;
var b1 = 3293161072;
var jd = ".";
var $b = "+-a^+6";
var Zb = "+-3^+b+-f";
for (var e = [], f = 0, g = 0; g < a.length; g++) {
var m = a.charCodeAt(g);
128 > m ? e[f++] = m : (2048 > m ? e[f++] = m >> 6 | 192 : (55296 == (m & 64512) && g + 1 < a.length && 56320 == (a.charCodeAt(g + 1) & 64512) ? (m = 65536 + ((m & 1023) << 10) + (a.charCodeAt(++g) & 1023),
e[f++] = m >> 18 | 240,
e[f++] = m >> 12 & 63 | 128) : e[f++] = m >> 12 | 224,
e[f++] = m >> 6 & 63 | 128),
e[f++] = m & 63 | 128)
}
a = b;
for (f = 0; f < e.length; f++) a += e[f],
a = RL(a, $b);
a = RL(a, Zb);
a ^= b1 || 0;
0 > a && (a = (a & 2147483647) + 2147483648);
a %= 1E6;
return a.toString() + jd + (a ^ b)
};
function RL(a, b) {
var t = "a";
var Yb = "+";
for (var c = 0; c < b.length - 2; c += 3) {
var d = b.charAt(c + 2),
d = d >= t ? d.charCodeAt(0) - 87 : Number(d),
d = b.charAt(c + 1) == Yb ? a >>> d: a << d;
a = b.charAt(c) == Yb ? a + d & 4294967295 : a ^ d
}
return a
}
""")
def getTk(self,text):
return self.ctx.call("TL",text)
这代码是参考别人的,里面由于需要运行JavaScript代码所以需要导入execjs模块,这个模块能够调用JavaScript代码。
里面封装了一个getTK方法,传入的参数就是带翻译的字符串。
2. 爬虫代码
import urllib.request
import execjs
# 谷歌翻译
class Py4Js():
def __init__(self):
self.ctx = execjs.compile("""
function TL(a) {
var k = "";
var b = 406644;
var b1 = 3293161072;
var jd = ".";
var $b = "+-a^+6";
var Zb = "+-3^+b+-f";
for (var e = [], f = 0, g = 0; g < a.length; g++) {
var m = a.charCodeAt(g);
128 > m ? e[f++] = m : (2048 > m ? e[f++] = m >> 6 | 192 : (55296 == (m & 64512) && g + 1 < a.length && 56320 == (a.charCodeAt(g + 1) & 64512) ? (m = 65536 + ((m & 1023) << 10) + (a.charCodeAt(++g) & 1023),
e[f++] = m >> 18 | 240,
e[f++] = m >> 12 & 63 | 128) : e[f++] = m >> 12 | 224,
e[f++] = m >> 6 & 63 | 128),
e[f++] = m & 63 | 128)
}
a = b;
for (f = 0; f < e.length; f++) a += e[f],
a = RL(a, $b);
a = RL(a, Zb);
a ^= b1 || 0;
0 > a && (a = (a & 2147483647) + 2147483648);
a %= 1E6;
return a.toString() + jd + (a ^ b)
};
function RL(a, b) {
var t = "a";
var Yb = "+";
for (var c = 0; c < b.length - 2; c += 3) {
var d = b.charAt(c + 2),
d = d >= t ? d.charCodeAt(0) - 87 : Number(d),
d = b.charAt(c + 1) == Yb ? a >>> d: a << d;
a = b.charAt(c) == Yb ? a + d & 4294967295 : a ^ d
}
return a
}
""")
def getTk(self, text):
"""获取tk值"""
return self.ctx.call("TL", text)
# 获取要翻译的文字
key = input("请输入要翻译的英文文字(英译中):")
# 获取Py4Js实例
py = Py4Js()
print(py.getTk(key)) # 打印tk值
# 请求的URL
url = "https://translate.google.cn/translate_a/single?client=webapp&sl=en&tl=zh-CN&hl=zh-CN&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t&otf=1&ssel=0&tsel=0&kc=7&tk=" + py.getTk(
key) + "&q=" + key
# 请求头
header = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36",
}
# 获取request对象
req = urllib.request.Request(url, headers=header)
# 响应的数据是通过Ajax返回的JSON格式数据,注意编码问题
resp = urllib.request.urlopen(req).read().decode("utf-8")
# 打印
print(resp)
该爬虫代码是英译中,而不能中译英,否则会出问题的。
运行代码,会得到上面的运行效果的图:
3. 中译英
和上面的代码类似,不同的是对URL的处理而已。
代码如下:
import urllib.parse
import urllib.request
import execjs
# 谷歌翻译
class Py4Js():
def __init__(self):
self.ctx = execjs.compile("""
function TL(a) {
var k = "";
var b = 406644;
var b1 = 3293161072;
var jd = ".";
var $b = "+-a^+6";
var Zb = "+-3^+b+-f";
for (var e = [], f = 0, g = 0; g < a.length; g++) {
var m = a.charCodeAt(g);
128 > m ? e[f++] = m : (2048 > m ? e[f++] = m >> 6 | 192 : (55296 == (m & 64512) && g + 1 < a.length && 56320 == (a.charCodeAt(g + 1) & 64512) ? (m = 65536 + ((m & 1023) << 10) + (a.charCodeAt(++g) & 1023),
e[f++] = m >> 18 | 240,
e[f++] = m >> 12 & 63 | 128) : e[f++] = m >> 12 | 224,
e[f++] = m >> 6 & 63 | 128),
e[f++] = m & 63 | 128)
}
a = b;
for (f = 0; f < e.length; f++) a += e[f],
a = RL(a, $b);
a = RL(a, Zb);
a ^= b1 || 0;
0 > a && (a = (a & 2147483647) + 2147483648);
a %= 1E6;
return a.toString() + jd + (a ^ b)
};
function RL(a, b) {
var t = "a";
var Yb = "+";
for (var c = 0; c < b.length - 2; c += 3) {
var d = b.charAt(c + 2),
d = d >= t ? d.charCodeAt(0) - 87 : Number(d),
d = b.charAt(c + 1) == Yb ? a >>> d: a << d;
a = b.charAt(c) == Yb ? a + d & 4294967295 : a ^ d
}
return a
}
""")
def getTk(self, text):
"""获取tk值"""
return self.ctx.call("TL", text)
# 获取要翻译的文字
key = input("请输入要翻译的中文文字(中译英):")
# 获取Py4Js实例
py = Py4Js()
print(py.getTk(key)) # 打印tk值
# 对中文进行处理
data = urllib.parse.urlencode({"q": key})
# 请求的URL
url = "https://translate.google.cn/translate_a/single?client=webapp&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&ssel=6&tsel=3&kc=1&tk=" + py.getTk(
key) + "&" + data
print(url)# 打印URL
# 请求头
header = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36",
}
# 获取request对象
req = urllib.request.Request(url, headers=header)
# 响应的数据是通过Ajax返回的JSON格式数据,注意编码问题
resp = urllib.request.urlopen(req).read().decode("utf-8")
# 打印
print(resp)
控制台打印: