继上一篇百度翻译接口爬虫,为了集齐五龙珠,我开始了又一个征程。
谷歌搜索服务在中国无法使用,但是其谷歌搜索服务可以使用,本次破解其翻译接口加密参数跟上次差不多,合理利用搜索,1小时不到就解决了其加密方式。
打开其接口,点击F12或查看源代码,通过查看请求和响应过程,我们发现了其请求参数,几次刷新页面后,发现一个参数随着请求内容变化而变化,且变化无明显规律。
百度搜索“谷歌翻译爬虫给”,已经有很多前辈进行了破解,首先在页面中正则匹配获取ttk这个值,然后找到加密的js代码。在搜索过程中,发现有人说“百度翻译的加密参数跟谷歌翻译加密参数的加密出来的结果是一致的,正巧上次已经将百度翻译的js加密代码翻译成了py代码,可以直接使用,经过尝试,果然是一样的。
下面贴代码
# -*- coding:utf-8 -*-
import re
import ctypes
from urllib.parse import urlencode
import requests
#请求需要的参数
def get_params(ttk, content):
tk = get_tk(ttk=ttk, r=content)
data = {
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,
source: bh,
ssel: 0,
tsel: 0,
kc: 1,
tk:tk,
q: content
}
return data
#正则从网页中匹配出ttk的值,用于得到tk的值
def get_ttk():
# \x3d十六进制编码,解码为=
# \x27解码为
headers = {
user-agent: Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36
}
page = requests.get(“https://translate.google.cn/”, headers=headers)
pattern = re.compile(ra\\x3d(.*?);var.*?b\\x3d(.*?);return (.*?)\+, re.S)
results = re.findall(pattern, page.text)
#print(results)
a = int(results[0][0])
b = int(results[0][1])
return results[0][2] + . + str(a+b)
#计算得出tk的值
def get_tk(ttk, r):
m = int(ttk.split(“.”)[0])
s = int(ttk.split(“.”)[1])
S = {}
v = 0
c = 0
while v < len(r):
A = ord(r[v])
if 128 > A:
S[str(c)] = A
c = c + 1
else:
if 2048 > A:
S[str(c)] = A >> 6 | 192
c = c + 1
else:
if 55296 == (64512 & A) and v + 1 < len(r) and 56320 == (64512 & ord(r[v + 1])):
v = v + 1
A = 65536 + ((1023 & A) << 10) + (1023 & ord(r[v]))
S[str(c)] = A >> 18 | 240
c = c + 1
S[str(c)] = A >> 12 & 63 | 128
c = c + 1
else:
S[str(c)] = A >> 12 | 224
c = c + 1
S[str(c)] = A >> 6 & 63 | 128
c = c + 1
S[str(c)] = 63 & A | 128
c = c + 1
v = v + 1
p = m
b = 0
F = “+-a^+6”
D = “+-3^+b+-f”
while b < len(S):
p = p + S[str(b)]
p = get_n(p, F)
b = b + 1
p = get_n(p, D)
p ^= s
if not 0 > p:
p = p
else:
p = (2147483647 & p) + 2147483648
p = p % 1e6
p = str(int(p)) + “.” + str((int(p) ^ m))
print(p)
return p
def get_n(p, D):
t = 0
while t < len(D) – 2:
a = D[t + 2]
if a >= “a”:
a = ord(a[0]) – 87
else:
a = int(a)
if D[t + 1] == “+”:
a = unsigned_right_shift(p, a)
else:
a = p << a
if D[t] == “+”:
p = p + a & 4294967295
else:
p = p ^ a
t = t + 3
return p
def int_overflow(val):
maxint = 2147483647
if not –maxint–1 <=val <=maxint:
val = (val + (maxint + 1)) % (2 * (maxint + 1)) – maxint –1
return val
def unsigned_right_shift(n, i):
if n < 0:
n = ctypes.c_uint32(n).value
if i < 0:
return –int_overflow(n << abs(i))
return int_overflow(n >> i)
#获取接口内容
def get_content(url, content):
ttk = get_ttk()
data = get_params(ttk=ttk, content=content)
headers = {
user-agent: Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36,
referer: https://translate.google.cn/
}
url = url + urlencode(data)
response = requests.get(url,headers=headers)
print(response.json())
if __name__ == “__main__”:
url = “https://translate.google.cn/translate_a/single?”
content = “数据分析师”
get_content(url=url,content=content)
#get_ttk()
这几天,除了把谷歌翻译破解出来,顺便还尝试了金山翻译和腾讯君翻译,其接口均没有进行加密,因此没花什么时间就把代码给撸出来了。
# -*- coding:utf-8 -*-
import time
import requests
from urllib.parse import urlencode
“””
金山翻译查询入口
http://www.iciba.com/index.php?
callback=jQuery190034858312023369775_1536974699247&
a=getWordMean&
c=search&
list=1%2C2%2C3%2C4%2C5%2C8%2C9%2C10%2C12%2C13%2C14%2C15%2C18%2C21%2C22%2C24%2C3003%2C3004%2C3005&
word=%E4%BD%A0%E5%A5%BD&
_=1536974699248″””
def get_params(content):
data = {
a: getWordMean,
c: search,
list: 1,2,3,4,5,8,9,10,12,13,14,15,18,21,22,24,3003,3004,3005,
word: content,
_: str(int(time.time() * 1000))
}
return data
def get_callback():
pass
def get_content(url, content):
data = get_params(content)
headers = {
Host: www.iciba.com,
User-Agent: Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36,
Referer: http://www.iciba.com/
}
url = url + urlencode(data)
response = requests.get(url=url, headers = headers)
results = response.json()
print(content,”:”,results.get(“baesInfo”))
print(response.json())
if __name__ == “__main__”:
url = http://www.iciba.com/index.php?
content = 数据分析师
get_content(url=url, content=content)
# -*- coding:utf-8 -*-
import time
import requests
“””
https://fanyi.qq.com/api/translate
“””
def get_content(url, content):
#中文译英文,f为zh,t为en
data = {
source: auto,
target: en,
sourceText: content,
essionUuid: translate_uuid + str(int(time.time() * 1000))
}
headers = {
Content-Type: application/x-www-form-urlencoded; charset=UTF-8,
Host: fanyi.qq.com,
User-Agent: Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36,
Referer: https://fanyi.qq.com/
}
response = requests.post(url=url, data=data, headers=headers)
results = response.json()
print(results)
if __name__ == “__main__”:
url = https://fanyi.qq.com/api/translate
content = 来我家吧
get_content(url=url, content=content)
总结
1.加上有道翻译,共破解了5个翻译接口,其中百度,谷歌和有道接口进行了加密,金山和腾讯没有进行加密,简直友好,当然大家还是应该有礼貌的使用接口,避免给对方服务器增加不必要的负担。
2.这是我第一次进行js加密参数破解,能够取得一些小成果也是合理利用搜索的结果,站在额前人的肩膀上,因此,此次也是将代码给贴出来,希望能给后来者学习提供一些方向。
3.破解js加密参数,首先还是需要对JavaScript有最基本的了解,然后要学会有耐心的把通过浏览器获取的到请求参数进行搜索寻找,找到最终加密参数,最后要会使用搜索,将不认识的代码关键词拿出来搜索,去理解,并将其转换为自己爬虫语言的表达方式。
4.在破解金山翻译的过程中,我第一件事是通过浏览器查看请求参数,紧接着根据请求参数去查找对应的加密js代码,我犯了一个错误,第一步应该是先尝试观察哪些参数是必须的,哪些是不必须的,然后再判断必须的参数是否加密,实际上金山翻译的查词和翻译入口的一个动态变换的参数都是非必须的,且参数无加密,可以直接构建请求参数进行爬取。
5.学习爬虫的道路是漫长的,需要学习很多知识,just try!
6.最后,本文仅记录学习之用,勿要将本文代码用于商业用途。