# 面向对象
# 百度翻译 -- 网页版(自动获取token,sign)
import requests
import js2py
import json
import re class WebFanyi:
"""百度翻译网页版爬虫"""
def __init__(self,query_str):
self.session = requests.session()
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36",
}
self.session.headers = headers
self.baidu_url = "https://www.baidu.com/"
self.root_url = "https://fanyi.baidu.com/"
self.lang_url = "https://fanyi.baidu.com/langdetect"
self.trans_url = "https://fanyi.baidu.com/v2transapi"
self.query_str = query_str def get_token_gtk(self):
'''获取token和gtk(用于合成Sign)'''
self.session.get(self.root_url)
resp = self.session.get(self.root_url)
html_str = resp.content.decode()
token = re.findall(r"token: '(.*?)'", html_str)[0]
gtk = re.findall(r"window.gtk = '(.*?)'", html_str)[0]
return token,gtk def generate_sign(self,gtk):
"""生成sign"""
# 1. 准备js编译环境
context = js2py.EvalJs()
with open('webtrans.js', encoding='utf8') as f:
js_data = f.read()
js_data = re.sub("window\[l\]",'"'+gtk+'"',js_data)
# js_data = re.sub("window\[l\]", "\"{}\"".format(gtk), js_data)
# print(js_data)
context.execute(js_data)
sign = context.e(self.query_str)
return sign def lang_detect(self):
'''获取语言转换类型.eg: zh-->en'''
lang_resp = self.session.post(self.lang_url,data={"query":self.query_str})
lang_json_str = lang_resp.content.decode() # {"error":0,"msg":"success","lan":"zh"}
lan = json.loads(lang_json_str)['lan']
to = "en" if lan == "zh" else "zh"
return lan,to def parse_url(self,post_data):
trans_resp = self.session.post(self.trans_url,data=post_data)
trans_json_str = trans_resp.content.decode()
trans_json = json.loads(trans_json_str)
result = trans_json["trans_result"]["data"][0]["dst"]
print("{}: {}".format(self.query_str,result)) def run(self):
"""实现逻辑"""
# 1.获取百度的cookie,(缺乏百度首页的cookie会始终报错998)
self.session.get(self.baidu_url)
# 2. 获取百度翻译的token和gtk(用于合成sign)
token, gtk = self.get_token_gtk()
# 3. 生成sign
sign = self.generate_sign(gtk)
# 4. 获取语言转换类型.eg: zh-->en
lan, to = self.lang_detect()
# 5. 发送请求,获取响应,输出结果
post_data = {
"from": lan,
"to": to,
"query": self.query_str,
"transtype": "realtime",
"simple_means_flag": 3,
"sign": sign,
"token": token
}
self.parse_url(post_data) if __name__ == '__main__':
webfanyi = WebFanyi('lover')
webfanyi.run()

上述代码中用于生成sign的 webtrans.js 文件具体代码如下(可以自己抓包,在js中打断点获取):

 // webtrans.js

 function n(r, o) {
for (var t = 0; t < o.length - 2; t += 3) {
var a = o.charAt(t + 2);
a = a >= "a" ? a.charCodeAt(0) - 87 : Number(a),
a = "+" === o.charAt(t + 1) ? r >>> a : r << a,
r = "+" === o.charAt(t) ? r + a & 4294967295 : r ^ a
}
return r
}
function e(r) {
var o = r.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g);
if (null === o) {
var t = r.length;
t > 30 && (r = "" + r.substr(0, 10) + r.substr(Math.floor(t / 2) - 5, 10) + r.substr(-10, 10))
} else {
for (var e = r.split(/[\uD800-\uDBFF][\uDC00-\uDFFF]/), C = 0, h = e.length, f = []; h > C; C++)
"" !== e[C] && f.push.apply(f, a(e[C].split(""))),
C !== h - 1 && f.push(o[C]);
var g = f.length;
g > 30 && (r = f.slice(0, 10).join("") + f.slice(Math.floor(g / 2) - 5, Math.floor(g / 2) + 5).join("") + f.slice(-10).join(""))
}
var u = void 0
,
// l = "" + String.fromCharCode(103) + String.fromCharCode(116) + String.fromCharCode(107);
i = null;
u = null !== i ? i : (i = window[l] || "") || "";
for (var d = u.split("."), m = Number(d[0]) || 0, s = Number(d[1]) || 0, S = [], c = 0, v = 0; v < r.length; v++) {
var A = r.charCodeAt(v);
128 > A ? S[c++] = A : (2048 > A ? S[c++] = A >> 6 | 192 : (55296 === (64512 & A) && v + 1 < r.length && 56320 === (64512 & r.charCodeAt(v + 1)) ? (A = 65536 + ((1023 & A) << 10) + (1023 & r.charCodeAt(++v)),
S[c++] = A >> 18 | 240,
S[c++] = A >> 12 & 63 | 128) : S[c++] = A >> 12 | 224,
S[c++] = A >> 6 & 63 | 128),
S[c++] = 63 & A | 128)
}
for (var p = m, F = "" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(97) + ("" + String.fromCharCode(94) + String.fromCharCode(43) + String.fromCharCode(54)), D = "" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(51) + ("" + String.fromCharCode(94) + String.fromCharCode(43) + String.fromCharCode(98)) + ("" + String.fromCharCode(43) + String.fromCharCode(45) + String.fromCharCode(102)), b = 0; b < S.length; b++)
p += S[b],
p = n(p, F);
return p = n(p, D),
p ^= s,
0 > p && (p = (2147483647 & p) + 2147483648),
p %= 1e6,
p.toString() + "." + (p ^ m)
}

实际上,除了用js2py作为python中执行js代码的环境编译器外,还可以使用另一个方法 'execjs' ,不过要先通过 pip install PyExecJS 安装PyExecJS模块.具体实现代码如下:

 import execjs
with open("webtrans.js") as f:
js_data = f.read()
js_data = re.sub("window\[l\]", '"' + gtk + '"', js_data)
sign = execjs.compile(js_data).call("e", query_str) # 调用webtrans.js代码中的 e函数,传入参数为 query_str
print(sign)

百度翻译爬虫-Web版(自动生成sign)的更多相关文章

  1. Web Api 自动生成帮助文档

    Web Api 自动生成帮助文档   新建Web Api项目之后,会在首页有API的导航菜单,点击即可看到API帮助文档,不过很遗憾,Description 是没有内容的. 怎么办呢? 第一步: 如果 ...

  2. 根据wsdl文件,Web工程自动生成webservice客户端调用

    根据wsdl文件,Web工程自动生成webservice客户端调用 1,工具:带有webservice插件的eclips 2,步骤: (1),新建一个Web工程:WSDLTest (2),浏览器访问W ...

  3. Web API 自动生成帮助文档并使用Web API Test Client 测试

    之前在项目中有用到webapi对外提供接口,发现在项目中有根据webapi的方法和注释自动生成帮助文档,还可以测试webapi方法,功能很是强大,现拿出来与大家分享一下. 先看一下生成的webapi文 ...

  4. 基于Tkinter以及百度翻译爬虫做的一个小的翻译软件

    首先看效果: 输入Hello, 可见输出 int. 打招呼 下面看源码: from tkinter import * import requests# 首先导入用到的库 request = reque ...

  5. 百度图片爬虫-python版-如何爬取百度图片?

    上一篇我写了如何爬取百度网盘的爬虫,在这里还是重温一下,把链接附上: http://www.cnblogs.com/huangxie/p/5473273.html 这一篇我想写写如何爬取百度图片的爬虫 ...

  6. C#爬虫----Fiddler 插件开发 自动生成代码

    哈喽^_^ 一般我们在编写网页爬虫的时候经常会使用到Fiddler这个工具来分析http包,而且通常并不是分析一个包就够了的,所以为了把更多的时间放在分析http包上,自动化生成封包代码就尤为重要了( ...

  7. Web API 自动生成接口文档

    1.添加NuGet程序包 Microsoft ASP.NET Web API 2.2 Help Page      (这是微软官方的) A Simple Test Client for ASP.NET ...

  8. 百度图片爬虫-python版

               self.browser=imitate_browser.BrowserBase()            self.chance=0            self.chanc ...

  9. mac百度网盘破解版

    以下资源来源于网络收集分享,如有问题请联系我删除!来源入口,后面链接挂了,可去原网址访问! 还在为Mac百度网盘下载速度慢而烦恼吗?百度云盘又是一个非常实用的分享工具,可支持图片.视频.音乐.文档.种 ...

随机推荐

  1. 在 ASP.NET Core 中发送邮件遇到的坑_学习笔记

    功能需求 因为项目需要有个忘记密码验证邮箱再重新修改密码的功能,然后我选用了很简单的一个方案,通过验证登录用户的邮箱然后发送邮件,通过这个邮件发送的链接地址来最后实现密码修改的小功能. 项目环境及实现 ...

  2. 修改dll的错误打开方式

    一不小心把dll类型的文件的打开方式改成了notepad,查了好多资料因为dll没有打开程序所以怎么也改不回来,只好从注册表中查,经检验修改注册表的以下项目可以改回 计算机\HKEY_CURRENT_ ...

  3. 计算机爱好者协会技术贴markdown第二期

    上一期我们学了多级标题,加粗,加斜以及蛮好看的小方块,这一期来继续学习吧 Txt版本: *上一期说这样可以加斜* _其实这样也可以加斜_ **上一期说这样可以加粗** __其实这样也可以加粗__ ** ...

  4. nginx高级用法汇总

    1,nginx限制IP访问,允许IP访问 1.1 模块:nginx_http_access_module 注意:检测顺序是按配置顺序进行的,匹配首条规则将会被使用,所以要注意在配置文件配置的顺序. a ...

  5. vue学习_01

    一.什么是VUE 渐进式的前端框架,MVVM(Model,view,viewmodel)模式,饿了么用的就是vue框架 二.VUE基本语法 1.引入vue: <script src=" ...

  6. ios  国际化开发

    一,.xib 1.首先选中xib文件,在右边的inspector中选择对应的国际化语言,如下图

  7. 2019.03.25 bzoj4568: [Scoi2016]幸运数字(倍增+线性基)

    传送门 题意:给你一棵带点权的树,多次询问路径的最大异或和. 思路: 线性基上树?? 倍增维护一下就完了. 时间复杂度O(nlog3n)O(nlog^3n)O(nlog3n) 代码: #include ...

  8. 关于chrome密码保存框的神坑,这样子解决就行

  9. centos7下安装mysql会遇到的问题集合

    1.mysqld_safe提示 command not found 解决方法 https://blog.csdn.net/lampqiu/article/details/79138961 2.Mysq ...

  10. NIOS II 之串口学习

    UART中有6个寄存器分别为control, status, rxdata, txdata, divisor,endofpacket. 的寄存器是16位位宽的. UART会产生一个高电平的中断,当接收 ...