Python爬虫(第九周)

一、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. 有道翻译案例

有道翻译:http://fanyi.youdao.com/

目的:模拟正常用户输入数据,得到翻译后的数据

①. 抓包:当我们输入要翻译的内容点击翻译后,会出现这个一个数据包: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)

 如果正确输出结果,则证明配置成功

四、百度翻译案例

百度翻译:https://fanyi.baidu.com/

①. 抓包:当我们输入要翻译的内容,会自动出现翻译后的内容,在此期间我们访问的网址并没有发生变化,所以这是一个异步加载的数据包,一般异步加载的数据包会放在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去破解各种验证码)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不懂编程的大学生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值