当前位置: 首页 > news >正文

熟练掌握爬虫技术

一、Crawler、Requests反爬破解

1. HTTP协议与WEB开发

1. 什么是请求头请求体,响应头响应体
2. URL地址包括什么
3. get请求和post请求到底是什么
4. Content-Type是什么

1.1 简介

HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于万维网(WWW:World Wide Web )服务器与本地浏览器之间传输超文本的传送协议。HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展。HTTP协议工作于客户端-服务端架构为上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。Web服务器根据接收到的请求后,向客户端发送响应信息。
在这里插入图片描述

1.2 请求协议与响应协议

URL:

1、URL:协议://IP:端口/路径/.../.../.../...?查询参数
https://www.lagou.com/wn/jobs?labelWords=&fromSearch=true&suginput=&kd=python
协议:HTTP
IP:每一台服务器的网络标识:www.lagou.com
端口:进程:默认80
路径:/wn/jobs
查询参数:labelWords=&fromSearch=true&suginput=&kd=python
2、网络三要素:协议、IP、端口
3、状态码:
404:找不到资源
101:进行中
202:请求成功
303:重定向
404:资源不存在、访问限制
505:服务器错误

http协议包含由浏览器发送数据到服务器需要遵循的请求协议与服务器发送数据到浏览器需要遵循的请求协议。用于HTTP协议交互的信被为HTTP报文。请求端(客户端)的HTTP报文 做请求报文,响应端(服务器端)的 做响应报文。HTTP报文本身是由多行数据构成的字文本。
在这里插入图片描述

请求方式: get与post请求- GET提交的数据会放在URL之后,以?分割URL和传输数据,参数之间以&相连,如EditBook?name=test1&id=123456. POST方法是把提交的数据放在HTTP包的请求体中.
- GET提交的数据大小有限制(因为浏览器对URL的长度有限制),而POST方法提交的数据没有限制响应状态码:状态码的职 是当客户端向服务器端发送请求时, 返回的请求 结果。借助状态码,用户可以知道服务器端是正常 理了请求,还是出 现了 。状态码如200 OK,以3位数字和原因组成。

2. requests&反爬破解

2.1 User-Agent反爬

在这里插入图片描述

import requestsheaders = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36",
}res = requests.get("https://www.baidu.com/",headers=headers
)# 解析数据
with open("baidu.html", "w") as f:f.write(res.text)

在这里插入图片描述

2.2 Refer反爬

在这里插入图片描述

# 选电影:喜剧
import requestsheaders = {"User-Agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)'' Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0',"Referer": "https://movie.douban.com/explore",
}res = requests.get("https://m.douban.com/rexxar/api/v2/movie/recommend?refresh=0&start=0&count=20&""selected_categories=%7B%22%E7%B1%BB%E5%9E%8B%22:%22%E5%96%9C%E5%89%A7%22%7D&uncollect=false&tags=%E5%96%9C%E5%89%A7",headers=headers,
)# print(res.text)
print(res.json().get("count"))

在这里插入图片描述

2.3 cookie反爬

在这里插入图片描述

# -*- coding utf-8 -*-
import requests
cookie="xq_a_token=edbee4e5d1e92f98548629214a6e17fe06486a8f; xqat=edbee4e5d1e92f98548629214a6e17fe06486a8f; xq_r_token=1bd9fe2188768570022d1a3f9e12934cdaa1dc53; xq_id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJ1aWQiOi0xLCJpc3MiOiJ1YyIsImV4cCI6MTcwODQ3NjMzNiwiY3RtIjoxNzA2MTk1NzQ0NzM1LCJjaWQiOiJkOWQwbjRBWnVwIn0.Dajzah-CDQ8ER2qN9cHnYH_TPjSiYoXzl7Ht1J_CE4TxQRbH8qEzrXe4LcT4KDd815rQOZ6DF4SORJbA1qltAQ-EmD1NiD0YX0FV-Ub-5ok2FDoLcD4_9dS3iNkpIyAQE8DNJZEMBUv4TuLl8tGh7g5l9PpcOlV-_rC5OYXTckDCklU5WNkvPRsSis2nIohnkz4up2STWsB1IowmYgAN3cTXABy5wFmpEY-KUsGYi49UGH5QSYzfAYdbOxVFO5YWOiKrzXV_GIJNRvL2G0N3wQBzMew-fpB0fopKO6BbzzdbKbY2hccxx3p27a_6b7hqED0PoMO34fUKH8z6p5yqvA; cookiesu=851706195765148; u=851706195765148; device_id=11c12c1015a4baf7b0208768b7589c02; Hm_lvt_1db88642e346389874251b5a1eded6e3=1706195767; Hm_lpvt_1db88642e346389874251b5a1eded6e3=1706196050"
headers = {"User-Agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)'' Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0',"Referer": "https://xueqiu.com/",# "Cookie": "xq_a_token=edbee4e5d1e92f98548629214a6e17fe06486a8f; "#           "xqat=edbee4e5d1e92f98548629214a6e17fe06486a8f; "#           "xq_r_token=1bd9fe2188768570022d1a3f9e12934cdaa1dc53; "#           "xq_id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9."#           "eyJ1aWQiOi0xLCJpc3MiOiJ1YyIsImV4cCI6MTcwODQ3NjMzNiwiY3RtIjoxNzA2"#           "MTk1NzQ0NzM1LCJjaWQiOiJkOWQwbjRBWnVwIn0.Dajzah-CDQ8ER2qN9cHnYH_"#           "TPjSiYoXzl7Ht1J_CE4TxQRbH8qEzrXe4LcT4KDd815rQOZ6DF4SORJbA1qltAQ-"#           "EmD1NiD0YX0FV-Ub-5ok2FDoLcD4_9dS3iNkpIyAQE8DNJZEMBUv4TuLl8tGh7g5"#           "l9PpcOlV-_rC5OYXTckDCklU5WNkvPRsSis2nIohnkz4up2STWsB1IowmYgAN3cTXAB"#           "y5wFmpEY-KUsGYi49UGH5QSYzfAYdbOxVFO5YWOiKrzXV_GIJNRvL2G0N3wQBzMew-f"#           "pB0fopKO6BbzzdbKbY2hccxx3p27a_6b7hqED0PoMO34fUKH8z6p5yqvA; "#           "cookiesu=851706195765148; u=851706195765148; "#           "device_id=11c12c1015a4baf7b0208768b7589c02; "#           "Hm_lvt_1db88642e346389874251b5a1eded6e3=1706195767; "#           "Hm_lpvt_1db88642e346389874251b5a1eded6e3=1706196050","Cookie": cookie
}res = requests.get("https://stock.xueqiu.com/v5/stock/chart/minute.json?symbol=SZ399001&period=1d",headers=headers
)
print(res.text)

在这里插入图片描述

3.请求参数

requests里面的两个参数:data、params

3.1 post请求以及请求体参数

data参数
在这里插入图片描述

import requests
while True:word = input("请输入翻译单词:")url = "https://aidemo.youdao.com/trans"my_data = {"q": word,"from": "Auto","to": "Auto"}my_headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0"}res = requests.post(url, data=my_data, headers=my_headers)# print(res.text)print(res.json().get("translation")[0])

在这里插入图片描述

3.2 get请求以及查询参数

params参数

# 2.get请求以及查询参数
import requests
headers = {"User-Agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)'' Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0',"Referer": "https://movie.douban.com/explore",
}
my_params = {"refresh": 0,"start": 0,"count": 20,"tags": "悬疑",
}
res = requests.get("https://m.douban.com/rexxar/api/v2/movie/recommend",headers=headers,params=my_params,
)
# print(res.text)
print(res.json())

在这里插入图片描述

4. 爬虫图片和视频

4.1 直接爬取媒体数据流

图片:
在这里插入图片描述

# -*- coding utf-8 -*-
import requestsurl = "https://pic.netbian.com/uploads/allimg/231213/233751-17024818714f51.jpg"res = requests.get(url)
# print(res.content)#  文件操作
with open("美女.jpg", "wb") as f:f.write(res.content)

视频
在这里插入图片描述

# -*- coding utf-8 -*-
import requestsurl = "https://apd-vlive.apdcdn.tc.qq.com/om.tc.qq.com/A2cOGJ1ZAYQyB_mkjQd9WD_pAtroyonOY92ENqLuwa9Q/B_JxNyiJmktHRgresXhfyMeiXZqnwHhIz_hST7i-68laByiTwQm8_qdRWZhBbcMHif/svp_50001/szg_1179_50001_0bf2kyaawaaafaal3yaoijqfcvwdbnlaac2a.f632.mp4?sdtfrom=v1010&guid=e765b9e5b625f662&vkey=38DF885CE72372B324B47541285404A230F61C9E12FC69B72EC8A2CF6F6809E00461165C635758EB7E7B49738D9DB608A7C855DB4E7A0B9A082A399875D82022567E1690D97ABE2A3C002ADD06D4AD5EAD4F028688C35E6D73D29DBF2D596F63C6722B78DA1EA3707EB5A7DD2F60781A45B31B693974432F649E523C08D797BA7907BFDB2562BF44E1483A3981FAAC70BEF8BD92611EF365A183621BDE70F55B2224394DB78CD7F5"
res = requests.get(url)# 解析数据
with open("相声.mp4", "wb") as f:f.write(res.content)

4.2 批量爬取数据

在这里插入图片描述

"""1.先爬取整个页面2.然后做数据解析找到想要的"""
import re
import os
import requestsheaders = {"User-Agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) ''Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0',
}res = requests.get("https://pic.netbian.com/4kqiche/",headers=headers
)
# print(res.text)# 数据解析url,例如:正则,xpath,bs4都是页面中解数据
# ret = re.findall(pattern:"", string:"")
img_url_list = re.findall("uploads/allimg/.*?.jpg", res.text)
print(img_url_list)for img_url in img_url_list:res = requests.get("https://pic.netbian.com/"+img_url)# print(res.content)#  文件操作img_name = os.path.basename(img_url)with open("./imgs/" + img_name, "wb") as f:f.write(res.content)

在这里插入图片描述

二、同步、并发以及JS逆向实战

1.同步获取短视频

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
1.只要播放地址对Json数据解析,先把列表找出:
在这里插入图片描述
在这里插入图片描述
2.只想要所有的播放地址,通过列表表达式循环遍历这个列表拿到每个对象,再从一个个对象里面找到Video,再从Video里面找到播放地址(play_addr),再从播放地址找到播放列表(url_list),播放列表有重复只要第一个
在这里插入图片描述
3.下载
在这里插入图片描述

2.并发获取短视频

在这里插入图片描述

3.JS逆向实战

3.1 对称加密(AES)

AES是一种对称加密,所谓对称加密就是加密与解密使用的秘钥是一个。key和iv必须一致

常见的对称加密: AES, DES, 3DES. 我们这里讨论AES。
安装:

pip install pycryptodome

AES 加密最常用的模式就是 CBC 模式和 ECB模式 ,当然还有很多其它模式,他们都属于AES加密。ECB模式和CBC 模式俩者区别就是 ECB 不需要 iv偏移量,而CBC需要。

"""
长度16: *AES-128*   24: *AES-192*32: *AES-256*MODE 加密模式. 常见的ECB, CBCECB:是一种基础的加密方式,密文被分割成分组长度相等的块(不足补齐),然后单独一个个加密,一个个输出组成密文。CBC:是一种循环模式,前一个分组的密文和当前分组的明文异或或操作后再加密,这样做的目的是增强破解难度。
"""

CBC加密案例(选择aes-128):先加密,再编码

from Crypto.Cipher import AES   # Crypto是一个算法库,Cipher有相应的算法,我们用AES
from Crypto.Util.Padding import pad     # 里面有个工具叫填充叫pad
import base64   # 64编码key = '0123456789abcdef'.encode()  # 秘钥: 因为aes-128模式,所以必须16字节
iv = 'abcdabcdabcdabcd'.encode() # 偏移量:因为aes-128模式,所以必须16字节
text = 'Self-improvement is a lifelong process!'  # 加密内容,因为aes-128模式,所以字节长度必须是16的倍数
# while len(text.encode('utf-8')) % 16 != 0:  # 如果text不足16位的倍数就用空格补足为16位
#     text += '\0'
text = pad(text.encode(), 16)   # pad在这里如果加密不足16位就会block_size:16填充
print("完整text:", text)aes = AES.new(key, AES.MODE_CBC, iv)  # 创建一个aes对象,传key,iv;中间值是个固定值模式,用AES中CBC模式en_text = aes.encrypt(text)  # 加密明文encrypt
print("aes加密数据:::", en_text)  # b"_\xf04\x7f/R\xef\xe9\x14#q\xd8A\x12\x8e\xe3\xa5\x93\x96'zOP\xc1\x85{\xad\xc2c\xddn\x86"en_text = base64.b64encode(en_text).decode()  # 将返回的字节型数据转进行base64编码,防止混淆,歧义
print(en_text)  #  Pwhs4f1/GxersDcWwZa6fxJTS4YfeV3FoOWvcq14jSLdG+clB/H3+kqBnAfwmZ03

在这里插入图片描述
CBC解密案例:先解码,再解密

from Crypto.Cipher import AES
import base64
from Crypto.Util.Padding import unpadkey = '0123456789abcdef'.encode()
iv = 'abcdabcdabcdabcd'.encode()
aes = AES.new(key, AES.MODE_CBC, iv)text = 'Pwhs4f1/GxersDcWwZa6fxJTS4YfeV3FoOWvcq14jSLdG+clB/H3+kqBnAfwmZ03'.encode()  # 需要解密的文本
ecrypted_base64 = base64.b64decode(text)  # base64解码成字节流
source = aes.decrypt(ecrypted_base64)  # 解密decrypt
print("aes解密数据:::", source.decode())
print("aes解密数据:::", unpad(source, 16).decode())

在这里插入图片描述

1.在Python中进行AES加密解密时,所传入的密文、明文、秘钥、iv偏移量、都需要是bytes(字节型)数据。python 在构建aes对象时也只能接受bytes类型数据。
2.当秘钥,iv偏移量,待加密的明文,字节长度不够16字节或者16字节倍数的时候需要进行补全。
3.CBC模式需要重新生成AES对象,为了防止这类错误,无论是什么模式都重新生成AES对象就可以了。

3.2 毛毛租的python逆向

毛毛租平台:https://www.maomaozu.com/#/build

在这里插入图片描述

3.2.1 加密

在这里插入图片描述
在这里插入图片描述
绝招:加一个断点
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
找key和iv:
在这里插入图片描述

3.2.2 解密

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

import jsonimport requests
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import base64cookies = {'PHPSESSID': '6rhg42ce8egfeulonevjnfj4sv','Hm_lvt_6cd598ca665714ffcd8aca3aafc5e0dc': '1706941076','SECKEY_ABVK': 'aJ99/mmPcgDcnVNO8MQjq74LRk9XDbNZo7uGOCGoln0%3D','Hm_lpvt_6cd598ca665714ffcd8aca3aafc5e0dc': '1706941479','BMAP_SECKEY': 'IN6Q3NYbpjYXemaxNcEdhP7dkIvDfrO09kOcuQx3rurdS546vjNWE-mY8RexJlLiLTvJaySgMcDcsFIr0mbjJKoCPrsissHnmXCxfpEUr4az4OxDtbb-s1bmRsoQs0yz9nVTEtFnE5dWUcYecms3m4YY8bV6rl2Sj6HvoQPViznasWG2OkGUebHlE5loh2dV',
}headers = {'Accept': '*/*','Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6','Cache-Control': 'no-cache','Connection': 'keep-alive','Content-Type': 'application/json; charset=UTF-8',# 'Cookie': 'PHPSESSID=6rhg42ce8egfeulonevjnfj4sv; Hm_lvt_6cd598ca665714ffcd8aca3aafc5e0dc=1706941076; SECKEY_ABVK=aJ99/mmPcgDcnVNO8MQjq74LRk9XDbNZo7uGOCGoln0%3D; Hm_lpvt_6cd598ca665714ffcd8aca3aafc5e0dc=1706941479; BMAP_SECKEY=IN6Q3NYbpjYXemaxNcEdhP7dkIvDfrO09kOcuQx3rurdS546vjNWE-mY8RexJlLiLTvJaySgMcDcsFIr0mbjJKoCPrsissHnmXCxfpEUr4az4OxDtbb-s1bmRsoQs0yz9nVTEtFnE5dWUcYecms3m4YY8bV6rl2Sj6HvoQPViznasWG2OkGUebHlE5loh2dV','Origin': 'https://www.maomaozu.com','Pragma': 'no-cache','Referer': 'https://www.maomaozu.com/','Sec-Fetch-Dest': 'empty','Sec-Fetch-Mode': 'cors','Sec-Fetch-Site': 'same-origin','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0','sec-ch-ua': '"Chromium";v="122", "Not(A:Brand";v="24", "Microsoft Edge";v="122"','sec-ch-ua-mobile': '?0','sec-ch-ua-platform': '"Windows"',
}# #   批量爬
# for i in range(1, 10):
#     data = {
#         "Type": 0,
#         "expire": 1706974966977,
#         "page": 5,
#     }
#
#     key = '55b3b62613aef1a0'.encode()
#     iv = '55b3b62613aef1a0'.encode()
#     text = json.dumps(data)
#
#     text = pad(text.encode(), 16)
#     print("完整text:", text)
#
#     aes = AES.new(key, AES.MODE_CBC, iv)  # 创建一个aes对象
#
#     en_text = aes.encrypt(text)  # 加密明文
#     print("aes加密数据:::", en_text)
#
#     en_text = base64.b64encode(en_text).decode()
#     print(en_text)
#
#     # data = 'i1gpLEJyKvluv3sQVGr/h6RZxT9vv00IpxineW3h2Y8GGtjqGm2Gl46nX7lTrD7H'   # 加密值
#
#     response = requests.post('https://www.maomaozu.com/index/build.json', cookies=cookies, headers=headers,
#                              data=en_text)
#     print(response.text)# 数据加密3个加密项
data = {"Type": 0,"expire": 1706974966977,"page": 5,
}key = '55b3b62613aef1a0'.encode()
iv = '55b3b62613aef1a0'.encode()
text = json.dumps(data)text = pad(text.encode(), 16)
print("完整text:", text)aes = AES.new(key, AES.MODE_CBC, iv)  # 创建一个aes对象en_text = aes.encrypt(text)  # 加密明文
print("aes加密数据:::", en_text)en_text = base64.b64encode(en_text).decode()
print(en_text)# data = 'i1gpLEJyKvluv3sQVGr/h6RZxT9vv00IpxineW3h2Y8GGtjqGm2Gl46nX7lTrD7H'   # 加密值response = requests.post('https://www.maomaozu.com/index/build.json', cookies=cookies, headers=headers, data=en_text)
print(response.text)# 解密数据逻辑
key = "0a1fea31626b3b55".encode()
iv = "0a1fea31626b3b55".encode()
aes = AES.new(key, AES.MODE_CBC, iv)ecrypted_base64 = base64.b64decode(response.text.encode())  # base64解码成字节流
source = aes.decrypt(ecrypted_base64)  # 解密
print("aes解密数据:::", source.decode())
print("aes解密数据:::", unpad(source, 16).decode())

三、JS逆向破解X-Bogus值

1.JS逆向实战破解X-Bogus值

X-Bogus:以DFS开头,总长28位

在这里插入图片描述
在这里插入图片描述
答案是X-Bogus,因为会把负载里面所有的值打包生成X-Boogus

1.1 找X-Bogus加密位置(请求堆栈)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.1.1 绝招加高级断点(日志断点)

日志断点看有没有X-B值
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
日志断点加上请求内容还是太多,下面看条件断点

1.1.2 绝招加高级断点(条件断点)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.1.3 做逆向(js逆向)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2. Python调用JS获取X-Bogus值

安装:

pip install pyExecJs
import execjswith open("douyin.js") as f:js_data = f.read()js_compile =execjs.compile(js_data)
xb_data =js_compile.call("window.xiaoc",)
print(xb_data)

在这里插入图片描述
在这里插入图片描述

import requests
import execjswith open("douying.js") as f:js_code = f.read()
js_compile = execjs.compile(js_code)
url = 'https://www.douyin.com/aweme/v1/web/aweme/post/?'
user_id = "MS4wLjABAAAA2WKmM-8lEtk72YjLLI6CFWFZRDtA_WtTUmg-5p7wHqI"
params = f"device_platform=webapp&aid=6383&channel=channel_pc_web&sec_user_id={user_id}&max_cursor=0&locate_query=false&show_live_replay_strategy=1&need_time_list=1&time_list_query=0&whale_cut_token=&cut_version=1&count=18&publish_video_strategy_type=2&pc_client_type=1&version_code=170400&version_name=17.4.0&cookie_enabled=true&screen_width=1536&screen_height=864&browser_language=zh-CN&browser_platform=Win32&browser_name=Edge&browser_version=122.0.0.0&browser_online=true&engine_name=Blink&engine_version=122.0.0.0&os_name=Windows&os_version=10&cpu_core_num=12&device_memory=8&platform=PC&downlink=10&effective_type=4g&round_trip_time=100&webid=7331003658269885952&msToken=i-THFcUZPJzlfcptH7pAamO1QadvQ88RnCYldJseXyIeYmMRC7guwnHnX0z6ENz1dxnyj-1QWQQLjqp9_pHjr8lU-MqWQ9g466pOEyefDAGUGskgcu6wkKoWNzH6"
x_b = js_compile.call("window.yuan", params)
print("xb:", x_b)new_url = url + params + "&X-Bogus=" + x_bheaders = {'authority': 'www.douyin.com','accept': 'application/json, text/plain, */*','accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6','cache-control': 'no-cache','cookie': 'ttwid=1%7CRJTTuwiJjYo8a1GXOAc0ysKVOH3AoSWjoA5U6N16pHk%7C1706882315%7C10741635cb69c8b1954456e49e85f1a8b629e3fe8266996d349e0165c31a4c5d; volume_info=%7B%22isUserMute%22%3Afalse%2C%22isMute%22%3Afalse%2C%22volume%22%3A0.7%7D; passport_csrf_token=2315da18ef8f1bd1c7d818260eae36b3; passport_csrf_token_default=2315da18ef8f1bd1c7d818260eae36b3; bd_ticket_guard_client_web_domain=2; ttcid=80c91cb353504f9fa1cbfd551625091119; SEARCH_RESULT_LIST_TYPE=%22single%22; FORCE_LOGIN=%7B%22videoConsumedRemainSeconds%22%3A180%2C%22isForcePopClose%22%3A1%7D; xgplayer_device_id=88169692726; xgplayer_user_id=821848890322; pwa2=%220%7C0%7C3%7C0%22; n_mh=j2Ixqzt56zfZqN7wQu0bsTqZmHMjmKDA8OWvBWdIfNw; passport_auth_status=ca6c3e1b67cbe85fe382b36d87909e47%2C; passport_auth_status_ss=ca6c3e1b67cbe85fe382b36d87909e47%2C; _bd_ticket_crypt_doamin=2; __security_server_data_status=1; store-region=cn-gs; store-region-src=uid; s_v_web_id=verify_ls4q16wq_gd9vvmzX_APhv_4s5s_BQWF_Kx0IHQHrC3eV; d_ticket=cc21dc4dd81ccb045d9f213894826fe819301; publish_badge_show_info=%221%2C0%2C0%2C1706883171006%22; sso_uid_tt=5ce4bf94843b5ceab602e1b8265103f2; sso_uid_tt_ss=5ce4bf94843b5ceab602e1b8265103f2; toutiao_sso_user=7c738c8c4feec8e0cd87a55f80fef383; toutiao_sso_user_ss=7c738c8c4feec8e0cd87a55f80fef383; uid_tt=2ebe791b464abe496f63029d978005c6; uid_tt_ss=2ebe791b464abe496f63029d978005c6; sid_tt=fde6df3996602ac63ddb768c5ae33686; sessionid=fde6df3996602ac63ddb768c5ae33686; sessionid_ss=fde6df3996602ac63ddb768c5ae33686; LOGIN_STATUS=1; _bd_ticket_crypt_cookie=3db9c81dd0322f1ee81e8cdfcd276366; download_guide=%223%2F20240203%2F0%22; stream_player_status_params=%22%7B%5C%22is_auto_play%5C%22%3A0%2C%5C%22is_full_screen%5C%22%3A0%2C%5C%22is_full_webscreen%5C%22%3A0%2C%5C%22is_mute%5C%22%3A0%2C%5C%22is_speed%5C%22%3A1%2C%5C%22is_visible%5C%22%3A0%7D%22; passport_assist_user=CkFNOzqmwHfXWRP4fyG05ko4_tavdpx5sOdpxaxaZb3KerJKAvnQ_EYX2N_zqxeqcAxJbfoIF_jeWbGmfp6nO2aTsBpKCjxUSrMbw60tg9cAtd0mQvsBdPCiBm2_h2p-EF-YIhSA10b_92HZgF0oetw9H9Av8ThB2baI3o-zq5ptELsQ377IDRiJr9ZUIAEiAQMx5xgb; sid_ucp_sso_v1=1.0.0-KDYwMjEyMmJmYzk2NzlmZDAyZWQ5NzBkNzFlYzllMjQ1ZDJlMWY5NDIKIQjN9LDFnfTrAhDaxv6tBhjvMSAMMPmV9vgFOAVA-wdIAxoCbGYiIDdjNzM4YzhjNGZlZWM4ZTBjZDg3YTU1ZjgwZmVmMzgz; ssid_ucp_sso_v1=1.0.0-KDYwMjEyMmJmYzk2NzlmZDAyZWQ5NzBkNzFlYzllMjQ1ZDJlMWY5NDIKIQjN9LDFnfTrAhDaxv6tBhjvMSAMMPmV9vgFOAVA-wdIAxoCbGYiIDdjNzM4YzhjNGZlZWM4ZTBjZDg3YTU1ZjgwZmVmMzgz; sid_guard=fde6df3996602ac63ddb768c5ae33686%7C1707058010%7C5184000%7CThu%2C+04-Apr-2024+14%3A46%3A50+GMT; sid_ucp_v1=1.0.0-KDgyY2IyM2Y3NzRhODEzZjY4YTg0MjhhZjQ2Mjg5YmYwN2U3NTgxMzMKGwjN9LDFnfTrAhDaxv6tBhjvMSAMOAVA-wdIBBoCbHEiIGZkZTZkZjM5OTY2MDJhYzYzZGRiNzY4YzVhZTMzNjg2; ssid_ucp_v1=1.0.0-KDgyY2IyM2Y3NzRhODEzZjY4YTg0MjhhZjQ2Mjg5YmYwN2U3NTgxMzMKGwjN9LDFnfTrAhDaxv6tBhjvMSAMOAVA-wdIBBoCbHEiIGZkZTZkZjM5OTY2MDJhYzYzZGRiNzY4YzVhZTMzNjg2; odin_tt=15ed412c92f86046a1f66b145483d18abe524ff517a32e287576fbbfee99abf87fb4b8ab259662e67b01f22aa06d185e; __ac_nonce=065c109e900f165569cd2; __ac_signature=_02B4Z6wo00f01ziblOAAAIDAhWWIp6lmGeM4u5BAAKvyHpOmyrU6K4rSSVRojioj55mhOG-mKTbPjs-6kQzaUaBrWFogi-SAHv3zDTMm8UbiOwX1XPxgDOTr7qpvpa12HandEuX1fzU5t3DT1d; dy_swidth=1536; dy_sheight=864; csrf_session_id=17273b27de04f7773592476475360114; strategyABtestKey=%221707149804.686%22; msToken=p6X3LJVOnOsZfhXFO3WGU-vQNTBIcLa7dg4sB05ADylBkkt9qrWQevh6eaZZU652-TDp_8f80ZNGFNlUd9ap-dzG_C74z_v6u8VA1Fg156ZmACGi1fQ=; home_can_add_dy_2_desktop=%220%22; IsDouyinActive=true; stream_recommend_feed_params=%22%7B%5C%22cookie_enabled%5C%22%3Atrue%2C%5C%22screen_width%5C%22%3A1536%2C%5C%22screen_height%5C%22%3A864%2C%5C%22browser_online%5C%22%3Atrue%2C%5C%22cpu_core_num%5C%22%3A12%2C%5C%22device_memory%5C%22%3A8%2C%5C%22downlink%5C%22%3A10%2C%5C%22effective_type%5C%22%3A%5C%224g%5C%22%2C%5C%22round_trip_time%5C%22%3A150%7D%22; msToken=i-THFcUZPJzlfcptH7pAamO1QadvQ88RnCYldJseXyIeYmMRC7guwnHnX0z6ENz1dxnyj-1QWQQLjqp9_pHjr8lU-MqWQ9g466pOEyefDAGUGskgcu6wkKoWNzH6; FOLLOW_NUMBER_YELLOW_POINT_INFO=%22MS4wLjABAAAAaGmtHScBtHcQitX8N9xUsNBdYVG4USCnwCrcjubaRP_o8UgL_J7Gmki9xuE6bbqL%2F1707235200000%2F0%2F0%2F1707152072578%22; bd_ticket_guard_client_data=eyJiZC10aWNrZXQtZ3VhcmQtdmVyc2lvbiI6MiwiYmQtdGlja2V0LWd1YXJkLWl0ZXJhdGlvbi12ZXJzaW9uIjoxLCJiZC10aWNrZXQtZ3VhcmQtcmVlLXB1YmxpYy1rZXkiOiJCSEd3amJDZWRrRGQvRmxIYjJJU3JuVVFERDNQakt3ZTdwaDZjWWlOR3VBTy9hUWlPbittMVpZQUNpWmJzRFJMWGxOWmp3ak04c0lURElRbVludEtqNlU9IiwiYmQtdGlja2V0LWd1YXJkLXdlYi12ZXJzaW9uIjoxfQ%3D%3D; tt_scid=B6.qvhXzjKAHGQyeSuXGsra-IPcCo.sMCBwCjy7OHMNlfgpsijh9lnDDeIxlH2QXae71; passport_fe_beating_status=true','pragma': 'no-cache','referer': 'https://www.douyin.com/user/MS4wLjABAAAA2WKmM-8lEtk72YjLLI6CFWFZRDtA_WtTUmg-5p7wHqI','sec-ch-ua': '"Chromium";v="122", "Not(A:Brand";v="24", "Microsoft Edge";v="122"','sec-ch-ua-mobile': '?0','sec-ch-ua-platform': '"Windows"','sec-fetch-dest': 'empty','sec-fetch-mode': 'cors','sec-fetch-site': 'same-origin','user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0',
}response = requests.get(new_url,headers=headers)print(response.text)

3. 下载视频

在这里插入图片描述
完整代码:
JS逆向crawler douyinshipin

import requests
import execjs
import threading
with open("douying.js") as f:js_code = f.read()
js_compile = execjs.compile(js_code)
url = 'https://www.douyin.com/aweme/v1/web/aweme/post/?'
user_id = "MS4wLjABAAAA2WKmM-8lEtk72YjLLI6CFWFZRDtA_WtTUmg-5p7wHqI"
params = f"device_platform=webapp&aid=6383&channel=channel_pc_web&sec_user_id={user_id}&max_cursor=0&locate_query=false&show_live_replay_strategy=1&need_time_list=1&time_list_query=0&whale_cut_token=&cut_version=1&count=18&publish_video_strategy_type=2&pc_client_type=1&version_code=170400&version_name=17.4.0&cookie_enabled=true&screen_width=1536&screen_height=864&browser_language=zh-CN&browser_platform=Win32&browser_name=Edge&browser_version=122.0.0.0&browser_online=true&engine_name=Blink&engine_version=122.0.0.0&os_name=Windows&os_version=10&cpu_core_num=12&device_memory=8&platform=PC&downlink=10&effective_type=4g&round_trip_time=100&webid=7331003658269885952&msToken=i-THFcUZPJzlfcptH7pAamO1QadvQ88RnCYldJseXyIeYmMRC7guwnHnX0z6ENz1dxnyj-1QWQQLjqp9_pHjr8lU-MqWQ9g466pOEyefDAGUGskgcu6wkKoWNzH6"
x_b = js_compile.call("window.yuan", params)
print("xb:", x_b)new_url = url + params + "&X-Bogus=" + x_bheaders = {'authority': 'www.douyin.com','accept': 'application/json, text/plain, */*','accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6','cache-control': 'no-cache','cookie': 'ttwid=1%7CRJTTuwiJjYo8a1GXOAc0ysKVOH3AoSWjoA5U6N16pHk%7C1706882315%7C10741635cb69c8b1954456e49e85f1a8b629e3fe8266996d349e0165c31a4c5d; volume_info=%7B%22isUserMute%22%3Afalse%2C%22isMute%22%3Afalse%2C%22volume%22%3A0.7%7D; passport_csrf_token=2315da18ef8f1bd1c7d818260eae36b3; passport_csrf_token_default=2315da18ef8f1bd1c7d818260eae36b3; bd_ticket_guard_client_web_domain=2; ttcid=80c91cb353504f9fa1cbfd551625091119; SEARCH_RESULT_LIST_TYPE=%22single%22; FORCE_LOGIN=%7B%22videoConsumedRemainSeconds%22%3A180%2C%22isForcePopClose%22%3A1%7D; xgplayer_device_id=88169692726; xgplayer_user_id=821848890322; pwa2=%220%7C0%7C3%7C0%22; n_mh=j2Ixqzt56zfZqN7wQu0bsTqZmHMjmKDA8OWvBWdIfNw; passport_auth_status=ca6c3e1b67cbe85fe382b36d87909e47%2C; passport_auth_status_ss=ca6c3e1b67cbe85fe382b36d87909e47%2C; _bd_ticket_crypt_doamin=2; __security_server_data_status=1; store-region=cn-gs; store-region-src=uid; s_v_web_id=verify_ls4q16wq_gd9vvmzX_APhv_4s5s_BQWF_Kx0IHQHrC3eV; d_ticket=cc21dc4dd81ccb045d9f213894826fe819301; publish_badge_show_info=%221%2C0%2C0%2C1706883171006%22; sso_uid_tt=5ce4bf94843b5ceab602e1b8265103f2; sso_uid_tt_ss=5ce4bf94843b5ceab602e1b8265103f2; toutiao_sso_user=7c738c8c4feec8e0cd87a55f80fef383; toutiao_sso_user_ss=7c738c8c4feec8e0cd87a55f80fef383; uid_tt=2ebe791b464abe496f63029d978005c6; uid_tt_ss=2ebe791b464abe496f63029d978005c6; sid_tt=fde6df3996602ac63ddb768c5ae33686; sessionid=fde6df3996602ac63ddb768c5ae33686; sessionid_ss=fde6df3996602ac63ddb768c5ae33686; LOGIN_STATUS=1; _bd_ticket_crypt_cookie=3db9c81dd0322f1ee81e8cdfcd276366; download_guide=%223%2F20240203%2F0%22; stream_player_status_params=%22%7B%5C%22is_auto_play%5C%22%3A0%2C%5C%22is_full_screen%5C%22%3A0%2C%5C%22is_full_webscreen%5C%22%3A0%2C%5C%22is_mute%5C%22%3A0%2C%5C%22is_speed%5C%22%3A1%2C%5C%22is_visible%5C%22%3A0%7D%22; passport_assist_user=CkFNOzqmwHfXWRP4fyG05ko4_tavdpx5sOdpxaxaZb3KerJKAvnQ_EYX2N_zqxeqcAxJbfoIF_jeWbGmfp6nO2aTsBpKCjxUSrMbw60tg9cAtd0mQvsBdPCiBm2_h2p-EF-YIhSA10b_92HZgF0oetw9H9Av8ThB2baI3o-zq5ptELsQ377IDRiJr9ZUIAEiAQMx5xgb; sid_ucp_sso_v1=1.0.0-KDYwMjEyMmJmYzk2NzlmZDAyZWQ5NzBkNzFlYzllMjQ1ZDJlMWY5NDIKIQjN9LDFnfTrAhDaxv6tBhjvMSAMMPmV9vgFOAVA-wdIAxoCbGYiIDdjNzM4YzhjNGZlZWM4ZTBjZDg3YTU1ZjgwZmVmMzgz; ssid_ucp_sso_v1=1.0.0-KDYwMjEyMmJmYzk2NzlmZDAyZWQ5NzBkNzFlYzllMjQ1ZDJlMWY5NDIKIQjN9LDFnfTrAhDaxv6tBhjvMSAMMPmV9vgFOAVA-wdIAxoCbGYiIDdjNzM4YzhjNGZlZWM4ZTBjZDg3YTU1ZjgwZmVmMzgz; sid_guard=fde6df3996602ac63ddb768c5ae33686%7C1707058010%7C5184000%7CThu%2C+04-Apr-2024+14%3A46%3A50+GMT; sid_ucp_v1=1.0.0-KDgyY2IyM2Y3NzRhODEzZjY4YTg0MjhhZjQ2Mjg5YmYwN2U3NTgxMzMKGwjN9LDFnfTrAhDaxv6tBhjvMSAMOAVA-wdIBBoCbHEiIGZkZTZkZjM5OTY2MDJhYzYzZGRiNzY4YzVhZTMzNjg2; ssid_ucp_v1=1.0.0-KDgyY2IyM2Y3NzRhODEzZjY4YTg0MjhhZjQ2Mjg5YmYwN2U3NTgxMzMKGwjN9LDFnfTrAhDaxv6tBhjvMSAMOAVA-wdIBBoCbHEiIGZkZTZkZjM5OTY2MDJhYzYzZGRiNzY4YzVhZTMzNjg2; odin_tt=15ed412c92f86046a1f66b145483d18abe524ff517a32e287576fbbfee99abf87fb4b8ab259662e67b01f22aa06d185e; __ac_nonce=065c109e900f165569cd2; __ac_signature=_02B4Z6wo00f01ziblOAAAIDAhWWIp6lmGeM4u5BAAKvyHpOmyrU6K4rSSVRojioj55mhOG-mKTbPjs-6kQzaUaBrWFogi-SAHv3zDTMm8UbiOwX1XPxgDOTr7qpvpa12HandEuX1fzU5t3DT1d; dy_swidth=1536; dy_sheight=864; csrf_session_id=17273b27de04f7773592476475360114; strategyABtestKey=%221707149804.686%22; msToken=p6X3LJVOnOsZfhXFO3WGU-vQNTBIcLa7dg4sB05ADylBkkt9qrWQevh6eaZZU652-TDp_8f80ZNGFNlUd9ap-dzG_C74z_v6u8VA1Fg156ZmACGi1fQ=; home_can_add_dy_2_desktop=%220%22; IsDouyinActive=true; stream_recommend_feed_params=%22%7B%5C%22cookie_enabled%5C%22%3Atrue%2C%5C%22screen_width%5C%22%3A1536%2C%5C%22screen_height%5C%22%3A864%2C%5C%22browser_online%5C%22%3Atrue%2C%5C%22cpu_core_num%5C%22%3A12%2C%5C%22device_memory%5C%22%3A8%2C%5C%22downlink%5C%22%3A10%2C%5C%22effective_type%5C%22%3A%5C%224g%5C%22%2C%5C%22round_trip_time%5C%22%3A150%7D%22; msToken=i-THFcUZPJzlfcptH7pAamO1QadvQ88RnCYldJseXyIeYmMRC7guwnHnX0z6ENz1dxnyj-1QWQQLjqp9_pHjr8lU-MqWQ9g466pOEyefDAGUGskgcu6wkKoWNzH6; FOLLOW_NUMBER_YELLOW_POINT_INFO=%22MS4wLjABAAAAaGmtHScBtHcQitX8N9xUsNBdYVG4USCnwCrcjubaRP_o8UgL_J7Gmki9xuE6bbqL%2F1707235200000%2F0%2F0%2F1707152072578%22; bd_ticket_guard_client_data=eyJiZC10aWNrZXQtZ3VhcmQtdmVyc2lvbiI6MiwiYmQtdGlja2V0LWd1YXJkLWl0ZXJhdGlvbi12ZXJzaW9uIjoxLCJiZC10aWNrZXQtZ3VhcmQtcmVlLXB1YmxpYy1rZXkiOiJCSEd3amJDZWRrRGQvRmxIYjJJU3JuVVFERDNQakt3ZTdwaDZjWWlOR3VBTy9hUWlPbittMVpZQUNpWmJzRFJMWGxOWmp3ak04c0lURElRbVludEtqNlU9IiwiYmQtdGlja2V0LWd1YXJkLXdlYi12ZXJzaW9uIjoxfQ%3D%3D; tt_scid=B6.qvhXzjKAHGQyeSuXGsra-IPcCo.sMCBwCjy7OHMNlfgpsijh9lnDDeIxlH2QXae71; passport_fe_beating_status=true','pragma': 'no-cache','referer': 'https://www.douyin.com/user/MS4wLjABAAAA2WKmM-8lEtk72YjLLI6CFWFZRDtA_WtTUmg-5p7wHqI','sec-ch-ua': '"Chromium";v="122", "Not(A:Brand";v="24", "Microsoft Edge";v="122"','sec-ch-ua-mobile': '?0','sec-ch-ua-platform': '"Windows"','sec-fetch-dest': 'empty','sec-fetch-mode': 'cors','sec-fetch-site': 'same-origin','user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0',
}response = requests.get(new_url,headers=headers)# print(response.text)aweme_list = response.json().get("aweme_list")url_list = [aweme.get("video").get("play_addr").get("url_list")[0] for aweme in aweme_list] # 加起来形成一个完整地址,取video里面的play_addr里面url_list的第一个地址(播放列表有重复的取第一个)(查看网页预览一步一步点)
# print(url_list)# 下载短视频def get_one_video(url, c):res = requests.get(url)# 文件写操作with open(f"./videos/{c}.mp4", "wb") as f:  # w:写文本 wb写字节f.write(res.content)print(f"{c}.mp4下载成功!")c = 1
t_list = []
for url in url_list:t = threading.Thread(target=get_one_video, args=(url, c))t.start()t_list.append(t)c += 1for t in t_list:t.join()    # 遍历t_list里面所有的线程对象,等待所有的都执行完join才通过

四、图片验证码、打码平台、JS逆向将加密拿到本地

1.图片验证码

import requestsres = requests.get('https://www.gushiwen.cn/RandCode.ashx')with open("code.png", "wb") as f:f.write(res.content)

在这里插入图片描述

2.打码平台

网址:http://www.ttshitu.com/,找到开发文档点击Python,没有钱了要用我的账号密码,充钱

import base64
import json
import requests# 一、图片文字类型(默认 3 数英混合):
# 1 : 纯数字
# 1001:纯数字2
# 2 : 纯英文
# 1002:纯英文2
# 3 : 数英混合
# 1003:数英混合2
#  4 : 闪动GIF
# 7 : 无感学习(独家)
# 11 : 计算题
# 1005:  快速计算题
# 16 : 汉字
# 32 : 通用文字识别(证件、单据)
# 66:  问答题
# 49 :recaptcha图片识别
# 二、图片旋转角度类型:
# 29 :  旋转类型
#
# 三、图片坐标点选类型:
# 19 :  1个坐标
# 20 :  3个坐标
# 21 :  3 ~ 5个坐标
# 22 :  5 ~ 8个坐标
# 27 :  1 ~ 4个坐标
# 48 : 轨迹类型
#
# 四、缺口识别
# 18 : 缺口识别(需要2张图 一张目标图一张缺口图)
# 33 : 单缺口识别(返回X轴坐标 只需要1张图)
# 五、拼图识别
# 53:拼图识别
def base64_api(uname, pwd, img, typeid):with open(img, 'rb') as f:base64_data = base64.b64encode(f.read())b64 = base64_data.decode()data = {"username": uname, "password": pwd, "typeid": typeid, "image": b64}result = json.loads(requests.post("http://api.ttshitu.com/predict", json=data).text)if result['success']:return result["data"]["result"]else:# !!!!!!!注意:返回 人工不足等 错误情况 请加逻辑处理防止脚本卡死 继续重新 识别return result["message"]return ""if __name__ == "__main__":img_path = "code.png"result = base64_api(uname='stara', pwd='050611zZ', img=img_path, typeid=3)print(result)

在这里插入图片描述

3. JS逆向案例

一品威客网站:https://www.epwk.com/login.html

抓包分析

在这里插入图片描述

在这里插入图片描述
复制cURL,写爬虫代码

import requestscookies = {'Hm_lvt_387b8f4fdb89d4ea233922bdc6466394': '1709892079','PHPSESSID': 'a3c14f78e68b82a9c91d890fcc45b15d313e35f4','time_diff': '1','XDEBUG_SESSION': 'XDEBUG_ECLIPSE','adbanner_city': '%E5%85%B0%E5%B7%9E%E5%B8%82','Hm_lpvt_387b8f4fdb89d4ea233922bdc6466394': '1709894677','login_fail_need_graphics': '0',
}headers = {'Accept': 'application/json, text/plain, */*','Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6','Access-Token': '','App-Id': '4ac490420ac63db4','App-Ver': '','CHOST': 'www.epwk.com','Cache-Control': 'no-cache','Connection': 'keep-alive','Content-Type': 'application/x-www-form-urlencoded',# 'Cookie': 'Hm_lvt_387b8f4fdb89d4ea233922bdc6466394=1709892079; PHPSESSID=a3c14f78e68b82a9c91d890fcc45b15d313e35f4; time_diff=1; XDEBUG_SESSION=XDEBUG_ECLIPSE; adbanner_city=%E5%85%B0%E5%B7%9E%E5%B8%82; Hm_lpvt_387b8f4fdb89d4ea233922bdc6466394=1709894677; login_fail_need_graphics=0','Device-Os': 'web','Device-Ver': '','Imei': '','NonceStr': '1709894743bnhju','Origin': 'https://www.epwk.com','Os-Ver': '','Pragma': 'no-cache','Referer': 'https://www.epwk.com/login.html','Sec-Fetch-Dest': 'empty','Sec-Fetch-Mode': 'cors','Sec-Fetch-Site': 'same-origin','Signature': 'lvSv16nUQ71tdqkhzS/g7l/HiQXeib5mZIAyFnBLrLhhiZkoGTiV8OXfe6aqMvgY','Timestemp': '1709894743','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0','X-REQUEST-ID': 'ed47d61b77278235b96b8f6c92a54810','sec-ch-ua': '"Chromium";v="124", "Microsoft Edge";v="124", "Not-A.Brand";v="99"','sec-ch-ua-mobile': '?0','sec-ch-ua-platform': '"Windows"',
}data = {'username': 'eeeeeeeeeeeeeeeeeeee','password': 'eeeeeeeeeeeeeeeeeeeeeeee','code': '7y9a','hdn_refer': '',
}response = requests.post('https://www.epwk.com/api/epwk/v1/user/login', cookies=cookies, headers=headers, data=data)
print(response.text)

在这里插入图片描述

3.1 查看Signature值到底是怎么加密生成的(关键字查询)

Signature应该是有一个函数固定生成加密值的,结构应该是Signature=函数()
在这里插入图片描述
加断点
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.2 JS逆向实现

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

JS源代码:

const cryptojs = require("crypto-js")l = {key: cryptojs.enc.Utf8.parse("fX@VyCQVvpdj8RCa"),iv: cryptojs.enc.Utf8.parse(function (t) {for (var e = "", i = 0; i < t.length - 1; i += 2) {var n = parseInt(t[i] + "" + t[i + 1], 16);e += String.fromCharCode(n)}return e}("00000000000000000000000000000000"))
}, v = function (data) {return function (data) {return cryptojs.AES.encrypt(data, l.key, {iv: l.iv,mode: cryptojs.mode.CBC,padding: cryptojs.pad.Pkcs7}).toString()}(data)
}, d = function (data) {return cryptojs.MD5(data).toString()
}, f = function (t) {var e = "";return Object.keys(t).sort().forEach((function (n) {e += n + ("object" === typeof (t[n]) ? JSON.stringify(t[n], (function (t, e) {return "number" == typeof e && (e = String(e)),e})).replace(/\//g, "\\/") : t[n])})),e
}h = function (t) {var data = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, e = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : "a75846eb4ac490420ac63db46d2a03bf", n = e + f(data) + f(t) + e;return n = d(n),n = v(n)
}U = {"App-Ver": "","Os-Ver": "","Device-Ver": "","Imei": "","Access-Token": "","Timestemp": 1709898581,"NonceStr": "1709898581goio1","App-Id": "4ac490420ac63db4","Device-Os": "web"
}M = {"username": "eeeeeeeeeeeeeeeeeeee","password": "eeeeeeeeeeee","code": "n5a7","hdn_refer": ""
}C = 'a75846eb4ac490420ac63db46d2a03bf'console.log(h(U, M, C))
mport requests
import execjs
import jsondef base64_api(base64_img, typeid=3):data = {"username": "yuan0316", "password": "yuan0316", "typeid": typeid, "image": base64_img}result = json.loads(requests.post("http://api.ttshitu.com/predict", json=data).text)if result['success']:return result["data"]["result"]else:# !!!!!!!注意:返回 人工不足等 错误情况 请加逻辑处理防止脚本卡死 继续重新 识别return result["message"]return ""with open("yipinweike.js") as f:js_code = f.read()js_compile = execjs.compile(js_code)data = {}
headers = js_compile.call("fn", data)
print(headers)url = "https://www.epwk.com/api/epwk/v1/captcha/show?channel=common_channel&base64=1"
res = requests.get(url, headers=headers)
base64_img = res.json().get("data").get("base64")
code = base64_api(base64_img)
print(code)data = {"username": "121232312","password": "1231232131","code": code,"hdn_refer": "https://www.epwk.com/"
}
headers = js_compile.call("fn", data)
print(headers)url = "https://www.epwk.com/api/epwk/v1/user/login"res = requests.post(url, headers=headers, data=data)
print(res.text)

五、前端JS相关环境编译,node.js和pyexecjs抓取

1. 前端JS相关

  • 三元运算
v1 = 条件 ? 值A : 值B;		# 如果条件成立v1=值A,不成立v1等于值Bres = 1 === 1 ? 99 : 88 			# res=99
  • 特殊的逻辑运算
v1 = 1===1 || 2===2			# Ture
v2 = 9 || 14   				# 9
v3 = 0 || 15   				# 15
v3 = 0 || 15 || "zhangfei"		# 15
  • 赋值和比较
v1 = 11 === (n=123)		# Flase
  • 案例:
v1 = 1 > ( n = 2) || 1 === 1 ? 9 :8		# 分析
n = 2
v1 = 9
var o = (null === (n = window.byted_acrawler) || void 0 === n ? void 0 : null === (a = n.sign) || void 0 === a ? void 0 : a.call(n, i)) || "";void 0 -> undifined
# 分析(window.byted_acrawler不为空、window.byted_acrawler.sign不为空)
var o = (null === (n = window.byted_acrawler) || void 0 === n ? void 0 : null === (a = n.sign) || void 0 === a ? void 0 : a.call(n, i)) || "";var o = window.byted_acrawler.sign.call(n,i) || ""var o = window.byted_acrawler.sign.call(n,i)
  • 执行函数
function sign(v1){// this在函数内部console.log(v1);
}
// 执行,函数内部this=window全局对象
sign(123)			# 123// 执行函数内部会把第一个参数赋值给 this=123
sign.call(123,456)			# 456
// n就会传递给call函数中this
// i当做参数传递
var o = window.byted_acrawler.sign.call(n,i)
var o = window.byted_acrawler.sign(i)
  • 扩展
# 之前的javascript不支持面向对象,通过将函数去伪造
function Person(name,age){this.name=name;this.age = age
}obj = new Person("张飞",123)
  • 函数的参数
function sign(){console.log(arguments)
}sign()        
sign(11,22,33)
sign(11,22,44,55)
虽然没定义参数,但是可以传入参数
  • 合并对象补充JS环境
v1 = { k1: 123 }
v2 = { k2:99, k3:888}Objects.assign(v1,v2)	# 将第二个字典全部更新到V1;和python字典update很像console.log(v1) 			# {k1: 123, k2:99, k3:888}

2.编译js代码

2.1 node.js编译代码

  • v1.js
function func(arg) {return arg + 'i666';
}
let data = func("老铁");
console.log(data)
  • node编译执行
    在这里插入图片描述

  • python执行执行本地命令:node v1.js

import os
import subprocess# 根据自己的操作系统去修改(相当于python的sys.path,加载安装的模块)
os.environ["NODE_PATH"] = "/usr/local/lib/node_modules/"  signature = subprocess.getoutput('node v1.js')

2.2 pyexecjs编译代码

准备环境:

  • node.js
  • pyexecjs模块
pip install pyexecjs

例如:

  • v2.js
function func(arg) {return arg + '666';
}
  • 执行js代码
import execjs
import osos.environ["NODE_PATH"] = "/usr/local/lib/node_modules/"
with open('v2.js', mode='r', encoding='utf-8') as f:js = f.read()JS = execjs.compile(js)sign = JS.call("func", "微信")
print(sign) # 微信666

node.js:电脑上安装上node.js之后(编译器,相当于装CPython解释器), 自动安装npm(第三方包管理器,相当于pip)

2.3 浏览器环境

有些JS的代码你从别的地拿过来执行的时候不成功,因为需要模拟浏览器环境

环境准备

  • node.js
  • jsdom(通过后端node+js代码实现伪造浏览器环境)
npm install node-gyp@latest sudo npm explore -g npm -- npm i node-gyp@latest
npm install jsdom -g   # -g全局安装

注意:上述安装成功后已可以模拟浏览器环境,由于今天的头条他的内容。

npm install canvas -g

方式一:v10.js

const jsdom = require("jsdom");
const {JSDOM} = jsdom;const resourceLoader = new jsdom.ResourceLoader({userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36",
});const html = `<!DOCTYPE html><p>Hello world</p>`;const dom = new JSDOM(html, {url: "https://www.toutiao.com",referrer: "https://example.com/",contentType: "text/html",resources: resourceLoader,
});console.log(dom.window.location)
console.log(dom.window.navigator.userAgent)
console.log(dom.window.document.referrer)

在这里插入图片描述

import os
import subprocess# 根据自己的操作系统去修改(相当于python的sys.path,加载安装的模块)
os.environ["NODE_PATH"] = "/usr/local/lib/node_modules/"  res = subprocess.getoutput('node v10.js')

方式二:无法补充环境时

const jsdom = require("jsdom");
const {JSDOM} = jsdom;const resourceLoader = new jsdom.ResourceLoader({userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36"
});const html = `<!DOCTYPE html><p>Hello world</p>`;
const dom = new JSDOM(html, {url: "https://www.toutiao.com",referrer: "https://example.com/",contentType: "text/html",resources: resourceLoader,
});/*
console.log(dom.window.location)
console.log(dom.window.navigator.userAgent)
console.log(dom.window.document.referrer)
*/window = global;const params = {location: {hash: "",host: "www.toutiao.com",hostname: "www.toutiao.com",href: "https://www.toutiao.com",origin: "https://www.toutiao.com",pathname: "/",port: "",protocol: "https:",search: "",},navigator: {appCodeName: "Mozilla",appName: "Netscape",appVersion: "5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36",cookieEnabled: true,deviceMemory: 8,doNotTrack: null,hardwareConcurrency: 4,language: "zh-CN",languages: ["zh-CN", "zh"],maxTouchPoints: 0,onLine: true,platform: "MacIntel",product: "Gecko",productSub: "20030107",userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36",vendor: "Google Inc.",vendorSub: "",webdriver: false}
};Object.assign(global,params) 	# location、navigator设置成了全局变量# 在下面如果你使用location.href、navigator.appCodeName
我们在上面代码加入window = global这样window.location.href、window.appCodeName也能够获取到

注意:在nodejs中默认代码中会有一个global的关键字(全局变量)。

v1 = 123;  # 写了个全局变量,相当于global赋了个值
console.log(global);
global.v1 = 123
global.v2 = 123
global.navigator = {...
}
console.log(v1,v2);navigator.userAgent

3.头条(node.js实现)

3.1 分析请求

在这里插入图片描述
直接发送获取到结果:

import requests
# 这后面的就是我们需要注意的签名_02B4Z6wo009010IJgRwAAIDDtGCIOlEVa8tCLYWAALV5CV7lvAp2MWxOhC9EGgecK8orbBZu.elV57IoxY70Cqa8TI2XW0z.U3dOc84bBFDE83277HsB4oykmNYgkYd-9NbV8enDst.RVEBu76
res = requests.get(url="https://www.toutiao.com/api/pc/list/feed?offset=0&channel_id=94349549395&max_behot_time=0&category=pc_profile_channel&disable_raw_data=true&aid=24&app_name=toutiao_web&_signature=_02B4Z6wo009010IJgRwAAIDDtGCIOlEVa8tCLYWAALV5CV7lvAp2MWxOhC9EGgecK8orbBZu.elV57IoxY70Cqa8TI2XW0z.U3dOc84bBFDE83277HsB4oykmNYgkYd-9NbV8enDst.RVEBu76",headers={"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0"}
)print(res.text)

在这里插入图片描述

3.2 _signature(寻找签名因为具有失效性,假如操作体育可能就获取不到了)

在这里插入图片描述

var o = (null === (n = window.byted_acrawler) || void 0 === n || null === (a = n.sign) || void 0 === a ? void 0 : a.call(n, o)) || ""

在这里插入图片描述
在这里插入图片描述

n=undefined;
i={url:"https://www.toutiao.com/api/pc/list/feed?offset=0&channel_id=94349549395&max_behot_time=0&category=pc_profile_channel&disable_raw_data=true&aid=24&app_name=toutiao_web"}
var o = window.byted_acrawler.sign.call(n,i);

再简化一下

i={url:"https://www.toutiao.com/api/pc/list/feed?offset=0&channel_id=94349549395&max_behot_time=0&category=pc_profile_channel&disable_raw_data=true&aid=24&app_name=toutiao_web"}
var o = window.byted_acrawler.sign(i);
  • 找到sign算法,看看他是内部实现(走不通)。
  • 应该有一个js,给全局变量中赋值,
  • 整体调用试试看,把JS粘贴过来,找到了这个JS加载完之后赋的值
    在这里插入图片描述

在这里插入图片描述

3.3 验证签名是否可用

在这里插入图片描述

在这里插入图片描述

做一个拼接:url+&_signature=签名

https://www.toutiao.com/api/pc/list/feed?offset=0&channel_id=94349549395&max_behot_time=0&category=pc_profile_channel&disable_raw_data=true&aid=24&app_name=toutiao_web&_signature=_02B4Z6wo009010IJgRwAAIDDtGCIOlEVa8tCLYWAALV5CV7lvAp2MWxOhC9EGgecK8orbBZu.elV57IoxY70Cqa8TI2XW0z.U3dOc84bBFDE83277HsB4oykmNYgkYd-9NbV8enDst.RVEBu76& _signature=_02B4Z6wo00f01uuvg2AAAIDCHcaKRkpygJbrh4fAAN8p4e

在这里插入图片描述

import requestsres = requests.get(url="https://www.toutiao.com/api/pc/list/feed?offset=0&channel_id=94349549395&max_behot_time=0&category=pc_profile_channel&disable_raw_data=true&aid=24&app_name=toutiao_web&_signature=_02B4Z6wo009010IJgRwAAIDDtGCIOlEVa8tCLYWAALV5CV7lvAp2MWxOhC9EGgecK8orbBZu.elV57IoxY70Cqa8TI2XW0z.U3dOc84bBFDE83277HsB4oykmNYgkYd-9NbV8enDst.RVEBu76& _signature=_02B4Z6wo00f01uuvg2AAAIDCHcaKRkpygJbrh4fAAN8p4e",headers={"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0"}
)print(res.text)

3.4 补环境运行

在这里插入图片描述
在这里插入图片描述

v20.js

const jsdom = require("jsdom");
const {JSDOM} = jsdom;const resourceLoader = new jsdom.ResourceLoader({userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36"
});const html = `<!DOCTYPE html><p>Hello world</p>`;
const dom = new JSDOM(html, {url: "https://www.toutiao.com",referrer: "https://example.com/",contentType: "text/html",resources: resourceLoader,
});/*
console.log(dom.window.location)
console.log(dom.window.navigator.userAgent)
console.log(dom.window.document.referrer)
*/// 报错加入:既然要去读这个referrer,而它是去document里面读,那么写上个全局变量
document = dom.window.documentwindow = global;const params = {location: {hash: "",host: "www.toutiao.com",hostname: "www.toutiao.com",href: "https://www.toutiao.com",origin: "https://www.toutiao.com",pathname: "/",port: "",protocol: "https:",search: "",},navigator: {appCodeName: "Mozilla",appName: "Netscape",appVersion: "5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36",cookieEnabled: true,deviceMemory: 8,doNotTrack: null,hardwareConcurrency: 4,language: "zh-CN",languages: ["zh-CN", "zh"],maxTouchPoints: 0,onLine: true,platform: "MacIntel",product: "Gecko",productSub: "20030107",userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36",vendor: "Google Inc.",vendorSub: "",webdriver: false}
};Object.assign(global,params)// 以上为手动补充环境// var glb;
// (glb = "undefined" == typeof window ? global : window)
//  浏览器执行,在函数内部会创建一个全局变量 byted_acrawler   ===》》》 global
window._$jsvmprt = function(b, e, f) {function a() {if ("undefined" == typeof Reflect || !Reflect.construct)return !1;if (Reflect.construct.sham)return !1;if ("function" == typeof Proxy)return !0;try {return Date.prototype.toString.call(Reflect.construct(Date, [], (function() {}))),!0} catch (b) {return !1}}function d(b, e, f) {return (d = a() ? Reflect.construct : function(b, e, f) {var a = [null];a.push.apply(a, e);var d = new (Function.bind.apply(b, a));return f && c(d, f.prototype),d}).apply(null, arguments)}function c(b, e) {return (c = Object.setPrototypeOf || function(b, e) {return b.__proto__ = e,b})(b, e)}function n(b) {return function(b) {if (Array.isArray(b)) {for (var e = 0, f = new Array(b.length); e < b.length; e++)f[e] = b[e];return f}}(b) || function(b) {if (Symbol.iterator in Object(b) || "[object Arguments]" === Object.prototype.toString.call(b))return Array.from(b)}(b) || function() {throw new TypeError("Invalid attempt to spread non-iterable instance")}()}for (var i = [], r = 0, t = [], o = 0, l = function(b, e) {var f = b[e++], a = b[e], d = parseInt("" + f + a, 16);if (d >> 7 == 0)return [1, d];if (d >> 6 == 2) {var c = parseInt("" + b[++e] + b[++e], 16);return d &= 63,[2, c = (d <<= 8) + c]}if (d >> 6 == 3) {var n = parseInt("" + b[++e] + b[++e], 16), i = parseInt("" + b[++e] + b[++e], 16);return d &= 63,[3, i = (d <<= 16) + (n <<= 8) + i]}}, u = function(b, e) {var f = parseInt("" + b[e] + b[e + 1], 16);return f = f > 127 ? -256 + f : f}, s = function(b, e) {var f = parseInt("" + b[e] + b[e + 1] + b[e + 2] + b[e + 3], 16);return f = f > 32767 ? -65536 + f : f}, p = function(b, e) {var f = parseInt("" + b[e] + b[e + 1] + b[e + 2] + b[e + 3] + b[e + 4] + b[e + 5] + b[e + 6] + b[e + 7], 16);return f = f > 2147483647 ? 0 + f : f}, y = function(b, e) {return parseInt("" + b[e] + b[e + 1], 16)}, v = function(b, e) {return parseInt("" + b[e] + b[e + 1] + b[e + 2] + b[e + 3], 16)}, g = g || this || window, h = Object.keys || function(b) {var e = {}, f = 0;for (var a in b)e[f++] = a;return e.length = f,e}, m = (b.length,0), I = "", C = m; C < m + 16; C++) {var q = "" + b[C++] + b[C];q = parseInt(q, 16),I += String.fromCharCode(q)}if ("HNOJ@?RC" != I)throw new Error("error magic number " + I);m += 16;parseInt("" + b[m] + b[m + 1], 16);m += 8,r = 0;for (var w = 0; w < 4; w++) {var S = m + 2 * w, R = "" + b[S++] + b[S], x = parseInt(R, 16);r += (3 & x) << 2 * w}m += 16,m += 8;var z = parseInt("" + b[m] + b[m + 1] + b[m + 2] + b[m + 3] + b[m + 4] + b[m + 5] + b[m + 6] + b[m + 7], 16), O = z, E = m += 8, j = v(b, m += z);j[1];m += 4,i = {p: [],q: []};for (var A = 0; A < j; A++) {for (var D = l(b, m), T = m += 2 * D[0], $ = i.p.length, P = 0; P < D[1]; P++) {var U = l(b, T);i.p.push(U[1]),T += 2 * U[0]}m = T,i.q.push([$, i.p.length])}var _ = {5: 1,6: 1,70: 1,22: 1,23: 1,37: 1,73: 1}, k = {72: 1}, M = {74: 1}, H = {11: 1,12: 1,24: 1,26: 1,27: 1,31: 1}, J = {10: 1}, N = {2: 1,29: 1,30: 1,20: 1}, B = [], W = [];function F(b, e, f) {for (var a = e; a < e + f; ) {var d = y(b, a);B[a] = d,a += 2;k[d] ? (W[a] = u(b, a),a += 2) : _[d] ? (W[a] = s(b, a),a += 4) : M[d] ? (W[a] = p(b, a),a += 8) : H[d] ? (W[a] = y(b, a),a += 2) : J[d] ? (W[a] = v(b, a),a += 4) : N[d] && (W[a] = v(b, a),a += 4)}}return K(b, E, O / 2, [], e, f);function G(b, e, f, a, c, l, m, I) {null == l && (l = this);var C, q, w, S = [], R = 0;m && (C = m);var x, z, O = e, E = O + 2 * f;if (!I)for (; O < E; ) {var j = parseInt("" + b[O] + b[O + 1], 16);O += 2;var A = 3 & (x = 13 * j % 241);if (x >>= 2,A < 1) {A = 3 & x;if (x >>= 2,A > 2)(A = x) > 10 ? S[++R] = void 0 : A > 1 ? (C = S[R--],S[R] = S[R] >= C) : A > -1 && (S[++R] = null);else if (A > 1) {if ((A = x) > 11)throw S[R--];if (A > 7) {for (C = S[R--],z = v(b, O),A = "",P = i.q[z][0]; P < i.q[z][1]; P++)A += String.fromCharCode(r ^ i.p[P]);O += 4,S[R--][A] = C} elseA > 5 && (S[R] = h(S[R]))} else if (A > 0) {(A = x) > 8 ? (C = S[R--],S[R] = typeof C) : A > 6 ? S[R] = --S[R] : A > 4 ? S[R -= 1] = S[R][S[R + 1]] : A > 2 && (q = S[R--],(A = S[R]).x === G ? A.y >= 1 ? S[R] = K(b, A.c, A.l, [q], A.z, w, null, 1) : (S[R] = K(b, A.c, A.l, [q], A.z, w, null, 0),A.y++) : S[R] = A(q))} else {if ((A = x) > 14)z = s(b, O),(U = function e() {var f = arguments;return e.y > 0 ? K(b, e.c, e.l, f, e.z, this, null, 0) : (e.y++,K(b, e.c, e.l, f, e.z, this, null, 0))}).c = O + 4,U.l = z - 2,U.x = G,U.y = 0,U.z = c,S[R] = U,O += 2 * z - 2;else if (A > 12)q = S[R--],w = S[R--],(A = S[R--]).x === G ? A.y >= 1 ? S[++R] = K(b, A.c, A.l, q, A.z, w, null, 1) : (S[++R] = K(b, A.c, A.l, q, A.z, w, null, 0),A.y++) : S[++R] = A.apply(w, q);else if (A > 5)C = S[R--],S[R] = S[R] != C;else if (A > 3)C = S[R--],S[R] = S[R] * C;else if (A > -1)return [1, S[R--]]}} else if (A < 2) {A = 3 & x;if (x >>= 2,A < 1) {if ((A = x) > 9);else if (A > 7)C = S[R--],S[R] = S[R] & C;else if (A > 5)z = y(b, O),O += 2,S[R -= z] = 0 === z ? new S[R] : d(S[R], n(S.slice(R + 1, R + z + 1)));else if (A > 3) {z = s(b, O);try {if (t[o][2] = 1,1 == (C = G(b, O + 4, z - 3, [], c, l, null, 0))[0])return C} catch (m) {if (t[o] && t[o][1] && 1 == (C = G(b, t[o][1][0], t[o][1][1], [], c, l, m, 0))[0])return C} finally {if (t[o] && t[o][0] && 1 == (C = G(b, t[o][0][0], t[o][0][1], [], c, l, null, 0))[0])return C;t[o] = 0,o--}O += 2 * z - 2}} else if (A < 2) {if ((A = x) > 12)S[++R] = u(b, O),O += 2;else if (A > 10)C = S[R--],S[R] = S[R] << C;else if (A > 8) {for (z = v(b, O),A = "",P = i.q[z][0]; P < i.q[z][1]; P++)A += String.fromCharCode(r ^ i.p[P]);O += 4,S[R] = S[R][A]} elseA > 6 && (q = S[R--],C = delete S[R--][q])} else if (A < 3) {(A = x) < 2 ? S[++R] = C : A < 4 ? (C = S[R--],S[R] = S[R] <= C) : A < 11 ? (C = S[R -= 2][S[R + 1]] = S[R + 2],R--) : A < 13 && (C = S[R],S[++R] = C)} else {if ((A = x) > 12)S[++R] = l;else if (A > 5)C = S[R--],S[R] = S[R] !== C;else if (A > 3)C = S[R--],S[R] = S[R] / C;else if (A > 1) {if ((z = s(b, O)) < 0) {I = 1,F(b, e, 2 * f),O += 2 * z - 2;break}O += 2 * z - 2} elseA > -1 && (S[R] = !S[R])}} else if (A < 3) {A = 3 & x;if (x >>= 2,A > 2)(A = x) > 7 ? (C = S[R--],S[R] = S[R] | C) : A > 5 ? (z = y(b, O),O += 2,S[++R] = c["$" + z]) : A > 3 && (z = s(b, O),t[o][0] && !t[o][2] ? t[o][1] = [O + 4, z - 3] : t[o++] = [0, [O + 4, z - 3], 0],O += 2 * z - 2);else if (A > 1) {if ((A = x) < 2) {for (z = v(b, O),C = "",P = i.q[z][0]; P < i.q[z][1]; P++)C += String.fromCharCode(r ^ i.p[P]);S[++R] = C,O += 4} else if (A < 4)if (S[R--])O += 4;else {if ((z = s(b, O)) < 0) {I = 1,F(b, e, 2 * f),O += 2 * z - 2;break}O += 2 * z - 2}elseA < 6 ? (C = S[R--],S[R] = S[R] % C) : A < 8 ? (C = S[R--],S[R] = S[R]instanceof C) : A < 15 && (S[++R] = !1)} else if (A > 0) {(A = x) < 1 ? S[++R] = g : A < 3 ? (C = S[R--],S[R] = S[R] + C) : A < 5 ? (C = S[R--],S[R] = S[R] == C) : A < 14 && (C = S[R - 1],q = S[R],S[++R] = C,S[++R] = q)} else {(A = x) < 2 ? (C = S[R--],S[R] = S[R] > C) : A < 9 ? (z = v(b, O),O += 4,q = R + 1,S[R -= z - 1] = z ? S.slice(R, q) : []) : A < 11 ? (z = y(b, O),O += 2,C = S[R--],c[z] = C) : A < 13 ? (C = S[R--],S[R] = S[R] >> C) : A < 15 && (S[++R] = s(b, O),O += 4)}} else {A = 3 & x;if (x >>= 2,A > 2)(A = x) > 13 ? (S[++R] = p(b, O),O += 8) : A > 11 ? (C = S[R--],S[R] = S[R] >>> C) : A > 9 ? S[++R] = !0 : A > 7 ? (z = y(b, O),O += 2,S[R] = S[R][z]) : A > 0 && (C = S[R--],S[R] = S[R] < C);else if (A > 1) {(A = x) > 10 ? (z = s(b, O),t[++o] = [[O + 4, z - 3], 0, 0],O += 2 * z - 2) : A > 8 ? (C = S[R--],S[R] = S[R] ^ C) : A > 6 && (C = S[R--])} else if (A > 0) {if ((A = x) < 3) {var D = 0, T = S[R].length, $ = S[R];S[++R] = function() {var b = D < T;if (b) {var e = $[D++];S[++R] = e}S[++R] = b}} elseA < 5 ? (z = y(b, O),O += 2,C = c[z],S[++R] = C) : A < 7 ? S[R] = ++S[R] : A < 9 && (C = S[R--],S[R] = S[R]in C)} else {if ((A = x) > 13)C = S[R],S[R] = S[R - 1],S[R - 1] = C;else if (A > 4)C = S[R--],S[R] = S[R] === C;else if (A > 2)C = S[R--],S[R] = S[R] - C;else if (A > 0) {for (z = v(b, O),A = "",P = i.q[z][0]; P < i.q[z][1]; P++)A += String.fromCharCode(r ^ i.p[P]);A = +A,O += 4,S[++R] = A}}}}if (I)for (; O < E; ) {j = B[O];O += 2;A = 3 & (x = 13 * j % 241);if (x >>= 2,A < 1) {var U;A = 3 & x;if (x >>= 2,A < 1) {if ((A = x) > 14)z = W[O],(U = function e() {var f = arguments;return e.y > 0 ? K(b, e.c, e.l, f, e.z, this, null, 0) : (e.y++,K(b, e.c, e.l, f, e.z, this, null, 0))}).c = O + 4,U.l = z - 2,U.x = G,U.y = 0,U.z = c,S[R] = U,O += 2 * z - 2;else if (A > 12)q = S[R--],w = S[R--],(A = S[R--]).x === G ? A.y >= 1 ? S[++R] = K(b, A.c, A.l, q, A.z, w, null, 1) : (S[++R] = K(b, A.c, A.l, q, A.z, w, null, 0),A.y++) : S[++R] = A.apply(w, q);else if (A > 5)C = S[R--],S[R] = S[R] != C;else if (A > 3)C = S[R--],S[R] = S[R] * C;else if (A > -1)return [1, S[R--]]} else if (A < 2) {(A = x) < 4 ? (q = S[R--],(A = S[R]).x === G ? A.y >= 1 ? S[R] = K(b, A.c, A.l, [q], A.z, w, null, 1) : (S[R] = K(b, A.c, A.l, [q], A.z, w, null, 0),A.y++) : S[R] = A(q)) : A < 6 ? S[R -= 1] = S[R][S[R + 1]] : A < 8 ? S[R] = --S[R] : A < 10 && (C = S[R--],S[R] = typeof C)} else if (A < 3) {if ((A = x) > 11)throw S[R--];if (A > 7) {for (C = S[R--],z = W[O],A = "",P = i.q[z][0]; P < i.q[z][1]; P++)A += String.fromCharCode(r ^ i.p[P]);O += 4,S[R--][A] = C} elseA > 5 && (S[R] = h(S[R]))} else {(A = x) < 1 ? S[++R] = null : A < 3 ? (C = S[R--],S[R] = S[R] >= C) : A < 12 && (S[++R] = void 0)}} else if (A < 2) {A = 3 & x;if (x >>= 2,A > 2)(A = x) > 12 ? S[++R] = l : A > 5 ? (C = S[R--],S[R] = S[R] !== C) : A > 3 ? (C = S[R--],S[R] = S[R] / C) : A > 1 ? O += 2 * (z = W[O]) - 2 : A > -1 && (S[R] = !S[R]);else if (A > 1) {(A = x) < 2 ? S[++R] = C : A < 4 ? (C = S[R--],S[R] = S[R] <= C) : A < 11 ? (C = S[R -= 2][S[R + 1]] = S[R + 2],R--) : A < 13 && (C = S[R],S[++R] = C)} else if (A > 0) {if ((A = x) < 8)q = S[R--],C = delete S[R--][q];else if (A < 10) {for (z = W[O],A = "",P = i.q[z][0]; P < i.q[z][1]; P++)A += String.fromCharCode(r ^ i.p[P]);O += 4,S[R] = S[R][A]} elseA < 12 ? (C = S[R--],S[R] = S[R] << C) : A < 14 && (S[++R] = W[O],O += 2)} else {if ((A = x) < 5) {z = W[O];try {if (t[o][2] = 1,1 == (C = G(b, O + 4, z - 3, [], c, l, null, 0))[0])return C} catch (m) {if (t[o] && t[o][1] && 1 == (C = G(b, t[o][1][0], t[o][1][1], [], c, l, m, 0))[0])return C} finally {if (t[o] && t[o][0] && 1 == (C = G(b, t[o][0][0], t[o][0][1], [], c, l, null, 0))[0])return C;t[o] = 0,o--}O += 2 * z - 2} elseA < 7 ? (z = W[O],O += 2,S[R -= z] = 0 === z ? new S[R] : d(S[R], n(S.slice(R + 1, R + z + 1)))) : A < 9 && (C = S[R--],S[R] = S[R] & C)}} else if (A < 3) {A = 3 & x;if (x >>= 2,A < 1)(A = x) < 2 ? (C = S[R--],S[R] = S[R] > C) : A < 9 ? (z = W[O],O += 4,q = R + 1,S[R -= z - 1] = z ? S.slice(R, q) : []) : A < 11 ? (z = W[O],O += 2,C = S[R--],c[z] = C) : A < 13 ? (C = S[R--],S[R] = S[R] >> C) : A < 15 && (S[++R] = W[O],O += 4);else if (A < 2) {(A = x) < 1 ? S[++R] = g : A < 3 ? (C = S[R--],S[R] = S[R] + C) : A < 5 ? (C = S[R--],S[R] = S[R] == C) : A < 14 && (C = S[R - 1],q = S[R],S[++R] = C,S[++R] = q)} else if (A < 3) {if ((A = x) < 2) {for (z = W[O],C = "",P = i.q[z][0]; P < i.q[z][1]; P++)C += String.fromCharCode(r ^ i.p[P]);S[++R] = C,O += 4} elseA < 4 ? S[R--] ? O += 4 : O += 2 * (z = W[O]) - 2 : A < 6 ? (C = S[R--],S[R] = S[R] % C) : A < 8 ? (C = S[R--],S[R] = S[R]instanceof C) : A < 15 && (S[++R] = !1)} else {(A = x) > 7 ? (C = S[R--],S[R] = S[R] | C) : A > 5 ? (z = W[O],O += 2,S[++R] = c["$" + z]) : A > 3 && (z = W[O],t[o][0] && !t[o][2] ? t[o][1] = [O + 4, z - 3] : t[o++] = [0, [O + 4, z - 3], 0],O += 2 * z - 2)}} else {A = 3 & x;if (x >>= 2,A > 2)(A = x) > 13 ? (S[++R] = W[O],O += 8) : A > 11 ? (C = S[R--],S[R] = S[R] >>> C) : A > 9 ? S[++R] = !0 : A > 7 ? (z = W[O],O += 2,S[R] = S[R][z]) : A > 0 && (C = S[R--],S[R] = S[R] < C);else if (A > 1) {(A = x) > 10 ? (z = W[O],t[++o] = [[O + 4, z - 3], 0, 0],O += 2 * z - 2) : A > 8 ? (C = S[R--],S[R] = S[R] ^ C) : A > 6 && (C = S[R--])} else if (A > 0) {if ((A = x) > 7)C = S[R--],S[R] = S[R]in C;else if (A > 5)S[R] = ++S[R];else if (A > 3)z = W[O],O += 2,C = c[z],S[++R] = C;else if (A > 1) {D = 0,T = S[R].length,$ = S[R];S[++R] = function() {var b = D < T;if (b) {var e = $[D++];S[++R] = e}S[++R] = b}}} else {if ((A = x) < 2) {for (z = W[O],A = "",P = i.q[z][0]; P < i.q[z][1]; P++)A += String.fromCharCode(r ^ i.p[P]);A = +A,O += 4,S[++R] = A} elseA < 4 ? (C = S[R--],S[R] = S[R] - C) : A < 6 ? (C = S[R--],S[R] = S[R] === C) : A < 15 && (C = S[R],S[R] = S[R - 1],S[R - 1] = C)}}}return [0, null]}function K(b, e, f, a, d, c, n, i) {var r, t;null == c && (c = this),d && !d.d && (d.d = 0,d.$0 = d,d[1] = {});var o = {}, l = o.d = d ? d.d + 1 : 0;for (o["$" + l] = o,t = 0; t < l; t++)o[r = "$" + t] = d[r];for (t = 0,l = o.length = a.length; t < l; t++)o[t] = a[t];return i && !B[e] && F(b, e, 2 * f),B[e] ? G(b, e, f, 0, o, c, null, 1)[1] : G(b, e, f, 0, o, c, null, 0)[1]}
};// (glb = "undefined" == typeof window ? global : window)
const v1 = "484e4f4a403f5243000d2d1aea78184c36c3d671000000000000ab44020000250074211b000b02430200013e2217000e1c211b000b03430200024017000e18011b000b02041c16004c211b000b04430200033e2217000b1c1b000b041e00041700181b000b04260200050a000118010a0002101c16001e180022011700051c131f0018011800131e00061a001d000727041c00261102000025552002000825000d1b000b081e00090101001f0702000a25000e211b000b094302000240001f0802000b25005b131e000c02000d02000e1a02221e000f24131e00100a000110220117003c1c0200002500131800221e0011240a0000100200123e00131e001301220117001a1c211b000b0a43020002402217000b1c1b000b0a1e001404001f090200152500131b000b0b1a00221e0016240a000010001f0a020017250039211800430200023e22011700081c1800263e17000702000000211800430200183e170012180017000902001916000602001a001800001f0b02001b25005218010117000802001c1f010200001f0618001f0e180e480039170033180618011b000b0c221e001d241b000b0c221e001e240a00001018011e001f2a0a00011019281f06180e2e1f0e16ffcb1806001f0c0200202500df0200021f0621134318063e22011700121c13221e0011240a00001002002140220117001c1c1b000b051e00221e0011221e002324130a00011002002140220117000d1c211b000b084318063e22011700201c1b000b08221e0011240a000010221e0024240200250a00011048003a220117000d1c211b000b0d4318063e22011700151c1b000b0d221e0011240a00001002002640220117000d1c211b000b0e4318063e17000520001b020b07260a00001001170028211b000b0f4318063e22011700151c1b000b0f221e0011240a00001002002740170005200012001f0d0200282500a3211801430200294017000400180002002a281f061801221e002b24131e000c02002c0200001a020a0001101f0748001f12181218071e001f3a17006618071812191f081808221e002d2448000a00011002002e3e17001a1808221e002f24480118081e001f0a0002101f0816ffd81808221e00242418060a00011048003e1700191808221e002f2418061e001f18081e001f0a0002100018122d1f1216ff95001f0e02003025007146000306000a271f22020000000500600200001f06131e003117001c131e0031221e00322418000a0001101f061806170006180600131e003317001c131e0033221e00322418000a0001101f0618061700061806001b020b0e2618001b000b081e00340a0002101f0618060007001f0f02003525009c460003060006271f2205008f131e0031170015131e0031221e003624180018010a0002101c131e0033170015131e0033221e003624180018010a0002101c49016d48182a483c2a483c2a4903e82a1f061b000b081800020037281d00341b000b08180002002a28180128020038281b000b0b1b000b0b1a00221e0016240a0000101806281a01221e0039240a0000102802003a281d003407001f1002003b25004c460003060006271f1e05003f131e0031170013131e0031221e003c2418000a0001101c131e0033170013131e0033221e003c2418000a0001101c1b000b081800020037281d003407001f1102003d2500a31b000b101a001f061b000b05221e003e24180602003f131e00061a002202000025000c1b030b00201d0040001d00410a0003101c1b000b11221e00422402004318060a0002101c13221700081c131e00442217000b1c131e00441e00451700091800201d00401b020b08260a00001017003013221700221c131e0046131e00472948643922011700101c131e0048131e0049294864391700091800201d0040001f1302004a25002b211343020002402217001f1c1b000b051e00221e0011221e002324131e004b0a00011002004c3e001f1402004d2500611b020b07260a0000100117005202004e1b000b0d420122011700111c1b000b0d1e004e1b000b12410122011700091c02004f134222011700091c020050134222011700091c0200511342220117000f1c020052134202005313423a0012001f150200542501661b000b0d1e005517000520000200561b000b05421700431b000b05221e0056241b000b0d0a0001101f101810221e0024240200550a00011048003b22011700151c1810221e0024240200570a00011048003b170005200013221700081c131e00582217000b1c131e00581e00592217000e1c131e00581e00591e005a17002a460003060006271f9605001e131e00581e0059221e005a240a0000101b000b063e17000520000702005b02005c02005d02005e02005f0200600200610200620200630200640200650a000b1f060200660200670200680a00031f07180708031fc918c921041700181fc8180718c8191fca1318ca19170005200016ffe7180608031fc918c9210417001b1fc8180618c8191fca131e006918ca19170005200016ffe4131e006908031fc918c921041700341fc818c8221e006a24131e000c02006b0200001a020a0001102217000f1c131e006918c81902006c19170005200016ffcb12001f1602006d2500c71b020b08260a0000101700291b000b13221e006e2402000f0a0001101f06180602000025000c1b030b00201d006f001d00701b020b09260a00001017005b46000306002c271f1a181a1e00711b000b14020072193e2217000e1c131e00311e001f48003e1700091800201d006f050029131e0031221e0036240200730200000a0002101c131e0031221e003c240200730a0001101c071b020b07260a000010170024131e007401221700121c131e007522011700081c131e00761700091800201d006f001f170200772500b11b020b07260a000010011700a21b000b08221e0078240200790a0001101f0618061e007a221e0011240a000010221e007b24131e000c02007c02007d1a020200000a000210221e00242402007e0a00011048003a220117003b1c1b000b0d1e0011221e0011240a000010221e007b24131e000c02007c02007d1a020200000a000210221e00242402007e0a00011048003a22011700181c1b000b0d1e004e221e0011240a00001002007f400012001f18020080250075131e000c0200810200001a021f0613221700081c131e00822217000b1c131e00821e008317004c131e00821e00831f071807221e0024240200840a00011048003e22011700151c1807221e0024240200850a00011048003e22011700111c1806221e000f2418070a000110170005200012001f190200862500961b020b1a1e008717000b1b020b1a1e00870046000306000a271f1e020000000500731b000b08221e0078240200790a0001101f0c180c221e0088240200890a0001101f0d180d221e008a2402008b0a0001101f0e180d221e008c24180e02008d190a0001101f0f180d221e008c24180e02008e190a0001101f10180f02008f281810281f111b020b1a18111d008718110007001f1b0200902501270200001f061b020b1a1e009117000f1b020b1a1e00911f061600fb48051f0e0a00001f0f1b000b0d1e004e1f10181022011700071c0a00001f1148001f121812180e3a1700b7460003060006271f3f0500a318111812191f130a00001f1448001f16181618131e001f3a1700371813221e00922418160a00011017001f1814221e0093241813221e00922418160a0001101e00940a0001101c18162d1f1616ffc418131e0095020000281f1518131e0096170011181518131e009602000028281f15181518131e009702000028281f1518151814221e0098240200000a000110281f15180f221e00932418150a0001101c0718122d1f1216ff47180f221e0098240200990a0001101f061b020b1a18061d00911806221e009a2448004904000a000210001f1c02009b2504631b000b0d1e009c221e009d240a0000101f061b000b0d1e009e221e009d240a0000101f0748001f0848011f0948021f0a48031f0b48041f0c48051f0d180d1f0e02009f1f0f0200a01f100200a11f110200a21f120200a31f130200a41f140200a51f150200a61f161806221e0024240200a70a00011048003b22011700151c1806221e0024240200a80a00011048003b17000a180c1f0e1600f71806221e002424180f0a00011048003b17000a18081f0e1600dd1806221e00242418110a00011048003b17000a18091f0e1600c31806221e00242418120a00011048003b22011700151c1806221e0024240200a90a00011048003b22011700151c1806221e0024240200aa0a00011048003b17000a180a1f0e16007b1806221e00242418130a00011048003b22011700141c1806221e00242418140a00011048003b22011700141c1806221e00242418150a00011048003b22011700151c1806221e0024240200ab0a00011048003b22011700151c1806221e0024240200ac0a00011048003b17000a180b1f0e160007180d1f0e1807221e00242418100a00011048003b221700091c180e18084017000820001601521807221e00242418120a00011048003b22011700141c1807221e00242418110a00011048003b22011700151c1807221e0024240200ad0a00011048003b221700091c180e180a40221700091c180e18094017000820001600f91807221e00242418160a00011048003b22011700141c1807221e00242418140a00011048003b22011700141c1807221e00242418150a00011048003b22011700141c1807221e00242418130a00011048003b221700091c180e180c40221700091c180e180b40170008200016008b1807221e00242418100a00011048003a221700141c1807221e00242418120a00011048003a221700141c1807221e00242418160a00011048003a221700141c1807221e00242418130a00011048003a221700141c1807221e00242418140a00011048003a221700141c1807221e00242418150a00011048003a1f001800180e180d3e40170005200048001f1748011f1848021f1948041f1a48051f1b181b1f1c1806221e0024240200ae0a00011048003b17000a18191f1c1600861806221e0024240200af0a00011048003b22011700151c1806221e0024240200b00a00011048003b17000a18181f1c1600541806221e0024240200b10a00011048003b17000a18171f1c1600391806221e0024240200b20a00011048003b22011700151c1806221e0024240200b30a00011048003b17000a181a1f1c160007181b1f1c1b020b1c260a000010221e009d240a0000101f1d1b020b1b260a000010221e009d240a0000101f1e181c18173f221700091c181c18183f2217002d1c131e005822011700231c1b000b0d1e00b4221e0011240a000010221e0024240200b50a00011048003b1700052000181c18173f221700091c181c18183f221700151c181d221e0024240200580a00011048003b1700052000181c181a3e2217000a1c181e0200003f170005200012001f1d0200b62500da261f0646000306000f271f121b000b081e00b71f060500191b000b08221e00b8240200b90a0001104800191f06071806263e170004001b000b08221e0078240200ba0a0001101f070200bb1b000b15264927101b000b0c221e001e240a0000102a480a0a000210280200bb281b000b0b1a00221e0016240a000010281f0818000200bc180828281f00180718001d00bd1318080200002500311b030b011800041c460003060006271f0c05001c1b030b06221e00be241b030b070a0001101c131b030b080907000d1806221e00bf2418070a0001101c001f1e0200c02500be18001e001f1f0618064802331f07180117003018001806480129191f0818074804291f07180818074803293a22011700091c1808180739170005260018081f0748001f09180918063a17004a180018091b000b16221e00c12418001809194900ff2f18001809194808354900ff2f18001809194810354900ff2f18001809194818354900ff2f0a0004100d18092d1f0916ffb41800221e0098240200000a0001101f0a1801170013180a221e002f24480018070a00021000180a001f200200c225007f18001e001f1f0618064802341f07180648032f48004017000818072d1f07180117001a1b000b1718074801281a011f081808180718060d16000d1b000b1718071a011f0848001f09180918063a17002c1808180948023423191800221e00c32418090a000110180948032f48033333300d18092d1f0916ffd21808001f210200c425000a18001400c52f001f220200c6250030180248053518014802333118014803351802480433312818001801311805180348032f180431191802312831001f230200c725001818001e001f48043a17000a180048041d001f1800001f240200c82500d618001e001f1f0618064801291f0718001807191f0948001f0a1b000b0c221e001d244806483418062b280a0001104800301f0d180d4800391700981b020b22180a1b020b1f28041f0a180a48023548032f1f0b48001f0c180c18073a17003d1800180c480128191f081800180c1b020b221800180c191b020b2326180a18081809180c180b18010a00061028040d271f09180c2d1f0c16ffc118004800191f08180018071b020b2218001807191b020b2326180a180818091807180b18010a00061028040d271f09180d2e1f0d16ff661800001f250200c92500d818001e001f1f0618064801291f0718004800191f081b000b0c221e001d244806483418062b280a0001101f0d1b020b22180d1b020b1f2a041f0a180a480040170093180a48023548032f1f0b18071f0c180c48003917003d1800180c480129191f091800180c1b020b221800180c191b020b2326180a18081809180c180b18010a00061029040d271f08180c2e1f0c16ffc118001807191f09180048001b020b2218004800191b020b2326180a180818094800180b18010a00061029040d271f081b020b22180a1b020b1f29041f0a16ff6b1800001f260200ca2501ac131e000c0200cb0200001a02221e000f2418000a0001101700061800000a00001f0618001e001f1f0748001f0848001f09180818073a1701641800221e00c32418080a0001101f0a180a4900803a170018180618091800221e002d2418080a0001100d16012a180a4908003a17002a180618091b000b16221e00c1244900c0180a48063430490080180a483f2f300a0002100d1600fa180a4a0000d8003a220117000c1c180a4a0000dfff39170036180618091b000b16221e00c1244900e0180a480c3430490080180a480634483f2f30490080180a483f2f300a0003100d1600ae180848012818073a1700991800221e00c32418084801280a0001101f0b180a4a0000dc003a2217000c1c4a0000dc00180b3c2217000c1c180b4a0000dfff3c170062180a4903ff2f480a33180b4903ff2f304a00010000281f0c180618091b000b16221e00c1244900f0180c481234483f2f30490080180c480c34483f2f30490080180c480634483f2f30490080180c483f2f300a0004100d18082d1f0816000d1b000b180200cc1a014718082d1f0818092d1f0916fe9a1806221e0098240200000a000110001f270200cd25024e1b000b1718011a011f0648001f0748001f0818001e001f1f09180718013a221700091c180818093a1702051800221e00c3241808222d1f080a0001101f0a180a4804341f0c180c480040170061180c480140170059180c480240170051180c480340170049180c480440170041180c480540170039180c480640170031180c480740170029180c480c4017002b180c480d40170023180c480e40170055180c480f401700a216016816017d18061807180a0d160173180818093a17002818061807180a481f2f4806331800221e00c3241808222d1f080a000110483f2f300d16000d1b000b180200ce1a0147160139180848012818093a17004018061807180a480f2f480c331800221e00c3241808222d1f080a000110483f2f480633301800221e00c3241808222d1f080a000110483f2f300d16000d1b000b180200ce1a01471600e4180848022818093a1700b4180a48072f4812331800221e00c3241808222d1f080a000110483f2f480c33301800221e00c3241808222d1f080a000110483f2f480633301800221e00c3241808222d1f080a000110483f2f304a00010000291f0b4800180b3c2217000c1c180b4a000fffff3c17002f18061807222d1f07180b480a344903ff2f4a0000d800300d18061807180b4903ff2f4a0000dc00300d16001b1b000b180200cf180b221e00112448100a000110281a014716000d1b000b180200ce1a014716001b1b000b180200d0180a221e00112448100a000110281a014718072d1f0716fdef180718013a17000a180618071d001f1b000b161e00c11b000b16180610001f280200d12502aa0a00001f061b000b174a000080001a011f0748001f0848001f0918001e001f1f0a180818013a221700091c1809180a3a1702431800221e00c3241809222d1f090a0001101f0b180b4804341f0e180e480040170061180e480140170059180e480240170051180e480340170049180e480440170041180e480540170039180e480640170031180e480740170029180e480c4017002b180e480d40170023180e480e40170055180e480f401700a216016816017d18071808180b0d1601731809180a3a17002818071808180b481f2f4806331800221e00c3241809222d1f090a000110483f2f300d16000d1b000b180200ce1a01471601391809480128180a3a17004018071808180b480f2f480c331800221e00c3241809222d1f090a000110483f2f480633301800221e00c3241809222d1f090a000110483f2f300d16000d1b000b180200ce1a01471600e41809480228180a3a1700b4180b48072f4812331800221e00c3241809222d1f090a000110483f2f480c33301800221e00c3241809222d1f090a000110483f2f480633301800221e00c3241809222d1f090a000110483f2f304a00010000291f0c4800180c3c2217000c1c180c4a000fffff3c17002f18071808222d1f08180c480a344903ff2f4a0000d800300d18071808180c4903ff2f4a0000dc00300d16001b1b000b180200cf180c221e00112448100a000110281a014716000d1b000b180200ce1a014716001b1b000b180200d0180b221e00112448100a000110281a01471808497fff4801293b17003518084801281f0d1807180d1d001f180618061e001f1b000b161e00c11b000b161807100d1801180d291f0148004801291f0818082d1f0816fdb11808480039170020180718081d001f180618061e001f1b000b161e00c11b000b161807100d1806221e0098240200000a000110001f290200d22500b418011b000b063e22011700081c1801263e22011700091c180148003a17000a18001e001f1f01180148003e17000702000000131e000c0200cb0200001a02221e000f2418000a000110220117001c1c131e000c0200d30200001a02221e000f2418000a00011001170021180118001e001f3e1700061800001800221e00d424480018010a0002100018014a0000ffff3a1700131b020b2826180018010a0002101600101b020b2926180018010a000210001f2a0200d525006b18001b000b063e22011700081c1800263e220117000c1c18001e001f48003e1700061800001b020b271800041f001b020b271801041f011b020b20261b020b25261b020b21261800200a0002101b020b241b020b21261801120a000210040a000210120a000210001f2b0200d625006718001b000b063e22011700081c1800263e220117000c1c18001e001f48003e1700061800001b020b271801041f011b020b2a1b020b20261b020b26261b020b21261800120a0002101b020b241b020b21261801120a000210040a000210200a00021004001f2c0200d725019d0200d81f0602002a1f0718021700080200001f07180117000718011f060200001f0848001f0a18001e001f180a4803283b1700b31800221e00c324180a222d1f0a0a0001104900ff2f4810331800221e00c324180a222d1f0a0a0001104900ff2f480833301800221e00c324180a222d1f0a0a0001104900ff2f301f0918081806221e002d2418094a00fc00002f4812340a000110281f0818081806221e002d2418094a0003f0002f480c340a000110281f0818081806221e002d241809490fc02f4806340a000110281f0818081806221e002d241809483f2f0a000110281f0816ff4518001e001f180a294800391700a81800221e00c324180a222d1f0a0a0001104900ff2f48103318001e001f180a3917001a1800221e00c324180a0a0001104900ff2f4808331600054800301f0918081806221e002d2418094a00fc00002f4812340a000110281f0818081806221e002d2418094a0003f0002f480c340a000110281f08180818001e001f180a3917001a1806221e002d241809490fc02f4806340a0001101600051807281f0818081807281f081808001f2d0200d92500120200da221e00242418000a000110001f2e0200db2501100200001f0648001f07180718001e001f4803293a1700f61b020b2e1800221e002d2418074800280a000110041f081b020b2e1800221e002d2418074801280a000110041f091b020b2e1800221e002d2418074802280a000110041f0a1b020b2e1800221e002d2418074803280a000110041f0b18061b000b16221e00c12418084802331809480435300a000110281f061800221e002d2418074802280a00011002002a3f17002718061b000b16221e00c12418094804334900f02f180a480235480f2f300a000110281f061800221e002d2418074803280a00011002002a3f17002118061b000b16221e00c124180a4806334900c02f180b300a000110281f0618074804281f0716ff021806001f2f0200dc25004a1800483f2f1f001b000b16221e00c12418001800481a3a1700084841160025180048343a17000848471600181800483e3a17000b48004804291600084800481129280a000110001f310200dd2500331b020b311f06180618004818340418061800481234042818061800480c340428180618004806340428180618000428001f320200de2500981b020b121e00df0200e0281f061b020b1e26180602000025007818001e001f48083a17000400460003060006271f7405005f1b020b2c261b020b2f1800221e009a2448080a000110041800221e009a24480048080a0002100a0002101f0c180c0200e13e1700131b020b38262018000a0002101c160019180c0200e23e1700101b020b38261218000a0002101c07000a0002101c001f370200e325004e1b020b1218001d00e4460003060006271f1e050038131e0031170016131e0031221e0036240200e518010a0002101c131e0033170016131e0033221e0036240200e518010a0002101c07001f380200e62500a90200001f06460003060006271f2305003f131e0031170015131e0031221e0032240200e50a0001101f0618060122011700081c131e0033170015131e0033221e0032240200e50a0001101f06071806170055460003060006271f430500491b020b2c261b020b2f1806221e009a2448080a000110041806221e009a24480048080a0002100a0002101f2318230200e13e170008200016000e18230200e23e17000512000712001f390200e7250103121f061b020b121e00e4203e170009201f061600201b020b121e00e4123e170009121f0616000e1b020b39260a0000101f06131e00061a0022121d00e822121d00e922121d00822218061d00ea22121d00eb22121d004022121d00ec22121d00ed22121d005522121d006f22121d00ee220200ef25000520001f4018401d000f1f0718071b020b0d260a0000101d00eb18071e00eb011700671b020b131807041c1b020b171807041c18071b020b14260a0000101d00ec18071b020b15260a0000101d00ed18071b020b16260a0000101d005518071b020b18260a0000101d00ee18071b020b19260a0000101d008218071b020b1d260a0000101d00e91807001f3a0200f025005c1b000b05221e00f12418000a0001101f0648001f0718061e001f4801291f08180848003b1700321800180618081919170008480116000548001f09180918061e001f180829480129331807301f0718082e1f0816ffcc1807001f3b0200f225003848001f06180618011e001f3a17002618004a0001003f2a1801221e00c32418060a000110284800351f0018062d1f0616ffd51800001f3c0200f325003848001f06180618011e001f3a17002618001801221e00c32418060a000110314a0001003f2a4800351f0018062d1f0616ffd51800001f3d0200f42500a348001f06180618011e001f3a1700911801221e00c32418060a0001101f0718074a0000d8003b2217000c1c18074a0000dbff3c2217000c1c180618011e001f3a1700451801221e00c32418064801280a0001101f0818084a0000fc002f4a0000dc003d17002218074903ff2f480a3318084903ff2f284a00010000281f0718064801281f0618004a0001003f2a1807284800351f0018062d1f0616ff6a1800001f3e0200f5250077180022011700071c0200001f061806221e007b24131e000c0200f60200001a020200000a0002101f061806221e0024240200e00a0001104800480129401700211806221e00d42448001806221e0024240200e00a0001100a00021016000518061f061806170008180616000602008f1f061806001f3f0200f72500b1180022011700071c0200001f061806221e006a24131e000c0200f80200001a020a0001101f0718071700161807480019221e00d42448010a0001101600060200001f0618061700141806221e002b240200f90a000110160004261f08131e00061a001f09180817004548001f0a180a18081e001f3a17003618091808180a19221e002b2402002a0a0001104800191808180a19221e002b2402002a0a0001104801190d180a2d1f0a16ffc51809001f400200fa25009118000122011700171c1b000b19221e00fb2418000a0001100200fc3e17000a131e00061a00001b000b05221e00f12418000a000110221e00fd240a0000101f06131e00061a001f0748001f10181018061e001f3a170037180117001a180718061810191800180618101919020000280d1600131807180618101918001806181019190d18102d1f1016ffc41807001f410200fe2500781b000b17221e00ff2418000a0001101700131800221e0100241b020b420a0001100018001b000b05411700491b000b05221e00f12418000a000110221e00fd240a0000101f0c180c221e010124020000250017180018011b020b421b030b00180119040d180000131e00061a000a000210001800001f4202010225007d18000122011700171c1b000b19221e00fb2418000a0001100200fc3e170007020000001b000b05221e00f12418000a000110221e00fd240a0000101f060200001f0748001f10181018061e001f3a170029180718061810190a000102002a281800180618101919280200f928281f0718102d1f1016ffd21807001f430201032500cb1b000b08221e0078240200790a0001101f07180748301d0104180748101d01051807221e0088240201060a0001101f0818080201071d01081808221e01092402010a4802480c0a0003101c180848021d010b180848011d010c180802010d1d010e1808221e010f24480848084808480048020a0005101c1808221e0110240a0000101c1807221e007a240a0000101f0648001f09180948203a17002c18004a0001003f2a1806221e00c324180018061e001f2c0a000110284800351f0018092d1f0916ffd21800001f4402011125002046000306000c271f0c48004801290005000d1b020b44140112040007001f45020113250011110201131d00951118001d0114001f4602011525001a460003060008271f0c200005000b131e003101010007001f4702011625001a460003060008271f0c200005000b131e003301010007001f4802011725001a460003060008271f0c200005000b131e007401010007001f490201182500301b020b0b1b020b49260a000010041b020b0b1b020b48260a00001004281b020b0b1b020b47260a0000100428001f4a020119250023131e011a1f0618061e01040200bb2818061e0105280200bb2818061e011b28001f4b02011c250019131e011a1f0618061e011d0200bb2818061e011e28001f4c02011f2500711b000b1a0200002500640201201b000b0d421700511b000b0d221e0120240a000010221e0121240200002500311b040b001800020122190200bb28180002012319280200bb28180002012419280200bb2818000201251928041c000a0001101c16000a1800020000041c001a01001f4d02012625007d0201271f0648001f07211b000b0d180619430200024017000f1b000b0d1806191f0716001c211b000b0d180619430200024017000c1b000b0d1806191f07460003060009271f50121f080500181b000b08221e0128240201290a0001101c201f080702012a13421f0918070200bb281808280200bb28180928001f4e02012b2500671b000b0b1a001f061806221e012c2448010a0001101c1806221e012d2448050a0001101c48001806221e012e240a000010291f071806221e012d24480b0a0001101c48001806221e012e240a000010291f081b000b0c221e012f24180718080a000210001f4f0201302501dd0201310201320201330a00031f06131e00061a001f07131e00061a001f081b000b081e00b70117000702001a001806031f1b181b21041700711f1a1b000b08221e0078240201340a0001101f1c181c0201351d0136181c1e01370201381d0139181c1e0137181a1d013a1b000b081e00b7221e00bf24181c0a0001101c1807181a181c1e013b0d1808181a181c1e013c0d1b000b081e00b7221e00be24181c0a0001101c16ff8e02013d02013e02013f02014002014102014202014302014402014502014602014702014802014902014a02014b02014c02014d02014e02014f0201500201510201520201530201540201550201560201570201580201590a001d1f0948001f0b271f0a271f0c48001f1a181a18091e001f3a1700b31806031f1c181c210417009f1f1b1b000b08221e0078240201340a0001101f1d181d0201351d0136181d1e01370201381d0139181d1e01371809181a1902015a28181b281d013a1b000b081e00b7221e00bf24181d0a0001101c181d1e013b1807181b1940220117000f1c181d1e013c1808181b19401f1e1b000b081e00b7221e00be24181d0a0001101c181e170018181a481e3a17000d4801181a33180a301f0a16000616ff60181a2d1f1a16ff48180a221e00112448100a000110001f5002015b25002146000306000c271f0c180c1e01140005000e1b000b1b02015c1a011c07001f5102015d2500141b000b1c221e0011240a0000101e001f001f5202015e2501e81b020b07260a000010220117000d1c1b020b09260a00001022011700231c1b000b0d1e009c221e009d240a000010221e00242402015f0a00011048003917000702000000131e016022011700081c131e016122011700081c131e01621f061b000b1a02000025017d46000306000d271f6a1800020000041c0501691b030b0617015a1b030b06131e00061a0022131e00061a00220201631d01640a00011d01651a011f06020000250004001f07131e000c0201660200001a021f08131e000c02016702007d1a021f091806221e0168240200000a0001101c1b000b1d2602000025000d1b040b00020000041c004901f40a0002101c1806221e0169240a0000101f0a180a1b000b1a41170038180a221e0121240200002500131b040b06221e016a2418000a000110000a000110221e012124020000250004000a0001101c1600301806221e01692402000025001c1b040b06221e016a2418001b040b071b040b070a0003101c0018070a0002101c18060200002500601800221700091c18001e016b2217000c1c18001e016b1e016b1700431b040b08221e016c2418001e016b1e016b0a0001101f0618061700271806480019221e006a241b040b090a0001101f07180717000e1b040b001806480019041c001d016d16000a1800020000041c07001a01001f5302016e25005d02016f221e007b24131e000c02017002007d1a0202000025003e1b000b0c221e001e240a00001048102a4800301f0618000201713d170008180616000b180648032f4808301f071807221e00112448100a000110000a000210001f5402017225005518001e001f48223e1700481b020b3c2648001800221e002f24480048200a0002100a0002101f061806221e0011240a000010221e002f24480048020a0002101800221e002f24482048220a0002103e0012001f5502017325005d1b020b0f020174041f0618062217000b1c1b020b551806041700061806001b020b54260a0000101f0618061b020b3c26480018060a00021028221e002f24480048220a0002101f061b020b102602017418060a0002101c1806001f56020175250033180001170007020000001b020b0c4804041f0618061b020b2d261b020b2b26180018060a0002100201760a00021028001f5702017725015d180117003a48001f0b48001f0c180c18001e001f3a1700271800180c191e01781700141800180c191801180b222d1f0b191d0179180c2d1f0c16ffd40200001f061800221e017a2402000025001b1b03220b061b020b0b18001e01790402017b28281d017c000a0001101c18061b020b0a260a000010281f061b020b54260a0000101f071b000b0c221e001d241807221e00c32448030a00011048082b0a0001101807221e00c32448030a00011048082c281f081807221e002f24480448041808280a0002101f091b020b2d1b020b2b26180618090a000210180728041f061b020b12221e017d02017e1b000b1e180604280200f928281d017d271f0a1b020b1e26180a02000025004d180002017f1948003d2217000a1c1800020180191700351b020b121b020b57180002018019041d01811b020b121800020180191d01821b020b10260201831800020180190a0002101c000a0002101c001f5802018425049a1b000b0d221700051c13221700081c1b000b080117000400131e00061a00220201851d01862248041d01872218001e01851d0179131e00061a00220201881d01862248031d0187221b020b0a1d0189131e00061a002202018a1d01862248031d0187221b020b4a1d0189131e00061a00220200791d01862248031d0187221b020b451d0189131e00061a002202018b1d01862248031d0187221b020b0a1d0189131e00061a002202009e1d01862248001d0187131e00061a002202018c1d01862248001d0187131e00061a002202018d1d01862248001d0187131e00061a002202018e1d01862248001d0187131e00061a00220200571d01862248001d0187131e00061a002202018f1d01862248031d0187221b020b4b1d0189131e00061a00220201901d01862248031d0187221b020b4c1d0189131e00061a00220201911d01862248011d0187131e00061a00220201921d01862248011d0187131e00061a00220201931d01862248011d0187131e00061a00220201941d01862248001d0187131e00061a00220201951d01862248031d0187221b020b4d1d01892248011d0178131e00061a00220201961d01862248031d0187221b020b4e1d0189131e00061a00220201971d01862248031d0187221b020b4f1d0189131e00061a00220201981d01862248031d0187221b020b0a1d0189131e00061a00220201991d01862248031d0187221b020b1b1d0189131e00061a002202019a1d01862248031d0187221b020b501d0189131e00061a002202019b1d01862248031d0187221b020b1c1d0189131e00061a002202019c1d01862248031d0187221b020b0a1d0189131e00061a002202009c1d01862248001d0187131e00061a002202019d1d01862248031d0187221b020b0f1d0189220201831d019e131e00061a002202019f1d01862248031d0187221b020b511d0189131e00061a00220201a01d01862248031d0187221b020b521d0189131e00061a00220201a11d01862248031d0187221b020b531d01892248011d0178131e00061a00220200821d01862248011d0187131e00061a00220201a21d01862248041d0187221b020b061e01a31d0179131e00061a00220201a41d01862248031d0187221b020b561d0189131e00061a00220201a51d01862248031d0187221b020b0a1d0189131e00061a00220201a61d01862248041d01870a00221f060a00001f07180608031f11181121041700db1f1018061810191e01871f12181248004017001e1812480140170033181248024017004018124803401700501600a918061810191b020b0b1b000b0d18061810191e018619041d017916008c18061810191318061810191e0186191d017916007718061810191b000b0818061810191e0186191d017916005f18061810191e01781700321b000b1a1700281807221e00932418061810191e0189221e00232418061810191e019e0a0001100a0001101c160025180618101918061810191e0189221e0023242618061810191e019e0a0002101d017916ff241b000b1a1700361b000b1a221e01a72418070a000110221e0121240200002500141b020b58261b030b0618000a0002101c000a0001101c16000b1b020b581806041c001f590201a82500441b000b082217000b1c1b000b081e01a901170004001b020b5b08031f0d180d210417001f1f0c1b000b08221e01a924180c1b020b5b180c190a0002101c16ffe0001f5d0201aa25008418001e001f4900c8391700131800221e01ab24480048640a0002101c18001e001f48003917004e180018001e001f480129191f0c18011e01ac180c1e01ac2948003c220117002a1c0201ad1801422217000f1c18011e0171180c1e01713d2217000f1c18011e01ad180c1e01ad3d170004001800221e00932418010a0001101c001f610201ae25006048001f0618001e01af22011700091c18001e01b022011700091c18001e01b122011700091c18001e01b217000748011f061b020b61261b020b60131e00061a002218061d0171221b000b0b221e01b3240a0000101d01ac0a0002101c001f620201b425006d18001f0618001e00941f0718001e01b52217000a1c18070201b63e17001318001e01b74800191f061b02201d01b8131e00061a002218061e01b91d01712218061e01ba1d01ad221b000b0b221e01b3240a0000101d01ac1f081b020b61261b020b5e18080a0002101c001f630201bb25006d18001f0618001e00941f0718001e01b52217000a1c18070201bc3e17001318001e01b74800191f061b02201d01b8131e00061a002218061e01b91d01712218061e01ba1d01ad221b000b0b221e01b3240a0000101d01ac1f081b020b61261b020b5f18080a0002101c001f640201bd2500191800221e0101241b020b650a00011018001e001f2b001f670201be25006818001e001f48013c1700064800001b020b671800041f061800221e01002402000025000b18001b030b0629000a0001101f071b000b0c221e01bf241807221e0100241b020b660a000110221e0101241b020b650a00011018001e001f4801292b0a000110001f680201c02500d548001f0648001f0718001e001f1801391700ba0a00001f0848001f09180918001e001f4801293a17008418001809480128191f0a18001809191f0b180a1e01ac180b1e01ac291f0c180c17005918021700171808221e0093244801180c2b0a0001101c1600401808221e0093241b000b0c221e01bf241b020b66180a1e0171180b1e017129041b020b66180a1e01ad180b1e01ad2904280a000110180c2b0a0001101c18092d1f0916ff741b020b671808041f061b020b681808041f07180748003d1700081401c11f07180618070a0002001f690201c2250119121f06460003060006271f2105002b1b000b082217000b1c1b000b081e01281700171b000b08221e0128240201290a0001101c201f06071b020b69261b020b5e48010a0002101f071b020b69261b020b604805200a0003101f0848011f09180601221700081c1b020b5c17000a18094840301f091b020b5e1e001f48003e17000d18094802301f09160015180748001948323917000a18094810301f091b020b5f1e001f48003e17000a18094804301f091b020b601e001f48003e17000d18094808301f0916001618084800191401c33917000a18094820301f091809221e00112448200a0001101f0a180a1e001f48013e17000e0201c4180a281f0a160016180a1e001f48023e17000b02001a180a281f0a180a001f6a0201c525002d0200001f06460003060006271f0e0500191b020b0e260201c61b000b081e00340a0002101f06071806001f6b0201c72500531b000b19221e00fb24131e00061a002218001d000e221b000b1f1b000b19221e00fb2418011e00b70a000110041d01c82218021d01860a0001101f061b020b2d261806020176200a0003101f071807001f6c0201c9250434211801430200023e2217000c1c21180043020001402217000a1c18001e01ca0117000d1b020b460201cb1a014748001f0648001f074a0000fff11f081b000b0b1a00221e0016240a0000104903e82b4800351f091b020b061e01cc012217003e1c1b020b3d261b020b3d2648001809020000280a0002101b000b0e1e0083221e002f241b000b0e1e01cd1e001f4802280a0001100a00021018082c1f071809180718082a31480035221e00112448020a0001101f0a180a1f0b180a1e001f48203917001b180a221e002f24180a1e001f4820290a0001101f0b16003c180a1e001f48203a1700310200001f7048001f7118714820180a1e001f293a170013187002001a281f7018712d1f7116ffe51870180b281f0b0201ce1f0c0201cf1f0d0201d01f0e180e180d28180c28180b281f061b000b1526180648020a0002101f061b020b3d2648001806020000280a0002101f0f1b020b3a260a0000101f1018100200e818020201d13e17000712160004200d0200001f11180117000a18011f1116011e1b020b5a1e01d2221e002324110201d318000a0003101c18001e00b72217001a1c1b000b19221e00fb2418001e00b70a0001100200fc4017006f48001fc318001e01d41700331b020b3e2648001b000b19221e00fb241b020b412618001e00b718001e01d40a0002100a0001100a0002101fc31600271b020b3e2648001b000b19221e00fb241b020b4218001e00b7040a0001100a0002101fc30201d518c3280200f9281f111b020b4018001e01ca041fc218001e01d617001a1b000b05221e01d72418c218001e01d60a00021016000518c21fc218111b020b4318c204281f1118110201d8281b020b3f18001e01ca04280200f9281f1118110201d9280201da281f111b020b5a1e01d2221e002324110201db18110a0003101c1b020b3b1810041f121b020b061e01cc012217000d1c1b020b45260a0000101f131b020b061e01cc012217001e1c1b020b121e018122011700111c1b020b571b020b0f02018304041f141b020b331806041b020b3318061401dc2b48003504281b020b33181318063104281b020b331b020b3d26180f1b020b061e01cc012217000b1c1b000b0d1e009c221e0011240a0000100a00021018082c4810331b020b3d26180f1811020000280a00021018082c3004281b020b3318124808331b020b061e01dd4804333018063104281b020b32180704281f151b020b334800041c181417000a18151814281f151b020b6a260a00001022011700071c0201de1f160200bb1b020b6d281b020b061e01df281f1718171816281f1718171b020b6e181528281f171b020b3e26480018170a000210221e00112448100a0001101f181818221e009a2418181e001f48022918181e001f0a0002101f1918171819281f170200001f1a1b020b6b260a0000101f1b181b17001f1b020b6c26181b180018110a0003101f1a18170201e028181a281f171817001f6f0201e1250072131e00061a001f06180108031f081808210417005a1f0718011807191f0918001809191f0a21180a430200023e22011700081c180a263e170006121f0a180a26402217001a1c21180a430200033e220117000c1c21180a430200013e170006201f0a18061809180a0d16ffa51806001f700201e225004b0201e30201e402009e0201e502019402018c0201e60201270201e70200b40201e80201e90201ea0201eb0201ec0201ed0201ee0a00111f061b020b70261b000b0d18060a000210001f710201ef2500450201f00200490200470201f10201f20201f30201930201f40201f50201f60201f70201610201f80201f90201fa0201fb0a00101f061b020b70261318060a000210001f720201fc2500270201fd0201fe0200090201ff0202000a00051f061b020b70261b000b0818060a000210001f730202012500551b000b08221e0078240200790a0001101f06261f07460003060006271f100500281806221e0088240200890a00011022011700121c1806221e0088240202020a0001101f0707180701170006261f071807001f740202032500671800221e008a240202040a00011022011700121c1800221e008a240202050a00011022011700121c1800221e008a240202060a0001101f0618061700271800221e008c2418061e02070a0001101f07180748003e17000748021f071807001600052600001f750202082501b61b020b1a1e020917000b1b020b1a1e0209001b020b74260a0000101f0618060117000a131e00061a0000131e00061a00221806221e020a240a00001022011700071c0a00001d020b221806221e020c240a0000101e020d1d020d221806221e008c2418061e020e0a0001101d020f221806221e008c2418061e02100a0001101d0211221806221e008c2418061e02120a0001101d0213221b020b751806041d0203221806221e008c2418061e02140a0001101d0215221806221e008c2418061e02160a0001101d0217221806221e008c2418061e02180a0001101d0219221806221e008c2418061e021a0a0001101d021b221806221e008c2418061e021c0a0001101d021d221806221e008c2418061e021e0a0001101d021f221806221e008c2418061e02200a0001101d0221221806221e008c2418061e02220a0001101d0223221806221e008c2418061e02240a0001101d0225221806221e008c2418061e02260a0001101d0227221806221e008c2418061e02280a0001101d0229221806221e008c2418061e022a0a0001101d022b221806221e008c2418061e022c0a0001101d00961f071b020b1a18071d02091807001f7602022d250065131e00061a00221b020b71260a0000101d022e221b020b72260a0000101d022f221b020b73260a0000101d0069221b020b76260a0000101d0089221b020b1b260a0000101d0230221b020b1c260a0000101d004e1f061b020b1a18061d02311806001f77020232250075131e00061a001f061b020b1a1e023117000f1b020b1a1e02311f0616000e1b020b77260a0000101f0618061b000b0b221e01b3240a0000101d02331b020b0c4804041f0718071b020b2d261b020b2b261b000b19221e00fb2418060a00011018070a0002100201760a000210281f081808001f7802023425003b48001f0618061b020b121e02351e001f3a1700251b020b121e0235180619221e000f2418000a000110170005200018062d1f0616ffd112001f790202362503ac131e02371e00221f0618061e006e1f0718061e02381f0818061e02391f0918061e023a1f0a18061e023b170007001600091806201d023b1806020000250076111e023c01170065111e023d221e009324131e00061a00220202381d023e221b041d023f0a0001101c131e000c02024002000e1a02221e000f2418000a00011017002a111801221e0011240a000010221e009d240a000010221e002b240202410a0001104800191d02421b030b08111b0410001d02381806020000250012111b041d02431b030b0a111b0410001d023a1806020000250040110a00001d023d111e023d221e009324131e00061a002202006e1d023e221b041d023f0a0001101c1118001d02441118011d02451b030b07111b0410001d006e02024602007002024702024802024902024a02024b0a00071f0b180602000025026f11201d023c1b020b79111e024504170255111e0245221e00242402024c0a00011048004801293917000c1b030b09111b0410001118001d024d111e024e1f06111e02461f07111e00701f08111e02471f09111e02481f0a111e02491f0b111e024a1f0c111e024b1f0d111e024f1f0e111e02501f0f131e00061a001f1048001f2a182a1b030b0b1e001f3a17002118101b030b0b182a19111e02511b030b0b182a19190d182a2d1f2a16ffd8131e00061a00221b020b82261b030b00111e02450a0002101d01ca1f11111e02440202523d17003c111e02420202533e220117000c1c111e02420202543e17001a1b020b80261811111e0242111e024d0a0003101c16000c1b030b09111b0410001b020b851b030b000417001c1b030b00221e02552418111b000b060201d10a0003101600151b020b6f2618111b000b060201d10a0003101f121b020b8326111e024518120a0002101f13111e023d221700131c111e023d48001902023e1902006e3f1700052600111e023d1f1448001fa418a418141e001f3a17003618a448003e170010181418a4191e023f480118130d11181418a41902023e191911181418a4191e023f101c18a42d1fa416ffc5111e024317000e111e023a11111e0243101c1102023d091b020b121e025617001e11221e0238241b020b061e02571b020b78260a0000100a0002101c1118061d024e1118071d02461118081d00701118091d024711180a1d024811180b1d024911180c1d024a11180d1d024b11180e1d024f11180f1d025048001f9018901b030b0b1e001f3a170021111e02511b030b0b18901918101b030b0b189019190d18902d1f9016ffd81b030b09111b0410001d0239001f7a0202582503f60202592503c31801220117000a1c131e00061a001f011b020b7b2217000b1c18001b000b20411f060200001f0702025a1f08180617001418001e01ca1f0718001e025b1f0816002418001f0718011e025b17001418011e025b221e025c240a00001016000518081f08180802025a402217000a1c180802025240220117000c1c1b020b79180704011700111b030b0626180018010a00021000131e00061a00221b020b82261b030b0018070a0002101d01ca1f0918080202523d1701fc1b020b7f26180018010a000210221e002b240202410a000110480019221e009d240a0000101f5018500202533e220117000a1c18500202543e1701af18061700c81800221e025d240a000010221e025e240a000010221e0121240200002500881b020b80261b040b091b040b5018000a0003101c1b020b851b030b000417001e1b030b00221e0255241b040b091b000b060201d10a0003101600171b020b6f261b040b091b000b060201d10a0003101f061b020b83261b040b0718060a0002101f071b020b81261b040b00180718000a0003101f081b030b062618081b040b010a000210000200002500161b000b1a0200002500091b050b0047001a01000a000210001600e21b020b80261809185018011e00b70a0003101c1b020b851b030b000417001c1b030b00221e02552418091b000b060201d10a0003101600151b020b6f2618091b000b060201d10a0003101fa21b020b8326180718a20a0002101fa31b020b121e025617006f18010117002a131e00061a0022131e00061a00221b020b061e02571b020b78260a0000100d1d025f1f0116004218011e025f011700231801131e00061a00221b020b061e02571b020b78260a0000100d1d025f16001918011e025f1b020b061e02571b020b78260a0000100d1b030b062618a318010a000210001600111b030b0626180018010a00021000160112180802025a3e1700fb1b020b851b030b000417001c1b030b00221e02552418091b000b060201d10a0003101600151b020b6f2618091b000b060201d10a0003101f4e1b020b83261807184e0a0002101f4f18061700271b020b81261800184f1b000b060a0003101f501b030b0626185018010a000210001600871b020b121e025617006f18010117002a131e00061a0022131e00061a00221b020b061e02571b020b78260a0000100d1d025f1f0116004218011e025f011700231801131e00061a00221b020b061e02571b020b78260a0000100d1d025f16001918011e025f1b020b061e02571b020b78260a0000100d1b030b0626184f18010a000210001600111b030b0626180018010a00021000001f071b020b7e260a0000100117000400131e02601700070016000813201d0260131e02611f061318071d0261001f7d020262250008131e0261001f7e02026325010d0200001f061b020b7b2217000b1c18001b000b204117002218001e025f221e0041240202640a0001101f07180717000718071f061806001801221700091c18011e025f1700c61b020b7c2217000e1c18011e025f1b000b214117002218011e025f221e0041240202640a0001101f17181717000718171f0618060018011e025f1b000b174117004448001f47184718011e025f1e001f3a17003218011e025f184719480019221e009d240a0000100202643d17000f18011e025f1847194801190018472d1f4716ffc618011e025f1b000b054117003618011e025f08031f8f188f21041700231f8e188e221e009d240a0000100202643e17000c18011e025f188e190016ffdc180600001f7f0202652500ba1802263e220117000a1c18020200003e1700061800001802221e0011240a0000101f0218010202533e1700771800201d01d41802221e002b240200f90a0001101f0c131e00061a001f0d180c17004a48001f0e180e180c1e001f3a17003b180d180c180e19221e002b2402002a0a0001104800191b000b22180c180e19221e002b2402002a0a000110480119040d180e2d1f0e16ffc01800180d1d00b716001718001b000b19221e02662418020a0001101d00b71800001f8002026725009318001e025f1f061b020b121e025617001f1806221e0268241b020b061e02571b020b78260a0000100a0002101c1b000b201801131e00061a002218001e025b1d025b2218061d025f2218021d00b72218001e02691d02692218001e026a1d026a2218001e026b1d026b2218001e01eb1d01eb2218001e026c1d026c2218001e026d1d026d2218001e026e1d026e1a02001f8102026f25012518011f061b020b121e02701e001f48003917008048001f0818081b020b121e02701e001f3a17006c1b020b121e02701808194800191f091809221e000f2418010a0001101700451801221e007b2418091b020b121e02701808194801190a0002101f061b020b5a1e01d2221e0023241800020271020272180128020273281806280a0003101c16000b18082d1f0816ff8a1b000b2218060418063d17000c1b000b1f1806041f061806221e0024240200e00a0001101f071807480039221700151c1806221e0274240202750a00011018073917004d1806221e00d424480018074801280a0002101f201806221e00d424180748012818061e001f0a0002101f2118201821221e002b240202750a000110221e0098240202760a000110281f061806001f8202027725002d18001800221e0024240200e00a00011048004801294017000c02027818012816000902027918012828001f8302027a2500141b020b7a1800041c1b020b7d1800041c001f8402027b25000b18001b020b8741001f8502027c250019111b000b19221e0266241b020b860a0001101d027d001f8702027e2500c01b020b061e01cc17000526001b020b85110417000a111e027d1600071b020b121f061b000b05221e01d724180618000a0002101c1b020b8a1806041c18061e027a1700201b020b8b18061e027f041c1b020b8c18061e0280041c1b020b8411041c18061e02561700131b000b1d261b020b7748000a0002101c1b020b5d260a0000101c1b020b121e028101221700091c18061e01841700271b020b12201d02811b020b37260a0000101c1b000b1d261b020b59480018060a0003101c001f8902028225006618001e018548003e220117001c1c1b000b0c221e001d2418001e01850a00011018001e01853f17000d1b020b460202831a014718001e027a17002a18001e027f1e001f48003e220117000d1c18001e027f1e00930117000d1b020b460202841a0147001f8a02028525003f48001f06180618001e001f3a17002f180018061917001f1b020b121e0235221e0093241b000b2318001806191a010a0001101c18062d1f0616ffcc001f8b02028625004f18001b000b064017004448001f06180618001e001f3a1700351b020b121e0270221e0093241b000b2318001806194800191a0118001806194801190a00020a0001101c18062d1f0616ffc6001f8c020287250011131e028822011700071c020000001f8d0202892500561b020b0f1b020b061e028a0422011700071c0200001f061b020b111b020b061e028a041c180602028b3d17000b0200001f0616001518060200003d17000c1b000b081e02691f0618061700091318061d0288001f8e211b000b051e01d743020003401700c71b000b05221e003e241b000b050201d7131e00061a00220201d72500941800263e220117000b1c18001b000b063e17000d1b000b0702028c1a01471b000b051800041f0648011f0718071b031e001f3a17005b1b031807191f08180826402217000b1c18081b000b0640170039180808031f141814210417002c1f091b000b051e00221e028d221e002324180818090a00021017000d1806180918081809190d16ffd318072d1f0716ffa01806001f8f188f1d028e22201d028f22201d02900a0003101c1b000b051e00f1011701141b000b050200002501021b000b051e00221e028d1f06131e00061a0022261d0011221e0291240200110a000110011f0702001102029202029302028d02029402029102000d0a00071f0818081e001f1f090200002500b42118004302000340221700161c211800430200014022011700081c1800263e17000d1b000b070202951a01470a00001f06180008031f121812210417002a1f071b030b06221e002324180018070a0002101700111806221e00932418070a0001101c16ffd51b030b0717004548001f0818081b030b093a1700371b030b06221e00232418001b030b081808190a0002101700161806221e0093241b030b081808190a0001101c18082d1f0816ffc518060000260a0000101d00f1131e00061a00220202961d01a32248021d01dd22121d01cc220202881d028a220202971d01df220202981d02571f06131e00061a0022121d02992248001d018522121d018422121d025622121d027a220a00001d027f220a00001d0235220a00001d0280220a00001d02702202029a1d017d2202029b1d00df2202029c1d029d1f12131e00061a001f1a14029e1f1f48001f3002000025001e1b021b020b351d029f1b0218001d02a01b020b32180048023404001f34271f3302000025002a1b021b020b361d029f1b020b30481c331800480435301f061b0218001d02a01b020b32180604001f350200002500271b021b020b341d029f1b020b321b020b30481a33180048063530041b020b3118000428001f36131e00061a0022020000250049121f061b020b85110417000f111e027d1e02991f0616000c1b020b121e02991f061806221700201c1b000b11221e0042240202a11800280202a2280202a318010a0003101c001d01d21f5a131e00061a002218631d02a42218631d01b62218621d02a52218641d01bc2218641d02a61f5b121f5c0a00001f5e0a00001f5f0a00001f600200002500091800180128001f65020000250009180018002a001f660202a71f6d0202a81f6e1b000b202217000d1c1b000b201b000b05411f7b1b000b212217000d1c1b000b211b000b05411f7c1b000b19221e00fb2418120a0001101f86186f1f8818871e002218891d027e18871e002218881d025518871e0022188d1d02871806122217000b1c180d260a0000101d01cc188e260a0000101c180018871d027c1800188d1d0287180018891d027e180018881d02551b000b05221e003e2418000202a9131e00061a0022201d028e0a0003101c000a0002101c0002aa00066d606867617609776c6667646b6c67660864776c61766b6d6c03636f6607677a726d707671064d60686761760e607b7667665d63617063756e6770046b714b470c666d61776f676c764f6d6667096b71446b7067646d7a086b7151636463706b06506765477a720b616d6c7176707761766d70016b04766771760b4a564f4e476e676f676c7608766d5176706b6c6521596d60686761762251636463706b50676f6d76674c6d766b646b6163766b6d6c5f0671636463706b107277716a4c6d766b646b6163766b6d6c0c656776566b6f677176636f7207656776566b6f670865677654636e776707606d6d6e67636c013301320c70636c666d6f5176706b6c653e32333031363734353a3b636061666764656a6b68696e6f6c6d72737071767774757a7b78434041464744454a4b48494e4f4c4d52535051565754555a5b5805646e6d6d700670636c666d6f066e676c65766a09666d6f4667766761760f596d606867617622556b6c666d755f0972706d766d767b72670461636e6e076b6c66677a4d6408466d61776f676c7612596d6068676176224c63746b6563766d705f10596d6068676176224a6b71766d707b5f0a65677644706d6f517670067176706b6c65013f0571726e6b76045939245f06616a637043760122097177607176706b6c6509656776416d6d696b670e716771716b6d6c51766d70636567076567764b76676f0c6e6d61636e51766d7063656706616d6d696b6709716776416d6d696b67077167764b76676f313f3922677a726b7067713f4f6d6c2e2230322251677222303233322232323832323832322257564139227263766a3f2d390a3922677a726b7067713f0b766d454f565176706b6c650939227263766a3f2d390966676e416d6d696b670a70676f6d74674b76676f0e66676077656567704667766761760e6667646b6c6752706d726770767b026b6608666760776565677003656776036e6d6502276107616d6c716d6e6707646b70676077650a6d77766770556b66766a0a6b6c6c6770556b66766a0b6d777667704a676b656a760b6b6c6c67704a676b656a760a6c6d66674667766761760772706d6167717110596d60686761762272706d616771715f0d726a636c766d6f46677667617607726e77656b6c71085d726a636c766d6f0b61636e6e526a636c766d6f0b5d5d6c6b656a766f637067054377666b6d1841636c74637150676c6667706b6c65416d6c76677a7630460f75676066706b7467704667766761760975676066706b746770136567764d756c52706d726770767b4c636f6771096e636c65776365677106616a706d6f670770776c766b6f6707616d6c6c676176145d5d75676066706b7467705d6774636e77637667135d5d71676e676c6b776f5d6774636e776376671b5d5d75676066706b7467705d7161706b72765d64776c61766b6d6c175d5d75676066706b7467705d7161706b72765d64776c61155d5d75676066706b7467705d7161706b72765d646c135d5d647a66706b7467705d6774636e77637667125d5d66706b7467705d776c75706372726766155d5d75676066706b7467705d776c75706372726766115d5d66706b7467705d6774636e77637667145d5d71676e676c6b776f5d776c75706372726766145d5d647a66706b7467705d776c75706372726766095d71676e676c6b776f0c61636e6e51676e676c6b776f165d51676e676c6b776f5d4b46475d5067616d7066677008666d61776f676c76056f6376616a0a5e2659632f785f66615d066163616a675d0f6b6c616d656c6b766d466776676176046d72676c096b6c616d656c6b766d076d6c6770706d7004616d66671253574d56435d475a4147474647465d47505010716d6f6749677b4a677067407b766766096b6c66677a676646400c526d6b6c7667704774676c760e4f51526d6b6c7667704774676c760a6a6d6d694667766761760d617067637667476e676f676c760661636c74637109766d4663766357504e077067726e636167035e712801650a6c63766b7467616d666714596d606867617622526e77656b6c437070637b5f0e6e6d6163766b6d6c4667766761764a5c6a767672713d385e2d5e2d2a59322f3b5f79332e317f2a5e2c59322f3b5f79332e317f2b79317f7e59632f64322f3b5f79332e367f2a3859632f64322f3b5f79332e367f2b79357f2b086e6d6163766b6d6c046a70676404646b6e67106a767672382d2d6e6d61636e6a6d717606656776457277074552574b4c444d0a656776416d6c76677a7605756760656e0c656776477a76676c716b6d6c19554740454e5d66676077655d70676c66677067705d6b6c646d0c656776526370636f6776677015574c4f43514947465d54474c464d505d554740454e17574c4f43514947465d50474c46475047505d554740454e012d0a656776526e77656b6c7106524e57454b4c046b76676f047277716a04767b7267046c636f6707746770716b6d6c08646b6e676c636f6704686d6b6c02212105716e6b61670c616d6c716b7176416a67616909777167704365676c760b766d4e6d7567704163716708726e6376646d706f07756b6c666d757103756b6c07636c66706d6b66056e6b6c777a066b726a6d6c67046b726366046b726d66036f6361096f63616b6c766d716a0c6f63615d726d75677072612b0461706d71037a33330561706b6d7105647a6b6d7104726b696708646b7067646d7a2d066d726770632d05226d72702d07616a706d6f672d0876706b66676c762d046f716b670674676c666d7006456d6d656e670568716d6c7204606d667b14656776476e676f676c7671407b5663654c636f67046a676366067161706b7276015d0961636e6e606361693f037170610b70676f6d7467416a6b6e660b637272676c66416a6b6e660e766d406b6c63707b5176706b6c650c64706d6f416a6370416d66670d766d576b6c763130437070637b0a616a6370416d66674376056b6c7631300a36303b363b3435303b37026f7a04646b7a6912676c61707b7276576b6c763130437070637b12666761707b7276576b6c763130437070637b0a7776643a476c616d66670e5c595e7a32322f5e7a35645f2826104f636e646d706f6766227176706b6c65157776643a4667616d6667516a6d70765176706b6c651f576c646b6c6b716a6766225756442f3a226d617667762271677377676c616729416a63706361766770226d7776716b66672274636e6b6622576c6b616d66672270636c65673822327a15406366225756442f3a22676c616d666b6c6522327a147776643a4667616d66674e6d6c655176706b6c650a7776643a4667616d66670e5c595e7a32322f5e7a64645f282606717760717670057a7a76676307666761707b72760e6063716734365176636c666370664046696672656a3658497153403a322d4f64747531345a4b33503037295557436e476b354c4e606d735b564d5277786f4468486c707b7a3b4a5445616351764167106063716734365d616a63704b6c66677a40434041464744454a4b48494e4f4c4d52535051565754555a5b58636061666764656a6b68696e6f6c6d72737071767774757a7b7832333031363734353a3b292d146063716734365176636c666370664667616d6667096063716734365d616a066034365d313208656776526370636f08726370636f57706e013d026d6c036d64640971677651756b76616a0e5d726370636f51756b76616a4d6c0f5d607b7667665d726370636f5d71751265677651756b76616a44706d6f4163616a670f666776676176436c6d6f636e6b67710a666b70676176516b656c0a616d6c716b7176676c760671756b76616a03666d6f046c6d666707726a636c766d6f046a6d6d690b76677176446763767770670e637171676f606e67506771776e760469677b710b7166606f5d717663606e67047166606f107166606f5d717663606e675d726d6c7b076567765263766a222a6a767672385e2d5e2d7e6a76767271385e2d5e2d7e5e2d5e2d2b3d595c5e2d5f2808656776537767707b0e593d5f2a5e75293f2c28243d2b280124076d6068516d7076097176706b6c656b647b02797f04716d70760868716d6c516d7076076b71437070637b036f637206706766776167076d6068305176701261636c7463715d646b6c65677072706b6c7605756b66766a066a676b656a760230660a3336727a227167706b6404646d6c7608646b6e6e56677a7604c09f9a8e138e22c0acbf0a716a63666d75406e77700b716a6d754d64647167765a046e6b6f6709716a6d75416d6e6d7003637061067176706d69670965677641636c7463710a313531373b303a37373b0f416d6c646b65477a616772766b6d6c076f677171636567116a6371516771716b6d6c51766d706365670f6a63714e6d61636e51766d706365670c6a63714b6c66677a676646400c65677643606b6e6b766b67710d6567765067716d6e77766b6d6c0671617067676c0a616d6e6d70466772766a126567764374636b6e5067716d6e77766b6d6c0a6374636b6e556b66766a0b6374636b6e4a676b656a760e6567764063767667707b4b6c646d0a6567764063767667707b04766a676c08616a6370656b6c650c616a6370656b6c65566b6f670f666b71616a6370656b6c65566b6f67056e6774676e0c656776566d77616a4b6c646d0e6f637a566d77616a526d6b6c76710b6170676376674774676c760a566d77616a4774676c760c6d6c766d77616a71766370760b656776566b6f67786d6c670771677646637667087167764f6d6c766a11656776566b6f67786d6c674d6464716776036f6b6c08656776446d6c7671096f6d6c6d71726361670a71636c712f7167706b64057167706b64047172636c0d6f6f6f6f6f6f6f6f6f6f6e6e6b096b6c6c67704a564f4e0571767b6e67043530727a08646d6c76516b78670a646d6c7644636f6b6e7b0b6d6464716776556b66766a0c6d64647167764a676b656a760c5670676077616a6776224f5109556b6c65666b6c657107517b6e6463676c085167656d6722574b0a416d6c7176636c766b630b516b6f51776c2f477a7640084f5622477a7670630545776e6b6f0a4e67676e6375636667670556776c6563064f676b707b6d0654706b6c666309416d70666b63575241094372637063686b7663074b706b715752410852636e63766b6c6d0a416d6e6d6c6c63224f5608526e637b606b6e6e08486d6967706f636c09526370616a6f676c760a4f51224d77766e6d6d690956752241676c224f56064d52564b4f4306447776777063064354474c4b500c43706b636e224a67607067750a5163746d7b67224e47560941637176676e6e63700a4f5b504b43462252504d012e0e656776517b6c76637a4770706d701041706763766722556760516d616967760f6567764c63766b74674e676c65766a086567765076614b720b746b746d60706d757167701150564152676770416d6c6c6761766b6d6c146f6d7850564152676770416d6c6c6761766b6d6c17756760696b7650564152676770416d6c6c6761766b6d6c1c7176776c387176776c2c6e2c656d6d656e672c616d6f38333b3132300477706e710a6b6167516770746770713e2a59322f3b5f79332e317f2a5e2c59322f3b5f79332e317f2b79317f7e59632f64322f3b5f79332e367f2a3859632f64322f3b5f79332e367f2b79357f2b355c2a333b305e2c33343a5e2c7e33343b5e2c3037365e2c7e33325e2c7e3335305e2c2a3359342f3b5f7e305e667e315932335f2b2b1161706763766746637663416a636c6c676e0b6170676376674d64646770137167764e6d61636e46677161706b72766b6d6c0961636c666b6663766704677a67610e6d6c6b616761636c666b666376670477776b66207a7a7a7a7a7a7a7a7a7a7a7a367a7a7a7b7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a04597a7b5f017a0d616a676169416e6b676c764b660b656776416e6b676c764b66057676616b660d676c61707b7276516761466b6640434041464744454a4b48494e4f4c4d52535051565754555a5b58636061666764656a6b68696e6f6c6d72737071767774757a7b7832333031363734353a3b2f2c0e637171676f606e67526370636f710172017007646d704763616a025c5c01340c647252706d646b6e6757706e033d733f087067765d616d66670264720e5d607b7667665d7167615d666b660c5d7063755d7167615d666b660776765d71616b660366647203636b66016c0164097176637076566b6f6701760963606b6e6b766b67710a766b6f677176636f7233136a63706675637067416d6c61777070676c617b0c6667746b61674f676f6d707b086e636c65776365670a7067716d6e77766b6d6c0f6374636b6e5067716d6e77766b6d6c0971617067676c566d720a71617067676c4e676476106667746b6167526b7a676e5063766b6d0a72706d66776176517760076063767667707b09766d77616a4b6c646d08766b6f67786d6c670a766b6f677176636f7230076572774b6c646d0b6871446d6c76714e6b71760b726e77656b6c714e6b71760a766b6f677176636f72310a67746770416d6d696b67016f0b717b6c76637a4770706d700c6c63766b74674e676c65766a057076614b52096472546770716b6d6c0b5d5d746770716b6d6c5d5d08616e6b676c764b660a766b6f677176636f72360b677a76676c66446b676e6603636e6e107176637076516b6f726b646b67665760106366664774676c764e6b7176676c677009636666566d4e6b71760671726e6b61670166017b136a636c666e6749677b606d6370664774676c7606636e7649677b076176706e49677b076f67766349677b08716a6b647649677b036c6d75136a636c666e67526d716b766b6d6c4774676c760e616a636c656766566d77616a677109766d77616a6f6d746707766d77616a6771023b3007616e6b676c765a07616e6b676c765b106a636c666e67416e6b61694774676c760a766d77616a71766370760861636e614f67636c1561636e615176636c666370664667746b63766b6d6c04717370760961636e61517267676604322c323315656776516b6f726e6b646b67665760506771776e7603322c3702323209656776566771764b660b5d5d63615d766771766b660f65676c6770637667566771764e6d6501600c656776516b656c63767770670377706e2c6c6d6c6167226f77717622606722636c226d606867617622756b766a22632277706e2272706d726770767b230b666d6f4c6d7654636e6b660872706d766d616d6e043232323208323232323232333302333207646d707067636e056667607765056c6d6c61670b606d667b54636e307176700a606d667b5d6a63716a3f05737767707b066371716b656c097263766a6c636f673f0976765d7567606b663f062477776b663f086c6d6c61675176700a36303b363b3435303b34096467546770716b6d6c033232320b7277716a546770716b6d6c01280a65677654636e77672633106c63746b6563766d70516b656c636e710b637272416d66674c636f67076372724c636f670772706d6677617608617277416e637171056d716172770974676c666d705177600a666d4c6d76567063616907746b60706376670b61706766676c766b636e710771766d706365671b706773776771764f67666b6349677b517b7176676f43616167717109606e7767766d6d766a0d756b6c666d75516b656c636e71054b6f6365670771617067676c5a0771617067676c5b0f6b71516761777067416d6c76677a7607766d6d6e6063700b6e6d6163766b6d6c6063700d4361766b74675a4d606867617608677a7667706c636e0b726d71764f6771716365671b756760696b7650677377677176436c6b6f63766b6d6c4470636f670d406e7767766d6d766a57574b46086c677671616372670f666d61776f676c76516b656c636e710c616a637063617667705167760a616d6f7263764f6d6667066e637b677071066b6f636567710e656776556760656e41636c74637112677a7267706b6f676c76636e2f756760656e0d6f637a436c6b716d76706d727b1e475a565d76677a767770675d646b6e7667705d636c6b716d76706d726b6125554740494b565d475a565d76677a767770675d646b6e7667705d636c6b716d76706d726b61224f4d585d475a565d76677a767770675d646b6e7667705d636c6b716d76706d726b611e4f435a5d56475a565750475d4f435a5d434c4b514d56504d525b5d475a560c756760656e516b656c636e7105554740454e16656776517772726d70766766477a76676c716b6d6c7113717772726d70766766477a76676c716b6d6c7114656776416d6c76677a76437676706b607776677109636c766b636e6b637109404e57475d404b565108606e7767406b76710a464752564a5d404b565109666772766a406b76710a455047474c5d404b565109657067676c406b7671204f435a5d414d4f404b4c47465d56475a565750475d4b4f4345475d574c4b56511c6f637a416d6f606b6c676656677a767770674b6f636567576c6b7671194f435a5d415740475d4f43525d56475a565750475d514b5847156f637a417760674f637256677a76777067516b78671c4f435a5d445043454f474c565d574c4b444d504f5d544741564d5051196f637a447063656f676c76576c6b646d706f546761766d7071154f435a5d50474c4647504057444447505d514b5847136f637a50676c666770607764646770516b7867174f435a5d56475a565750475d4b4f4345475d574c4b5651146f637a56677a767770674b6f636567576c6b7671104f435a5d56475a565750475d514b58470e6f637a56677a76777067516b7867134f435a5d5443505b4b4c455d544741564d5051116f637a5463707b6b6c65546761766d7071124f435a5d54475056475a5d435656504b4051106f637a54677076677a437676706b60711e4f435a5d54475056475a5d56475a565750475d4b4f4345475d574c4b56511a6f637a54677076677a56677a767770674b6f636567576c6b76711a4f435a5d54475056475a5d574c4b444d504f5d544741564d5051176f637a54677076677a576c6b646d706f546761766d707118514a43464b4c455d4e434c45574345475d544750514b4d4c16716a63666b6c654e636c6577636567546770716b6d6c0c5156474c414b4e5d404b56510b7176676c616b6e406b767107544750514b4d4c066563766a6770096c63746b6563766d7006756b6c666d7503657277075147414b4c444d0a6567765167614b6c646d09766b6f677176636f720d6b71476c63606e67665263766a145d676c63606e675263766a4e6b7176506765677a0c6b6c766770616772765a4a500e5a4f4e4a7676725067737767717610716776506773776771764a67636667700471676c66106d746770706b66674f6b6f67567b72670f5d63615d6b6c766770616772766766055d71676c66155d607b7667665d6b6c766770616772765d6e6b71760464776c6109637065776f676c76710e5c616d6c76676c762f767b72672601390e5d607b7667665d616d6c76676c76115d6d746770706b66674f6b6f67567b72670d5d607b7667665d6f67766a6d660a5d607b7667665d77706e076d6c63606d7076066d6c6e6d6366096d6c6e6d6366676c660b6d6c6e6d636671766370760a6d6c72706d6570677171096d6c766b6f676d77760b5d716b656c63767770673f0b5d607b7667665d606d667b126d6c706763667b7176637667616a636c65670c706771726d6c7167567b726707766b6f676d77760677726e6d636604524d5156216372726e6b6163766b6d6c2d7a2f7575752f646d706f2f77706e676c616d666766106372726e6b6163766b6d6c2d68716d6c04716b656c0371666b0d7167614b6c646d4a67636667700e6b6c76677061677276446776616a0975706372446776616a03454756066f67766a6d660b766d57727267704163716705616e6d6c670476677a76076a676366677071165d5d63615d6b6c7667706167727667665d646776616a05646776616a0d717772726d707671446776616a145d656776446776616a416d6c76676c76567b72670c616d6c76676c762f767b72670b7772666376674c6d6c61670572637071670f60776b6e664c677550677377677176037167760870676467707067700e7067646770706770526d6e6b617b046f6d6667056163616a67087067666b70676176096b6c766765706b767b0e656776506775706b76676657706e105d77706e506775706b766750776e67710b706775706b766757706e22084d504b454b4c38220b08504755504b56474638220b6e6371764b6c66677a4d640125032730350860776b6e6657706e0c245d716b656c63767770673f0c3d5d716b656c63767770673f096b6c76677061677276196b714b6c7176636c61674d64407b76676643617063756e67700d407b76676643617063756e6770076d72766b6d6c71046b6c6b760e676c63606e675263766a4e6b71760f77706e506775706b766750776e6771045d6664720f74636e6b666376674d72766b6d6c711e6d72766b6d6c22636b662a4b6c76676567702b226b71226c676766676623276d72766b6d6c22676c63606e675263766a4e6b71762a437070637b2b226b71226c6767666766231065676c5263766a4e6b7176506765677a1265676c57706e506775706b7667506765677a0a656776506764677067700c5d5d63615d70676467706770106667636e506764677067704163616a670a7067646770677049677b0a5d5d63615d606e636c692a41636c6c6d7622616d6c7467707622776c6667646b6c6766226d70226c776e6e22766d226d60686761760e6a63714d756c52706d726770767b0574636e77670875706b7663606e670c616d6c646b65777063606e671472706d726770767b4b71476c776f677063606e670e766d4e6d61636e675176706b6c650774636e77674d640d6b7152706d766d767b72674d64204d60686761762c69677b712261636e6e6766226d6c226c6d6c2f6d606867617606302c33332c320640365834756d0c5a2f4f717166692f4b6c646d03606d67296a76767271382d2d7a7a60652c716c717166692c616d6f2d7567607166692d74332d6567764b6c646d236a76767271382d2d7a7a60652c716c717166692c616d6f2d7567607166692d74332d72236a76767271382d2d7a7a60652c716c717166692c616d6f2d7567607166692d74332d7605776057706e0a3034373636313735343b02373302363a03276122022f3c0d616d6e6d703821603333376630096f6d7771676f6d74670769677b666d756c096f6d777167666d756c0232300232330a5d5d67714f6d66776e67";
window._$jsvmprt(v1, [, ,  void 0, "undefined" != typeof module ? module : void 0, "undefined" != typeof define ? define : void 0, "undefined" != typeof Object ? Object : void 0, void 0, "undefined" != typeof TypeError ? TypeError : void 0, "undefined" != typeof document ? document : void 0,  void 0,  void 0, "undefined" != typeof Date ? Date : void 0, "undefined" != typeof Math ? Math : void 0, "undefined" != typeof navigator ? navigator : void 0, "undefined" != typeof location ? location : void 0, "undefined" != typeof history ? history : void 0, "undefined" != typeof Image ? Image : void 0, "undefined" != typeof console ? console : void 0, "undefined" != typeof PluginArray ? PluginArray : void 0, "undefined" != typeof indexedDB ? indexedDB : void 0, "undefined" != typeof DOMException ? DOMException : void 0, "undefined" != typeof parseInt ? parseInt : void 0, "undefined" != typeof String ? String : void 0, "undefined" != typeof Array ? Array : void 0, "undefined" != typeof Error ? Error : void 0, "undefined" != typeof JSON ? JSON : void 0, "undefined" != typeof Promise ? Promise : void 0, "undefined" != typeof WebSocket ? WebSocket : void 0, "undefined" != typeof eval ? eval : void 0, "undefined" != typeof setTimeout ? setTimeout : void 0, "undefined" != typeof encodeURIComponent ? encodeURIComponent : void 0, "undefined" != typeof encodeURI ? encodeURI : void 0, "undefined" != typeof Request ? Request : void 0, "undefined" != typeof Headers ? Headers : void 0, "undefined" != typeof decodeURIComponent ? decodeURIComponent : void 0, "undefined" != typeof RegExp ? RegExp : void 0]);

编译通过了,下面看看byted_acrawler有没有生成并且看看有没有生成signature
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.4.1 Python获取签名值并实现
# -*- coding: utf-8 -*-# (venv) E:\crawler(爬虫)\day04> node v20.js "https://www.toutiao.com/api/pc/list/feed?offset=0&channel_id=94349549395&max_behot_time=0&category=pc_profile_channel&disable_raw_data=true&aid=24&app_name=toutiao_web"
# _02B4Z6wo00f01vu4PgAAAIDBBEfB.ftCImL7mjqAANsre0import os
import subprocess# 根据自己的操作系统去修改(相当于python的sys.path,加载安装的模块)
os.environ["NODE_PATH"] = "D:\\Nodejs\\node_global\\node_modules"url = "https://www.toutiao.com/api/pc/list/feed?offset=0&channel_id=94349549395&max_behot_time=0&category=pc_profile_channel&disable_raw_data=true&aid=24&app_name=toutiao_web"
result = subprocess.run(f'node v20.js "{url}"', shell=True, stdout=subprocess.PIPE)
signature = result.stdout.decode('utf-8')print(signature)

在这里插入图片描述
得到签名在让url拼接起来已发送请求就应该获取到评论
在这里插入图片描述
拿着url再去发送请求
在这里插入图片描述

4.pyexecjs签名并实现

在这里插入图片描述
在这里插入图片描述

import requests
import execjs
import osos.environ["NODE_PATH"] = "D:\\Nodejs\\node_global\\node_modules"
with open('v20.js', mode='r', encoding='utf-8') as f:js = f.read()
JS = execjs.compile(js)url = "https://www.toutiao.com/api/pc/list/feed?offset=0&channel_id=94349549395&max_behot_time=0&category=pc_profile_channel&disable_raw_data=true&aid=24&app_name=toutiao_web"
signature = JS.call("get_sign", url)final_url = f"{url}&_signature={signature}"res = requests.get(url=final_url,headers={"user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36"}
)print(res.text)

六、知网资料批量爬取并可视化展示

1.批量爬取知网数据

  • lxml:是 Python 的一个功能强大且易用的 XML 和 HTML 处理库。它提供了简单又轻巧的 API,使得解析、构建和操作
    XML 和 HTML 文档变得非常方便。lxml 库通常用于处理 XML 和 HTML 文档,例如解析网页、处理配置文件等。
  • openpyxl:是 Python 中用于操作 Excel 文件(.xlsx 格式)的库。通过 openpyxl,你可以读取、修改和创建 Excel 文件,包括对工作表、单元格内容、样式等的操作。这个库在处理 Excel 数据时非常方便,可以用于数据处理、报表生成等应用场景。
    在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

import requests
from lxml import etree
from openpyxl import Workbookbase_url = 'http://search.cnki.com.cn/Search/ListResult'headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36'
}def get_page_text(url, headers, search_word, page_num):data = {'searchType': 'MulityTermsSearch','ArticleType': '','ReSearch': '','ParamIsNullOrEmpty': 'false','Islegal': 'false','Content': search_word,'Theme': '','Title': '','KeyWd': '','Author': '','SearchFund': '','Originate': '','Summary': '','PublishTimeBegin': '','PublishTimeEnd': '','MapNumber': '','Name': '','Issn': '','Cn': '','Unit': '','Public': '','Boss': '','FirstBoss': '','Catalog': '','Reference': '','Speciality': '','Type': '','Subject': '','SpecialityCode': '','UnitCode': '','Year': '','AcefuthorFilter': '','BossCode': '','Fund': '','Level': '','Elite': '','Organization': '','Order': '1','Page': str(page_num),'PageIndex': '','ExcludeField': '','ZtCode': '','Smarts': '',}response = requests.post(url=url, headers=headers, data=data)page_text = response.textreturn page_textdef list_to_str(my_list):my_str = "".join(my_list)return my_strdef get_abstract(url):response = requests.get(url=url, headers=headers)page_text = response.texttree = etree.HTML(page_text)abstract = tree.xpath('//div[@class="xx_font"]//text()')return abstractdef parse_page_text(page_text):tree = etree.HTML(page_text)item_list = tree.xpath('//div[@class="list-item"]')page_info = []for item in item_list:# 标题title = list_to_str(item.xpath('./p[@class="tit clearfix"]/a[@class="left"]/@title'))# 链接link = 'https:' + \list_to_str(item.xpath('./p[@class="tit clearfix"]/a[@class="left"]/@href'))# 作者author = list_to_str(item.xpath('./p[@class="source"]/span[1]/@title'))# 出版日期date = list_to_str(item.xpath('./p[@class="source"]/span[last()-1]/text() | ./p[@class="source"]/a[2]/span[1]/text() '))# 关键词keywords = list_to_str(item.xpath('./div[@class="info"]/p[@class="info_left left"]/a[1]/@data-key'))# 摘要abstract = list_to_str(get_abstract(url=link))# 文献来源paper_source = list_to_str(item.xpath('./p[@class="source"]/span[last()-2]/text() | ./p[@class="source"]/a[1]/span[1]/text() '))# 文献类型paper_type = list_to_str(item.xpath('./p[@class="source"]/span[last()]/text()'))# 下载量download = list_to_str(item.xpath('./div[@class="info"]/p[@class="info_right right"]/span[@class="time1"]/text()'))# 被引量refer = list_to_str(item.xpath('./div[@class="info"]/p[@class="info_right right"]/span[@class="time2"]/text()'))item_info = [i.strip() for i in[title, author, paper_source, paper_type, date, abstract, keywords, download, refer, link]]page_info.append(item_info)print(page_info)return page_infodef write_to_excel(info, search_word):wb = Workbook()ws = wb.active  # 创建子表ws.title = search_wordtitle = ['title', 'author', 'paper_source', 'paper_type', 'date', 'abstract', 'keywords', 'download', 'refer','link']  # 设置表头ws.append(title)for row in info:ws.append(row)wb.save('data.xlsx')return True# 获取页面数据1页
page_text = get_page_text(base_url, headers, 'YOLOV5', 1)# 解析页面数据
page_info = parse_page_text(page_text)
# # 添加循环遍历1到10页
# page_info_list = []
# for page_num in range(1, 11):
#     page_text = get_page_text(base_url, headers, 'YOLOV5', page_num)
#     page_info = parse_page_text(page_text)
#     page_info_list.extend(page_info)# 读取excel表格
write_to_excel(page_info, 'YOLOV5')# 将整个列表写入 Excel 文件
# write_to_excel(page_info_list, 'YOLOV5')

2.数据可视化

可视化第一作者、下载量、被引量

  • pandas 是一个强大的数据分析工具,主要用于数据的清洗、处理、分析和建模。它提供了快速、灵活、简单和实用的数据结构,使您能够轻松地操作结构化数据。
  • matplotlib.pyplot 是 Matplotlib 库的一部分,用于创建各种类型的图表,包括折线图、散点图、柱状图、饼图等。通过 matplotlib.pyplot,您可以将 pandas 中处理过的数据可视化,以便更直观地理解数据、分析数据间的关系,或进行结果的展示和分享。

在这里插入图片描述

import pandas as pd
import matplotlib.pyplot as plt# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False# 从 Excel 文件中读取数据
df = pd.read_excel('data.xlsx')# 提取每篇论文的第一个作者
df['first_author'] = df['author'].str.split(';').str[0]# 统计第一个作者的出现次数
first_author_counts = df['first_author'].value_counts()# 创建第一个作者条形图
plt.figure(figsize=(12, 8))
plt.barh(range(len(first_author_counts)), first_author_counts.values, align='center', alpha=0.5, color='skyblue')
plt.yticks(range(len(first_author_counts)), first_author_counts.index)
plt.xlabel('第一个作者出现次数')
plt.title('第一个作者', pad=20)
plt.gca().invert_yaxis()
plt.tight_layout(pad=2.0, rect=[0, 0.03, 1, 0.95])
plt.show()# 创建下载量条形图
plt.figure(figsize=(8, 6))
plt.barh(df['title'], df['download'], color='lightgreen')
plt.ylabel('论文标题')
plt.xlabel('下载量', labelpad=20)
plt.xticks([])          # 将 x 轴的刻度设置为空列表
plt.title('下载量', pad=20)
plt.tight_layout(pad=2.0, rect=[0, 0.03, 1, 0.95])
plt.show()# 创建被引量条形图
plt.figure(figsize=(8, 6))
plt.barh(df['title'], df['refer'], color='gold')
plt.xlabel('被引量')
plt.title('被引量', pad=20)
plt.tight_layout(pad=2.0, rect=[0, 0.03, 1, 0.95])
plt.show()

相关文章:

熟练掌握爬虫技术

一、Crawler、Requests反爬破解 1. HTTP协议与WEB开发 1. 什么是请求头请求体&#xff0c;响应头响应体 2. URL地址包括什么 3. get请求和post请求到底是什么 4. Content-Type是什么1.1 简介 HTTP协议是Hyper Text Transfer Protocol&#xff08;超文本传输协议&#xff09;…...

基于Spring Boot与Vue的智能房产匹配平台+文档

博主介绍&#xff1a;✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示&#xff1a;文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐&#xff1a;最热的500个选题…...

【VMware】VMware 开启的虚拟机无法联网的解决方案

目录 &#x1f30a;1. 问题说明 &#x1f30a;2. 解决方案 &#x1f30d;2.1 查看虚拟网络编辑器 &#x1f30d;2.2 设置 vmnet &#x1f30d;2.3 设置虚拟机网络 &#x1f30d;2.4 Xshell连接虚拟机 &#x1f30a;1. 问题说明 虚拟机 ping 其他网页显示失败,比如&#…...

linux——线程

在 Linux 系统中&#xff0c;进程和线程是两种重要的并发执行单元。本文将详细介绍它们的区别、使用场景、以及多线程编程中的关键API和示例代码。 进程与线程的区别 进程 进程是程序运行的一个实例&#xff0c;承担分配系统资源的基本单位。每个进程都有独立的地址空间&…...

install nebula with source

linux 环境&#xff1a;ubuntu 2004 默认gcc 7.5 nebula requerment&#xff1a; g 8.5 above 下载source git clone --branch release-3.8 https://github.com/vesoft-inc/nebula.git install gcc g 11 apt install gcc-11 g-11 此时 linux环境存在多个版本gcc&#xff1a…...

拆分盘投资策略解析:机制、案例与风险考量

一、引言 随着互联网技术的迅猛发展和金融市场的不断创新&#xff0c;拆分盘这一投资模式逐渐崭露头角&#xff0c;成为投资者关注的焦点。它基于特定的拆分策略&#xff0c;通过调整投资者持有的份额和单价&#xff0c;实现了看似稳健的资产增长。本文旨在深入探讨拆分盘的运…...

Redis主从复制、哨兵模式以及Cluster集群

一.主从复制 1.主从复制的概念 主从复制&#xff0c;是指将一台Redis服务器的数据&#xff0c;复制到其他的Redis服务器。前者称为主节点(Master)&#xff0c;后者称为从节点(Slave)&#xff1b;数据的复制是单向的&#xff0c;只能由主节点到从节点。默认情况下&#xff0c;…...

【chatgpt】npy文件和npz文件区别

npy文件和npz文件都是用于存储NumPy数组的文件格式。它们的主要区别如下&#xff1a; npy文件&#xff1a;这种文件格式用于存储单个NumPy数组。它是一种简单的二进制文件格式&#xff0c;可以快速地读写NumPy数组。 npz文件&#xff1a;这种文件格式是一个压缩包&#xff0c;…...

为什么IP地址会被列入黑名单?

您是否曾经历过网站访客数量骤减或电子邮件投递失败的困扰&#xff1f;这背后或许隐藏着一个常被忽略的原因&#xff1a;您的IP地址可能已经被列入了黑名单内。尽管您并没有进行任何违法的网络操作&#xff0c;但这个问题依然可能出现。那么&#xff0c;究竟黑名单是什么&#…...

【OceanBase诊断调优】—— 如何查找表被哪些其它表引用外键

本文详述如何查找指定表是否被其他表引用做外键。 适用版本 OceanBase 数据库所有版本。 MySQL 租户 obclient> select * from INFORMATION_SCHEMA.KEY_COLUMN_USAGE where REFERENCED_TABLE_NAME表名;Oracle 租户 obclient> SELECT TABLE_NAME FROM dba_constraint…...

网络编程常见问题

1、TCP状态迁移图 2、TCP三次握手过程 2.1、握手流程 1、TCP服务器进程先创建传输控制块TCB&#xff0c;时刻准备接受客户进程的连接请求&#xff0c;此时服务器就进入了LISTEN&#xff08;监听&#xff09;状态&#xff1b; 2、TCP客户进程也是先创建传输控制块TCB&#xff…...

回调函数的使用详解

实际工作中&#xff0c;经常使用回调函数。用来实现触发等机制&#xff0c;也是基于一些已开发好的底层平台&#xff0c;开发上层应用的常用方法。下面对回调函数做一个详细的解释。 目录 1. 简单的回调函数实例 2. C11&#xff0c;使用function<>的写法 3. 注册函数 …...

<电力行业> - 《第8课:输电(一)》

1 输电环节的意义 电能的传输&#xff0c;是电力系统整体功能的重要组成环节。发电厂与电力负荷中心通常都位于不同地区。在水力、煤炭等一次能源资源条件适宜的地点建立发电厂&#xff0c;通过输电可以将电能输送到远离发电厂的负荷中心&#xff0c;使电能的开发和利用超越地…...

【python学习】 __pycache__ 文件是什么

__pycache__文件是Python中的一个特殊目录&#xff0c;主要用于存储已编译的字节码文件&#xff08;.pyc文件&#xff09;。以下是关于__pycache__文件的详细解释&#xff1a; 作用&#xff1a;当Python解释器执行一个模块时&#xff0c;它会首先检查是否存在对应的.pyc文件。…...

论文阅读_基本于文本嵌入的信息提取

英文名&#xff1a;Embedding-based Retrieval with LLM for Effective Agriculture Information Extracting from Unstructured Data 中文名&#xff1a;基于嵌入的检索&#xff0c;LLM 从非结构化数据中提取有效的农业信息 地址: https://arxiv.org/abs/2308.03107 时间&…...

kafka学习笔记08

Springboot项目整合spring-kafka依赖包配置 有这种方式&#xff0c;就是可以是把之前test里的配置在这写上&#xff0c;用Bean注解上。 现在来介绍第二种方式&#xff1a; 1.添加kafka依赖&#xff1a; 2.添加kafka配置方式: 编写代码发送消息&#xff1a; 测试&#xff1a; …...

Flask的 preprocess_request

理解 Flask 类似框架中的 preprocess_request 方法 在 Flask 类似的 web 框架中&#xff0c;preprocess_request 方法是一个关键组件。它在请求被分派之前调用&#xff0c;用于执行一些预处理操作。让我们一步一步来理解这个方法的工作原理。 1. 方法概述 首先&#xff0c;我…...

重温react-05(类组件生命周期和性能优化)

类组件的生命周期 import React, { Component } from reactexport default class learnReact05 extends Component {state {number: 1}render() {return (<div>{this.state.number}</div>)}// 一般将请求的方法,放在这个生命周期componentDidMount() {setInterva…...

RHCE四---web服务器的高级优化方案

一、Web服务器&#xff08;2&#xff09; 基于https协议的静态网站 概念解释 HTTPS&#xff08;全称&#xff1a;Hyper Text Transfer Protocol over Secure Socket Layer 或 Hypertext TransferProtocol Secure&#xff0c;超文本传输安全协议&#xff09;&#xff0c;是以…...

Pytest集成Allure生成测试报告

# 运行并输出报告在Report文件夹下 查看生成的allure报告 1. 生成allure报告&#xff1a;pycharm terminal中输入命令&#xff1a;产生报告文件夹 pytest -s --alluredir../report 2. pycharm terminal中输入命令&#xff1a;查看生成的allure报告 allure serve ../report …...

SpringBoot 参数校验

参数校验 引入springvalidation依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId> </dependency>参数前添加Pattern public Result registry(Pattern(regexp &qu…...

【Arduino】实验使用ESP32控制可编程继电器制作跑马灯(图文)

今天小飞鱼实验使用ESP控制继电器&#xff0c;为了更好的掌握继电器的使用方法这里实验做了一个跑马灯的效果。 这里用到的可编程继电器&#xff0c;起始原理并不复杂&#xff0c;同样需要ESP32控制针脚输出高电平或低电平给到继电器&#xff0c;继电器使用这个信号控制一个电…...

islower()方法——判断字符串是否全由小写字母组成

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 语法参考 islower()方法用于判断字符串是否由小写字母组成。islower()方法的语法格式如下&#xff1a; str.islower() 如果字符串中包含至少一个区…...

发布/订阅模式

实现发布/订阅模式的基本思路是通过一个中介者&#xff08;发布者&#xff09;来管理订阅者&#xff08;监听器&#xff09;&#xff0c;并在特定事件发生时通知所有订阅者执行相应的操作。下面是实现发布/订阅模式的基本思路&#xff1a; 创建发布者对象&#xff1a;首先&…...

K8S Pod常见状态

这是自己所遇到 Pod 常见状态及可能原因&#xff0c;持续更新。 如有其他的错误状态&#xff0c;可私我更新 1. ImagePullBackOff 问题分析&#xff1a; 镜像拉取失败。 可能原因&#xff1a; 可能是网络问题导致&#xff0c;检查Pod所在节点是否能够正常访问网络; 镜…...

Hadoop3:Yarn常用Shell命令

一、查看任务 1、查看所有任务 yarn application -list2、根据状态查看任务 语法 yarn application -list -appStates &#xff08;所有状态&#xff1a;ALL、NEW、NEW_SAVING、SUBMITTED、ACCEPTED、RUNNING、FINISHED、FAILED、KILLED&#xff09;例如 yarn application…...

15.数据库简介+MySQl使用+SQL语句

文章目录 数据库简述一.数据库简介DB1.定义:2.DBMS数据库管理系统3.数据库分类 二.MySQL的安装1.安装步骤2.MySQL数据库图形管理工具3.mysql程序常用命令4.MySQL字符集及字符序5.Navicat快捷键操作 三.MySQL数据库基本操作 .........................................表管理一.…...

AI入门系列:工具篇之ChatGPT的优秀的国内替代品

文章目录 一&#xff0c;智谱清言(ChatGLM)1&#xff0c;智谱清言简介2&#xff0c;[智谱清言地址&#xff0c;点我开始用吧](https://chatglm.cn/) 二&#xff0c;Kimi智能助手1&#xff0c;Kimi简介2&#xff0c;[Kimi地址&#xff0c;点我开始用吧](https://kimi.moonshot.c…...

改机软件有哪些?实现一键新机、改串号、改IMEI和手机参数的需求 硬改手机软件,新机环境模拟 设备伪装,一键改机,一键复原

这次针对可以直接开端口修改参数的机型做一些工具解析 前面接触合作过很多工作室。其中很多工作室对于各自软件的跳验证有各自的需求。 一个机型各项参数一般有IMEI WiFi 蓝牙 sn psb ESN等等。 针对这些参数的修改首先要明白各自软件检测的具体是哪些参数来验证。 对于常用…...

如何快速使用JNI

文章目录 1_JNI是什么&#xff1f;2_使用3_扩展 1_JNI是什么&#xff1f; JNI 是Java Native Interface的缩写&#xff0c;通过JNI&#xff0c;允许Java代码与其他语言&#xff08;通常是C或C&#xff09;编写的本地应用程序或库进行交互。简而言之就是&#xff0c;Java可以通…...

simulink开发stm32,使用中断模块,无法产生中断,其中包括使用timer模块,以及ADC都无法产生中断,需要注意的地方

1&#xff0c;其中包括使用timer模块&#xff0c;以及ADC都无法产生中断&#xff0c;需要注意的地方 原来是需要在配置文件里开启一下timer的中断&#xff0c;其他模块自动加载ioc就可以了&#xff0c;这个timer需要注意力&#xff0c;需要自己勾选一下 如下图&#xff1a; 看…...

C# 如何单纯的优化循环

Parallel.For(0, 10000, i >{// 并行执行的代码块// 例如: Console.WriteLine(i);}); 这种循环比 单纯常用的for 和 foreach 要稍微快一点 但是呢如果循环里面写的是非常简单的业务逻辑 的话 for和foreach 要更胜一筹一点 Parallel 原理就好像我一个人忙不过来可以多找几个…...

【鸿蒙学习笔记】@Extend装饰器:定义扩展组件样式

官方文档&#xff1a;Extend装饰器&#xff1a;定义扩展组件样式 [Q&A] Extend装饰器 作用 Extend用于扩展原生组件样式。 [Q&A] Extend装饰器 特点 &#xff11;・Extend仅支持在全局定义&#xff0c;不支持在组件内部定义。 &#xff12;・Extend支持封装指定组件的…...

【Docker项目实战篇】Docker部署PDF多功能工具Stirling-PDF

【Docker项目实战篇】Docker部署PDF多功能工具Stirling-PDF 前言一、Stirling-PDF介绍1.1 Stirling-PDF简介1.2 Stirling-PDF功能 二、本次实践规划2.1 本地环境规划2.2 本次实践介绍 三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本 四…...

【算法训练记录——Day37】

Day37——贪心Ⅴ 1.leetcode_56合并区间 1.leetcode_56合并区间 思路&#xff1a;排序&#xff0c;如果重叠&#xff0c;更新right 为max(right, curVal), 不重叠就加入res,需要单独考虑最后一次&#xff0c;因为每次都是在下一次遍历开始时判断是否加入res&#xff0c;因此 当…...

OpenCV 张正友标定法(二)

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 在之前的博客OpenCV 张氏标定法中,我们没有考虑镜头畸变等因素,因此计算出的内参与外参均是理想情况下的数值,而如果我们考虑到镜头的畸变: 我们就需要考虑使用最小二乘法最小化像素坐标的重投影误差(上述所求…...

LeetCode题练习与总结:环形链表Ⅱ--142

一、题目描述 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测…...

【kaptcha】kaptcha验证码的使用-SpringBoot集成

Kaptcha验证码的依赖 <dependency><groupId>com.github.penggle</groupId><artifactId>kaptcha</artifactId><version>2.3.2</version> </dependency> Kaptcha验证码的配置类&#xff0c;对验证码的一些属性进行配置&#x…...

golang template模板嵌套语法 为何不能使用变量 底层源码解析

我们都知道在golang的模板语法中&#xff0c;我们可以使用template关键字嵌套其他模块&#xff0c; 如&#xff1a; {{template "模板文件名" .}} 然而&#xff0c;这里的 “模板文件名” 是不能使用变量的&#xff01; 注意这里最后的的 . 这个实际上是templa…...

【Linux】线程Thread

&#x1f525;博客主页&#xff1a; 我要成为C领域大神&#x1f3a5;系列专栏&#xff1a;【C核心编程】 【计算机网络】 【Linux编程】 【操作系统】 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 本博客致力于知识分享&#xff0c;与更多的人进行学习交流 ​ ​ 线程概述 …...

RAG技术:在自然语言处理中的深度融合与创新

在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;随着技术的不断进步&#xff0c;我们见证了各种创新方法的涌现。其中&#xff0c;检索增强生成&#xff08;Retrieval-Augmented Generation&#xff0c;简称RAG&#xff09;技术以其独特的优势&#xff0c;逐渐成为…...

什么是std::bind

2024年6月29日&#xff0c;周日下午 std::bind 是一个C11标准库中的函数&#xff0c;它用于将一个函数或函数对象与特定的参数绑定在一起&#xff0c;生成一个新的函数对象。 std::bind通常和std::function一起使用&#xff0c;因为std::function可以作为一个函数容器来接收st…...

C语言的数据结构:树与二叉树(哈夫曼树篇)

前言 上篇讲完了二叉树&#xff0c;二叉树的查找性能要比树好很多&#xff0c;如平衡二叉树保证左右两边节点层级相差不会大于1&#xff0c;其查找的时间复杂度仅为 l o g 2 n log_2n log2​n&#xff0c;在两边层级相同时&#xff0c;其查找速度接近于二分查找。1w条数据&am…...

docker 安装syslog

Syslog-ng是一个可靠、多功能的日志管理系统&#xff0c;用于收集日志并将其转发到指定的日志分析工具。 使用Docker CLI方式搭建 步骤 1: 拉取Syslog-ng镜像 首先&#xff0c;需要从Docker Hub拉取Syslog-ng的官方镜像。 docker pull balabit/syslog-ng:latest 步骤 2: 启动…...

什么是无头浏览器?

简而言之&#xff0c;无头浏览器是没有图形用户界面 &#xff08;GUI&#xff09; 的 Web 浏览器。GUI 包括用户与之交互的数字元素&#xff0c;例如按钮、图标和窗口。但是&#xff0c;关于无头浏览器&#xff0c;您需要了解的还有很多。 在本文中&#xff0c;您将了解什么是…...

【面试干货】与的区别:位运算符与逻辑运算符的深入探讨

【面试干货】&与&&的区别&#xff1a;位运算符与逻辑运算符的深入探讨 1、&&#xff1a;位运算符2、&&&#xff1a;逻辑运算符3、&与&&的区别 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; & 和 …...

搭建Renesas R7FA8D1BHECBD-BTB的开发调试环境(DAP-LINK: N32G45XVL-STB)

目录 概述 1 软硬件 1.1 软硬件环境信息 1.2 开发板信息 1.3 调试器信息 2 FSP和KEIL产生测试项目 2.1 FSP生成项目 2.2 Keil中配置 3 硬件连接框图 4 一个测试案例 4.1 功能介绍 4.2 定时器函数 5 测试 搭建Renesas R7FA8D1BHECBD-BTB的开发调试环境&#xff08…...

探索人工智能和LLM对未来就业的影响

近年来&#xff0c;人工智能&#xff08;AI&#xff09;迅猛发展&#xff0c;引发了人们的兴奋&#xff0c;同时也引发了人们对就业未来的担忧。大型语言模型&#xff08;LLM&#xff09;就是最新的例子。这些强大的人工智能子集经过大量文本数据的训练&#xff0c;以理解和生成…...

钓鱼网站原理与攻防

知识点&#xff1a;LAMP平台部署&#xff0c;Web架构分析&#xff0c;钓鱼网站原理与搭建 中间件&#xff1a; 中间件是一种独立的软件&#xff0c;位于客户机和服务器之间&#xff0c;主要用于在网络环境中进行数据的传输和通信。它充当客户端和服务端之间的桥梁&#xff0c;…...

Windows 中 Chrome / Edge / Firefox 浏览器书签文件默认存储路径

1. Chrome 浏览器 按组合键 Win R&#xff0c;打开运行对话框&#xff0c;输入 %USERPROFILE%\AppData\Local\Google\Chrome\User Data\Default或在Chrome 浏览器地址栏输入 chrome://version查看【个人资料路径】 2. Edge 浏览器 按组合键 Win R&#xff0c;打开运行对…...

python入门详细介绍

Python 是一种广泛使用的高级编程语言&#xff0c;以其清晰的语法和代码可读性而闻名。它支持多种编程范式&#xff0c;包括面向对象、命令式、函数式和过程式编程。Python 由 Guido van Rossum 于1989年底发明&#xff0c;第一个公开发行版发行于1991年。 Python 的特点&…...

AI革命:RAG技术引领未来智能

AI革命:RAG技术引领未来智能 在人工智能的浪潮中,一种名为RAG(Retrieval-Augmented Generation)的技术正在悄然改变我们的世界。这种技术通过整合外部知识库,极大地增强了大型语言模型(LLM)的性能,为智能助手、聊天机器人等应用带来了革命性的提升。 1 突破性的RAG技…...

Android - 模拟器

Android SDK 包括一个在您的计算机上运行的虚拟移动设备模拟器。 该模拟器可让您在不使用物理设备的情况下对 Android 应用程序进行原型设计、开发和测试。 在本章中&#xff0c;我们将探索真实安卓设备中存在的模拟器中的不同功能。 创建 AVD 如果您想模拟真实设备&#xff0c…...

WordPress网站如何做超级菜单(Mega Menu)?

大多数的网站菜单都是像以下这种条状的形式&#xff1a; 这种形式的是比较中规中矩的&#xff0c;大多数网站都在用的。当然还有另外一种菜单的表现形式&#xff0c;我们通常叫做“超级菜单”简称Mega Menu。网站的超级菜单&#xff08;Mega Menu&#xff09;是一种扩展的菜单&…...

UrbanGPT: Spatio-Temporal Large Language Models

1.文章信息 本次介绍的文章是2024年arxiv上一篇名为《UrbanGPT: Spatio-Temporal Large Language Models》的文章&#xff0c;UrbanGPT旨在解决城市环境中的时空预测问题&#xff0c;通过大语言模型&#xff08;LLM&#xff09;的强大泛化能力来应对数据稀缺的挑战。 2.摘要 Ur…...

Vue85-Vuex的求和案例

一、需求 二、开发 2-1、index.js中vuex的代码 注意&#xff1a; 书写格式&#xff1a;actions中的函数名用小写&#xff01;mutations中的函数名&#xff0c;用大写。 注意&#xff1a; 2-2、组件count.vue中的代码 2-3、代码优化 三、actions中的context参数 此写法的后…...

来自90年前的首款银箭赛车,梅赛德斯-奔驰W25创造无数传奇

90年前,这款银色单座赛车奠定了“银箭”这个名称,至今仍适用于梅赛德斯-奔驰的赛车。梅赛德斯-奔驰W25于1934年6月3日在纽博格林的艾菲尔赛事中首次亮相,Manfred von Brauchitsch赢得比赛,创下平均时速122.5公里的新纪录。这是成功故事的开始,延续至今天的梅赛德斯-AMG Pe…...

问界新M7Max焕新版将于5月31日发布,底盘升级,预售价29.8万

近日,余承东通过微博分享,问界新M7 Max焕新版将在底盘性能上进行升级,其引入了CDC连续可变阻尼减振器技术,能够根据不同驾驶场景自动调节悬挂软硬程度。同时,在华为智能化控制的助力下,新车将在操控性能、行驶感受和舒适感上带来更好的体验。目前,问界新M7 Max焕新版已经…...

史上最小沃尔沃!沃尔沃EX30这次玩点不合群的

如今的新能源市场竞争到了白热化阶段,传统车企与新势力车企纷纷都要加入分一杯羹。为抢夺这块肥美的“大蛋糕”,现在的大部分车型逐渐演变成以大为尊,设计苟同,疯狂堆料为潮流。这时沃尔沃带着旗下最小尺寸的新能源SUV闪亮登场,不走寻常路,选择回归本质、返璞归真,为用户…...

发挥直接融资支撑作用助力发展新质生产力

多位专家5月27日在“布雷顿森林体系:过去80年与未来展望”国际会议暨2024清华五道口全球金融论坛上表示,建设金融强国要看重质量和功能,从数量驱动到质量引领是建设金融强国的必由之路。同时,在发展新质生产力的过程中,直接融资可发挥重要支撑作用,应进一步推动我国多层次…...

【CSharp】判断目录以及文件是否存在

【CSharp】判断目录以及文件是否存在 1.背景2.判断目录3.判断文件1.背景 我们在进行磁盘IO的时候进行需要判断目录、文件是否存在,根据判断结果再做进一步的操作。 其中判断目录是否存在,涉及Directory.Exists(String) 方法; 命名空间:System.IO 方法功能:确定给定路径是…...

【大数据】Hadoop 2.X和1.X升级优化对比

目录 1.前言 2.hadoop 1.X的缺点和优化方向 3.解决NameNode的局限性 3.1.Hadoop HA 3.2.Haddop federation 4.yarn 5.周边组件 1.前言 本文是作者大数据系列中的一文&#xff0c;专栏地址&#xff1a; https://blog.csdn.net/joker_zjn/category_12631789.html?spm10…...