一、js加密参数案例
1. js加密参数的介绍
当我们在百度首页随著一个关键词(例如:中国)时,浏览器中显示的url是:https://www.baidu.com/s?wd=中国
而对应发送请求的url是:
https://www.baidu.com/s?wd=%E4%B8%AD%E5%9B%BD
实际上浏览器是拿着js加密后的密文数据去发送请求,而网站后端检查的也是密文数据而不是明文数据,所以当我们利用python代码发送一些网络请求时,需要把其中的明文数据转换为密文数据才可能拿到正确的相应。
2. 加密方式
MD5加密:
特点:①. 不管明文长度是多少,密文的长度都是固定的
②. 理论上来说是不可逆的:明文可以转为密文,密文不能转换为明文
python使用md5加密:需要导入hashlib库,这是一个原生库不需要下载
# 导包
import hashlib
# 明文数据
a = '中国'
b = '俄罗斯'
# md5加密
res_a = hashlib.md5(a.encode()).hexdigest()
res_b = hashlib.md5(b.encode()).hexdigest()
print(res_a) # c13dceabcb143acd6c9298265d618a9f
print(res_b) # 7eac3d4db8d7a5a3443c322ab4e33881
base64加密:
特点:①. 密文长度不是固定的
②. 加密是可逆的:明文可以转换为密文,密文也可以转换为明文
python使用base64加密:需要导入base64库
# -*- coding: utf-8 -*-
# 导包
import base64
# 明文数据
a = '中国'
b = '俄罗斯'
# base64加密
res_a = base64.b64encode(a.encode('utf-8')).decode()
res_b = base64.b64encode(b.encode('utf-8')).decode()
print(res_a) # 5Lit5Zu9
print(res_b) # 4S7YJZ55S7TJNLY=
# base64解密
c = base64.b64decode(res_a.encode()).decode()
d = base64.b64decode(res_b.encode()).decode()
print(c) # 中国
print(d) # 俄罗斯
3. 加盐加密之salt
简单理解:当我们输入 123, 456, 789时,后端在进行加密前,可以统一对明文进行一个操作:比如在明文前面加上一个字符或者在明文后面加上一个字符,例如:a123, a456, a789,这种操作就叫做加盐操作。对进行加盐操作的数据进行加密后,就算用户有手段对密文数据进行解密,得到的也是加盐操作后的数据,这在一定程度上提高了数据的安全性。
4. 格林尼治时间的介绍
从1970年1月1日到现在经历的时间
import time
print(time.time())
# python得到的格林尼治时间:1628565457.3019324
# form表单中lts的值: 1628565457301
# form表单中salt的值: 16285654573016
time.time() 得到的是以秒为单位的格林尼治时间
猜测:form表单中的格林尼治时间是以毫秒为单位
import time
print(int(time.time()*1000))
# python得到的格林尼治时间:1628565457301
# form表单中lts的值: 1628565457301
# form表单中salt的值: 16285654573016
对比发现,以毫秒为单位的格林尼治时间和form表单中lts的值相同,比salt的值少了一位
所以lts是以毫秒为单位的格林尼治时间,salt我们猜测是对以毫秒为单位的格林尼治时间进行了加盐操作
5. 有道翻译案例
目的:模拟正常用户输入数据,得到翻译后的数据
①. 抓包:当我们输入要翻译的内容点击翻译后,会出现这个一个数据包:translate_o?smartresult=dict&smartresult=rule,查看preview发现它包含要翻译的内容和翻译后的内容,再查看response,同样发现它包含了要翻译的内容和翻译后的内容且是json格式的数据
②. 找到了对应的数据包,查看headers发现它发送的是POST请求(需要携带form表单数据),得到的响应是json格式的数据(提取数据需要用到jsonpath)
③. 确认url:https://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule
④. 构造headers,双击我们找到的数据包,发现不能正常访问所以需要加上跳转信息
⑤. 构造form表单
这是浏览器中我们翻译你好时的form表单,我们在此基础上进行分析
i: 你好 # 要被翻译的数据
from: AUTO # 要翻译数据的语言(自动检测)
to: AUTO # 翻译后的语言(自动检测)
smartresult: dict # 结果返回键值对(json格式数据)
client: fanyideskweb # 使用的web网页端翻译
salt: 16285645097438 # 有点像加盐操作(数字有点经验的就可以看出来很想格林尼治时间)
sign: f568e53acbfea506beeba8f3f6734404 # 猜测是加密后的数据(无法确定:明文是什么,加密方式是什么)
lts: 1628564509743 # 格林尼治时间
bv: eda468fc64295ecf2810ab8a672c2db1 # # 猜测是加密后的数据(无法确定:明文是什么,加密方式是什么)
doctype: json # json格式数据
version: 2.1 # 版本
keyfrom: fanyi.web # 对于数据来源的描述
action: FY_BY_REALTlME # 动作(不知道是什么)
⑥. 如果用python代码模拟浏览器发送请求,form表单中的数据都需要带上(这些参数值是否固定,当更换要翻译的内容时,参数值是否会发生变化)
不发生改变的参数:直接复制
发生改变的参数:需要分析是如何发生改变的(重点)
⑦. 更换要翻译的内容,重新发送请求,对比两次的form表单
i: 中国 # 翻译内容肯定需要变化
from: AUTO # 不变
to: AUTO # 不变
smartresult: dict # 不变
client: fanyideskweb # 不变
salt: 16285668185407 # 两次翻译的时间不同,salt的值肯定不同
sign: e00349b6ebdeb13db45360dd90fd9034 # 发生变化
lts: 1628566818540 # 两次翻译的时间不同,salt的值肯定不同
bv: eda468fc64295ecf2810ab8a672c2db1 # 不变
doctype: json # 不变
version: 2.1 # 不变
keyfrom: fanyi.web # 不变
action: FY_BY_REALTlME # 不变
⑧. 确认发生变化的form表单参数:i,salt,sign,lts
i:自己输入的要被翻译的内容
salt:int(time.time()*1000) + 数字(该数字目前无法确定)
sign:完全未知
lts:以毫秒为单位的时间戳(格林尼治时间) int(time.time()*1000)
⑨. form表单的参数生成可以到js文件中的js代码中寻找
点击右上角的三个点,选择 search ,输入要搜索的内容(salt,sign)。当结果有很多时,我们可以一个一个分析(不推荐),也可以搜索form表单中其他不容易撞名的键名(smartresult,keyfrom等),然后点击搜索到的js文件,进入js代码,ctrl + f 在代码中继续进行搜索,找到与form表单最像的部分,发现sign,salt都是通过调用r中方法生成的,我们向上翻可以找到r函数
分析:
lts就是r中的ts,ts(r)就是现在的时间戳
salt = i = r + parseInt(10 * Math.random(), 10),猜测salt就是现在的时间戳加上一位随机数字
sigh:md5加密,"fanyideskweb" + e + i + "Y2FYu%TNSbMCxc3t2u^XT",前面和后面部分是固定的,i是salt,e是通过传参拿到的
确定e的值:打断点,启动程序。在r函数的末尾打断点,启动程序,程序就会在断点处停止运行。经过调试信息的分析,发现e的值是实际要翻译的内容
bv的值等于t,t的值等于n.md5(navigator.appVersion),调试时,我们将鼠标放在navigator.appVersion上,就会显示navigator.appVersion的值:5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36,所以bv的值是将本机的user-agent经过了md5加密
import random
import time
import hashlib
import jsonpath
import requests
if __name__ == '__main__':
# 输入要翻译的内容
kw_ = input('请输入要翻译的内容:')
# 1.确认目标的url
url_ = 'https://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'
# 2.构造请求头信息
headers_ = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36',
'Cookie': 'OUTFOX_SEARCH_USER_ID_NCOO=695517622.9493787; OUTFOX_SEARCH_USER_ID="1661542047@10.169.0.102"; _ga=GA1.2.1220542815.1610175292; _ntes_nnid=542a9c512f4112ee317d203a42e836c0,1612626606049; JSESSIONID=aaaGQJmrjHj3Be4wJ-TSx; DICT_UGC=be3af0da19b5c5e6aa4e17bd8d90b28a|; JSESSIONID=abcdlT8NCxn9phq2L-TSx; ___rl__test__cookies=1628570526123',
'Referer': 'https://fanyi.youdao.com/'
}
# 3.构造form表单
lts_ = str(int(time.time() * 1000))
salt_ = str(int(time.time() * 1000)) + str(random.randint(0, 9))
sign_ = "fanyideskweb" + kw_ + salt_ + "Y2FYu%TNSbMCxc3t2u^XT"
sign_md5 = hashlib.md5(sign_.encode()).hexdigest()
form_ = {
'i': kw_,
'from': 'AUTO',
'to': 'AUTO',
'smartresult': 'dict',
'client': 'fanyideskweb',
'salt': salt_,
'sign': sign_md5,
'lts': lts_,
'bv': 'eda468fc64295ecf2810ab8a672c2db1',
'doctype': 'json',
'version': '2.1',
'keyfrom': 'fanyi.web',
'action': 'FY_BY_REALTlME'
}
# 4.发送post请求,获取响应
response_ = requests.post(url_, headers=headers_, data=form_)
# 5.解析数据得到翻译后的内容
py_data = response_.json()
data_ = jsonpath.jsonpath(py_data, r'$..tgt')[0]
# 6.输出显示
print('您输入的内容的翻译是:', data_)
由于我们输入的内容可能不符合规范,所以我们做一个异常处理
import random
import time
import hashlib
import jsonpath
import requests
if __name__ == '__main__':
# 输入要翻译的内容
kw_ = input('请输入要翻译的内容:')
# 1.确认目标的url
url_ = 'https://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'
# 2.构造请求头信息
headers_ = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36',
'Cookie': 'OUTFOX_SEARCH_USER_ID_NCOO=695517622.9493787; OUTFOX_SEARCH_USER_ID="1661542047@10.169.0.102"; _ga=GA1.2.1220542815.1610175292; _ntes_nnid=542a9c512f4112ee317d203a42e836c0,1612626606049; JSESSIONID=aaaGQJmrjHj3Be4wJ-TSx; DICT_UGC=be3af0da19b5c5e6aa4e17bd8d90b28a|; JSESSIONID=abcdlT8NCxn9phq2L-TSx; ___rl__test__cookies=1628570526123',
'Referer': 'https://fanyi.youdao.com/'
}
# 3.构造form表单
lts_ = str(int(time.time() * 1000))
salt_ = str(int(time.time() * 1000)) + str(random.randint(0, 9))
sign_ = "fanyideskweb" + kw_ + salt_ + "Y2FYu%TNSbMCxc3t2u^XT"
sign_md5 = hashlib.md5(sign_.encode()).hexdigest()
form_ = {
'i': kw_,
'from': 'AUTO',
'to': 'AUTO',
'smartresult': 'dict',
'client': 'fanyideskweb',
'salt': salt_,
'sign': sign_md5,
'lts': lts_,
'bv': 'eda468fc64295ecf2810ab8a672c2db1',
'doctype': 'json',
'version': '2.1',
'keyfrom': 'fanyi.web',
'action': 'FY_BY_REALTlME'
}
# 进行异常处理
try:
# 4.发送post请求,获取响应
response_ = requests.post(url_, headers=headers_, data=form_)
# 5.解析数据得到翻译后的内容
py_data = response_.json()
data_ = jsonpath.jsonpath(py_data, r'$..tgt')[0]
# 6.输出显示
print('您输入的内容的翻译是:', data_)
except:
print('您输入的数据不符合规范,请重新输入')
二、应用生成
当我们写好一个程序,希望把他打包成一个应用可供其他人使用,就可以使用一个第三方库:pyinstaller
只需要在你要生成应用的py文件目录下,在路径中输入cmd弹出命令窗口,然后输入:
pyinstaller -F xxx.py
就会生成build和dist两个文件夹,而我们需要的应用程序(exe文件)在dist文件中
需要注意的是:py文件中不能出现空格
三、nodejs介绍
nodejs是运行js代码的工具
1. 下载:http://nodejs.cn/download/ 选择适合自己电脑的版本进行下载
2. 安装:尽量按照推荐的路径进行安装
3. 查看安装路径:cmd --> 输入: where node
4. 添加环境变量:在系统环境变量的Path中添加上查看安装路径中的路径(需要把结尾的node.exe删掉)
5. 检查是否安装成功:在非安装路径 输入 node -v ,得到版本号则说明安装成功
6. Pycharm中安装nodejs插件:file -> settings -> plugins -> 输入node.js -> install
7. Pycharm中指定nodejs的路径:file -> settings -> Languages&Frameworks -> 点击node.js and npm -> 选择node.js的路径
8. 建议重启Pycharm
测试:在Pycharm中新建一个JavaScript文件
function f(a, b) {
return a + b
}
a = f(1, 2)
console.log(a)
如果正确输出结果,则证明配置成功
四、百度翻译案例
①. 抓包:当我们输入要翻译的内容,会自动出现翻译后的内容,在此期间我们访问的网址并没有发生变化,所以这是一个异步加载的数据包,一般异步加载的数据包会放在xhr中,通过对xhr中数据包的preview和response检查,可以确定是v2transapi?from=zh&to=en这个数据包
②. 找到了对应的数据包,查看headers发现它发送的是POST请求(需要携带form表单数据),得到的响应是json格式的数据(提取数据需要用到jsonpath)
③. 确认url:https://fanyi.baidu.com/v2transapi?from=zh&to=en
④. 构造headers,双击我们找到的数据包,发现不能正常访问所以需要加上跳转信息
⑤. 构造form表单
这是浏览器中我们翻译你好时的form表单,我们在此基础上进行分析
from: zh # 中文
to: en # 英文(默认从中文翻译成英文)
query: 中国 # 要被翻译的数据
transtype: realtime # 翻译的方式
simple_means_flag: 3 # 不知道
sign: 777849.998728 # 加密的参数
token: 0ef89eb2633a51f5b129f400cdcebc4b # 一种跨域防护
domain: common # 域名(范围)
⑥. 如果用python代码模拟浏览器发送请求,form表单中的数据都需要带上(这些参数值是否固定,当更换要翻译的内容时,参数值是否会发生变化)
不发生改变的参数:直接复制
发生改变的参数:需要分析是如何发生改变的(重点)
⑦. 更换要翻译的内容,重新发送请求,对比两次的form表单
from: zh # 不变
to: en # 不变
query: 你好 # 要被翻译的数据,肯定变化
transtype: realtime # 不变
simple_means_flag: 3 # 不变
sign: 446766.143903 # 变化
token: 0ef89eb2633a51f5b129f400cdcebc4b # 不变
domain: common # 不变
⑧. 确认发生变化的form表单参数:query,sign
query:自己输入的要被翻译的内容
sign:完全未知
⑨. form表单的参数生成可以到js文件中的js代码中寻找
点击右上角的三个点,选择 search ,输入要搜索的内容(query,sign)。当结果有很多时,我们可以一个一个分析(不推荐),也可以搜索form表单中其他不容易撞名的键名(transtype,simple_means_flag等),然后点击搜索到的js文件,进入js代码,ctrl + f 在代码中继续进行搜索,找到与form表单最像的部分,在这后面打断点,启动程序,程序就会在断点处停止运行。发现sign是调用了h(n)函数,其中n是要翻译的内容
有道翻译:sign是md5加密,明文知道我们可以利用python代码执行md5加密,拿到加密的sign值
百度翻译:h(n)是JavaScript写的一个函数,sign值就是将翻译的内容作为参数传递给了h(n)函数,如果我们可以利用python代码写出这个h(n)函数的逻辑就可以解决问题,但是可以发现js函数定义部分逻辑非常复杂比较难模仿,此时我们不妨换一个思路,直接把js函数的定义部分拿过来,传入一个实参(要被翻译的内容)直接执行js代码,调用js的函数,得到他的返回值也可以解决问题(这就是js的逆向解析)。
在python中执行js文件
首先需要安装一个第三方库:PyExecJS
我们先创建一个a.js的文件
function f(a, b) {
return a + b
}
在python中执行a.js文件中的f函数
# 导包
import execjs
# 拿到响应的js代码
with open('a.js', 'r') as f:
js_data = f.read()
# 转换操作
js_obj = execjs.compile(js_data)
# 拿到转换对象,执行js代码
res_ = js_obj.call('f', 4, 5)
print(res_)
对以上内容了解后,我们就可以对百度翻译案例代码进行书写
我们利用js逆向获取sign值在执行后会报错:i is not defined
# 利用js逆向获取sign的值
# (1)打开js文件,获取js代码
with open('sign.js', 'r') as f:
js_code = f.read()
# (2)实例化一个js对象
js_obj = execjs.compile(js_code)
# (3)调用函数,获得返回值
sign_ = js_obj.call('e', kw_)
说明js代码中有个i值我们没有定义,所以我们需要返回到网站中找到的js代码中寻找变量i的定义,通过改变要翻译的内容我们发现i的值始终是320305.131321201,所以我们直接在保存的js代码中加入i的定义即可
var i = '320305.131321201'
运行后发现又有一个n没有定义,查看js代码,发现n是一个函数的调用,所以我们需要在网站的js代码中把函数n的定义也找到复制到我们的js代码中,n的定义就在e函数的上面
sign.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 i = '320305.131321201'
var u = void 0
, l = "" + String.fromCharCode(103) + String.fromCharCode(116) + String.fromCharCode(107);
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)
}
baidu.py
import jsonpath
import requests
import execjs
if __name__ == '__main__':
# 输入要翻译的内容
kw_ = input('请输入要翻译的内容:')
# 1.目标url的确认
url_ = 'https://fanyi.baidu.com/v2transapi?from=zh&to=en'
# 2.构造请求头信息
headers_ = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36',
'Cookie': 'BIDUPSID=5C86C3A345E71E667845B24CF1E67F57; PSTM=1582554282; REALTIME_TRANS_SWITCH=1; HISTORY_SWITCH=1; FANYI_WORD_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; __yjs_duid=1_87d0c9f7af61c48570f2b985588a639f1618070691104; BDUSS=TNFaUExfmlBZzhVYklDNm1kRUN4aktDaWwxTUwxcHNVaWtTbWpKRUJ4cWphZjlnRVFBQUFBJCQAAAAAAAAAAAEAAADwfqczAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKPc12Cj3NdgN; BDUSS_BFESS=TNFaUExfmlBZzhVYklDNm1kRUN4aktDaWwxTUwxcHNVaWtTbWpKRUJ4cWphZjlnRVFBQUFBJCQAAAAAAAAAAAEAAADwfqczAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKPc12Cj3NdgN; H_WISE_SIDS=110085_127969_174662_175539_175667_175757_176399_176555_176590_176677_177168_177224_177281_177370_177411_177950_177971_178265_178327_178493_178629_178704_178727_178896_178946_179005_179200_179258_179309_179335_179341_179349_179400_179432_179483_179520_179575_179595_179640_179731_180093_180112_180120_180123_180276_180324_180327_180364; BAIDUID=2EB59481A75F7B16D9F87D484025DFA5:FG=1; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; DOUBLE_LANG_SWITCH=1; delPer=0; PSINO=1; BAIDUID_BFESS=2EB59481A75F7B16D9F87D484025DFA5:FG=1; BDRCVFR[feWj1Vr5u3D]=I67x6TjHwwYf0; H_PS_PSSID=34300_34335_34369_34145_34374_33848_34072_34092_34107_34094_26350_34237; BA_HECTOR=8h850l0k0kak20ahcv1gh45d50q; BCLID=11428650171178675450; BDSFRCVID=3Y-OJexroG0YyxOHL61worj0ALweG7bTDYLtOwXPsp3LGJLVJeC6EG0Pts1-dEu-EHtdogKKW2OTHTuF_2uxOjjg8UtVJeC6EG0Ptf8g0M5; H_BDCLCKID_SF=tR3h3RrX26rDHJTg5DTjhPrM0MJCWMT-MTryKKJwM4QCOh4CDtcoK4TQLtvfKx-fKHnRhlRNBnnY_PnG2Mjf368ZyxomtfQxtNRJQKDE5p5hKq5S5-OobUPU3N59LUvnbmcdot5yBbc8eIna5hjkbfJBQttjQn3hfIkj2CKLtCvDqTrP-trf5DCShUFsJhFLB2Q-XPoO3KJZJtnOyMk-DJ-eKxCj3x7f5mkf3fbgylRM8P3y0bb2DUA1y4vpBtQmJeTxoUJ2-KDVeh5Gqfo15-0ebPRiL5j9QgbnLlQ7tt5W8ncFbT7l5hKpbt-q0x-jLTnhVn0MBCK0HPonHjKWjjbW3f; BCLID_BFESS=11428650171178675450; BDSFRCVID_BFESS=3Y-OJexroG0YyxOHL61worj0ALweG7bTDYLtOwXPsp3LGJLVJeC6EG0Pts1-dEu-EHtdogKKW2OTHTuF_2uxOjjg8UtVJeC6EG0Ptf8g0M5; H_BDCLCKID_SF_BFESS=tR3h3RrX26rDHJTg5DTjhPrM0MJCWMT-MTryKKJwM4QCOh4CDtcoK4TQLtvfKx-fKHnRhlRNBnnY_PnG2Mjf368ZyxomtfQxtNRJQKDE5p5hKq5S5-OobUPU3N59LUvnbmcdot5yBbc8eIna5hjkbfJBQttjQn3hfIkj2CKLtCvDqTrP-trf5DCShUFsJhFLB2Q-XPoO3KJZJtnOyMk-DJ-eKxCj3x7f5mkf3fbgylRM8P3y0bb2DUA1y4vpBtQmJeTxoUJ2-KDVeh5Gqfo15-0ebPRiL5j9QgbnLlQ7tt5W8ncFbT7l5hKpbt-q0x-jLTnhVn0MBCK0HPonHjKWjjbW3f; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1628382537,1628506488,1628575143,1628575148; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1628575148; __yjs_st=2_OTExNjdmMTJhOTUxN2IzYzVmMWMyMWQwNjE1NDE0MmU2NDcxNDFmOTU4YWY2NGNkNmVjZDU5Mzg4YjQ4YzQ0MWVmMWRiMzEwOGI0MzllMThiZWRiMDdlMmU4ODgzNjA0YjYyYzUxMmU5NzY3NDM1OGUxNDA2MWY0ODg4MWVmZmM4NzA5M2VkZmNmZDcwYjJjOGQ4OWQ2YzVlNzg5MDhiNWE3MmViYmEzMzdiNzQzN2E1ZjVlMWQ0ZmEyODkyODBlZDdlOGY2NTFlYWIwNjNkZWFkYjZjMWFmYTU3YWM1YTY1Y2NiYWM1MGQzODNmYzBmZDNiOWYzOWY1YzllNmUyNF83XzhkMDU1MWM4; ab_sr=1.0.1_ZGM2M2UxYTMxNDE2NWQ5ZjBmMGY0ZjQ5ZjdlYWM3MDg3YTAxMzY1NmQzMGU3N2RjY2RiNTA0NjFlZDFhYjNjNzgxYTdlMTc1Yzc2OTA0MWQ3NzA3NGJiNTM4ZDllZGRmZDk2NzJmMzVlODkwNDBjYjg4NDZlODgwYjYyYTg1MDcyN2RmZDRhYzg0ZWM4YmJlZWIyYmY1YTNlZWQ1MWExYmQ4OWYxZWE3NDcxMDk1ZjA3ODM1MGQ3YzVjYzFkMTJk',
'Referer': 'https://fanyi.baidu.com/?aldtype=16047'
}
# 利用js逆向获取sign的值
# (1)打开js文件,获取js代码
with open('sign.js', 'r') as f:
js_code = f.read()
# (2)实例化一个js对象
js_obj = execjs.compile(js_code)
# (3)调用函数,获得返回值
sign_ = js_obj.call('e', kw_)
# 3.构造form表单
form_ = {
'from': 'zh',
'to': 'en',
'query': kw_,
'transtype': 'realtime',
'simple_means_flag': '3',
'sign': sign_,
'token': '0ef89eb2633a51f5b129f400cdcebc4b',
'domain': 'common'
}
# 4.发送请求,获取响应
response_ = requests.post(url_, headers=headers_, data=form_)
# 5.解析响应,获取数据
js_data = response_.json()
data_ = jsonpath.jsonpath(js_data, '$..dst')[0]
# 6.输出显示
print('您输入的内容的翻译是:', data_)
五、打码平台的介绍
验证码:防爬虫
验证码的类型:数字 -> 扭曲的数字 -> 扭曲字母加数字 -> 滑块 -> 点击找出成语 -> 数学题 ...
爬虫通过验证码的方式:
1. 不进行破解,手动登录拿着登录后的Cookie去访问网站
2. 利用打码平台(收费:交钱,调用别人的api去破解各种验证码)