一、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 requests
headers = {
"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 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",
}
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=edbee4e5d1e92f13505050505a6e17fe06486a8f; xqat=edbee4e5d1e92f13505050505a6e17fe06486a8f; xq_r_token=1bd9fe13505050505d1a3f9e12934cdaa1dc53; xq_id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJ1aWQiOi0xLCJpc3MiOiJ1YyIsImV4cCI6MTcwODQ3NjMzNiwiY3RtIjoxNzA2MTk1NzQ0NzM1LCJjaWQiOiJkOWQwbjRBWnVwIn0.Dajzah-CDQ8ER2qN9cHnYH_TPjSiYoXzl7Ht1J_CE4TxQRbH8qEzrXe4LcT4KDd815rQOZ6DF4SORJbA1qltAQ-EmD1NiD0YX0FV-Ub-5ok2FDoLcD4_9dS3iNkpIyAQE8DNJZEMBUv4TuLl8tGh7g5l9PpcOlV-_rC5OYXTckDCklU5WNkvPRsSis2nIohnkz4up2STWsB1IowmYgAN3cTXABy5wFmpEY-KUsGYi49UGH5QSYzfAYdbOxVFO5YWOiKrzXV_GIJNRvL2G0N3wQBzMew-fpB0fopKO6BbzzdbKbY2hccxx3p27a_6b7hqED0PoMO34fUKH8z6p5yqvA; cookiesu=13505050505; u=13505050505; device_id=11c12c1015a4baf7b13505050505b7589c02; Hm_lvt_1db88642e13505050505b5a1eded6e3=13505050505; Hm_lpvt_1db88642e13505050505b5a1eded6e3=13505050505"
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=edbee4e5d1e92f13505050505a6e17fe06486a8f; "
# "xqat=edbee4e5d1e92f13505050505a6e17fe06486a8f; "
# "xq_r_token=1bd9fe13505050505d1a3f9e12934cdaa1dc53; "
# "xq_id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9."
# "eyJ1aWQiOi0xLCJpc3MiOiJ1YyIsImV4cCI6MTcwODQ3NjMzNiwiY3RtIjoxNzA2"
# "MTk1NzQ0NzM1LCJjaWQiOiJkOWQwbjRBWnVwIn0.Dajzah-CDQ8ER2qN9cHnYH_"
# "TPjSiYoXzl7Ht1J_CE4TxQRbH8qEzrXe4LcT4KDd815rQOZ6DF4SORJbA1qltAQ-"
# "EmD1NiD0YX0FV-Ub-5ok2FDoLcD4_9dS3iNkpIyAQE8DNJZEMBUv4TuLl8tGh7g5"
# "l9PpcOlV-_rC5OYXTckDCklU5WNkvPRsSis2nIohnkz4up2STWsB1IowmYgAN3cTXAB"
# "y5wFmpEY-KUsGYi49UGH5QSYzfAYdbOxVFO5YWOiKrzXV_GIJNRvL2G0N3wQBzMew-f"
# "pB0fopKO6BbzzdbKbY2hccxx3p27a_6b7hqED0PoMO34fUKH8z6p5yqvA; "
# "cookiesu=13505050505; u=13505050505; "
# "device_id=11c12c1015a4baf7b13505050505b7589c02; "
# "Hm_lvt_1db88642e13505050505b5a1eded6e3=13505050505; "
# "Hm_lpvt_1db88642e13505050505b5a1eded6e3=13505050505",
"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 requests
url = "https://pic.netbian.com/uploads/allimg/231213/13505050505f51.jpg"
res = requests.get(url)
# print(res.content)
# 文件操作
with open("美女.jpg", "wb") as f:
f.write(res.content)
视频
# -*- coding utf-8 -*-
import requests
url = "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=38DF885CE72372B324B13505050505A230F61C9E12FC69B72EC8A2CF6F6809E13505050505C635758EB7E7B49738D9DB608A7C855DB4E7A0B9A082A399875D13505050505E1690D97ABE2A3C002ADD06D4AD5EAD4F028688C35E6D73D29DBF2D596F63C6722B78DA1EA3707EB5A7DD2F60781A45B31B13505050505F649E523C08D797BA7907BFDB2562BF44E1483A3981FAAC70BEF8BD92611EF365A183621BDE70F55B13505050505DB78CD7F5"
res = requests.get(url)
# 解析数据
with open("相声.mp4", "wb") as f:
f.write(res.content)
4.2 批量爬取数据
"""1.先爬取整个页面
2.然后做数据解析找到想要的"""
import re
import os
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',
}
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, CBC
ECB:是一种基础的加密方式,密文被分割成分组长度相等的块(不足补齐),然后单独一个个加密,一个个输出组成密文。
CBC:是一种循环模式,前一个分组的密文和当前分组的明文异或或操作后再加密,这样做的目的是增强破解难度。
"""
CBC加密案例(选择aes-128):先加密,再编码
from Crypto.Cipher import AES # Crypto是一个算法库,Cipher有相应的算法,我们用AES
from Crypto.Util.Padding import pad # 里面有个工具叫填充叫pad
import base64 # 64编码
key = '13505050505abcdef'.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
from Crypto.Cipher import AES
import base64
from Crypto.Util.Padding import unpad
key = '13505050505abcdef'.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 json
import requests
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import base64
cookies = {
'PHPSESSID': '6rhg42ce8egfeulonevjnfj4sv',
'Hm_lvt_6cd598ca665714ffcd8aca3aafc5e0dc': '13505050505',
'SECKEY_ABVK': 'aJ99/mmPcgDcnVNO8MQjq74LRk9XDbNZo7uGOCGoln0%3D',
'Hm_lpvt_6cd598ca665714ffcd8aca3aafc5e0dc': '13505050505',
'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=13505050505; SECKEY_ABVK=aJ99/mmPcgDcnVNO8MQjq74LRk9XDbNZo7uGOCGoln0%3D; Hm_lpvt_6cd598ca665714ffcd8aca3aafc5e0dc=13505050505; 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": 13505050505,
# "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": 13505050505,
"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 execjs
with 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 execjs
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=135050505052&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_b
headers = {
'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%7C13505050505%7C13505050505cb69c8b13505050505e49e85f1a8b629e3fe13505050505d349e0165c31a4c5d; 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=80c91cb353504f9fa1cbfd13505050505; SEARCH_RESULT_LIST_TYPE=%22single%22; FORCE_LOGIN=%7B%22videoConsumedRemainSeconds%22%3A180%2C%22isForcePopClose%22%3A1%7D; xgplayer_device_id=13505050505; xgplayer_user_id=13505050505; 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=cc21dc4dd81ccb045d9f13505050505fe819301; publish_badge_show_info=%221%2C0%2C0%2C13505050505%22; sso_uid_tt=5ce4bf94843b5ceab602e1b13505050505f2; sso_uid_tt_ss=5ce4bf94843b5ceab602e1b13505050505f2; toutiao_sso_user=7c738c8c4feec8e0cd87a55f80fef383; toutiao_sso_user_ss=7c738c8c4feec8e0cd87a55f80fef383; uid_tt=2ebe791b464abe496f63029d978005c6; uid_tt_ss=2ebe791b464abe496f63029d978005c6; sid_tt=fde6df13505050505ac63ddb768c5ae33686; sessionid=fde6df13505050505ac63ddb768c5ae33686; sessionid_ss=fde6df13505050505ac63ddb768c5ae33686; LOGIN_STATUS=1; _bd_ticket_crypt_cookie=3db9c81dd0322f1ee81e8cdfcd276366; download_guide=%223%2F13505050505%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=fde6df13505050505ac63ddb768c5ae33686%7C13505050505%7C13505050505%7CThu%2C+04-Apr-13505050505%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=17273b27de04f135050505054; strategyABtestKey=%13505050505.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%2F13505050505%2F0%2F0%2F13505050505%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=135050505052&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_b
headers = {
'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%7C13505050505%7C13505050505cb69c8b13505050505e49e85f1a8b629e3fe13505050505d349e0165c31a4c5d; 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=80c91cb353504f9fa1cbfd13505050505; SEARCH_RESULT_LIST_TYPE=%22single%22; FORCE_LOGIN=%7B%22videoConsumedRemainSeconds%22%3A180%2C%22isForcePopClose%22%3A1%7D; xgplayer_device_id=13505050505; xgplayer_user_id=13505050505; 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=cc21dc4dd81ccb045d9f13505050505fe819301; publish_badge_show_info=%221%2C0%2C0%2C13505050505%22; sso_uid_tt=5ce4bf94843b5ceab602e1b13505050505f2; sso_uid_tt_ss=5ce4bf94843b5ceab602e1b13505050505f2; toutiao_sso_user=7c738c8c4feec8e0cd87a55f80fef383; toutiao_sso_user_ss=7c738c8c4feec8e0cd87a55f80fef383; uid_tt=2ebe791b464abe496f63029d978005c6; uid_tt_ss=2ebe791b464abe496f63029d978005c6; sid_tt=fde6df13505050505ac63ddb768c5ae33686; sessionid=fde6df13505050505ac63ddb768c5ae33686; sessionid_ss=fde6df13505050505ac63ddb768c5ae33686; LOGIN_STATUS=1; _bd_ticket_crypt_cookie=3db9c81dd0322f1ee81e8cdfcd276366; download_guide=%223%2F13505050505%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=fde6df13505050505ac63ddb768c5ae33686%7C13505050505%7C13505050505%7CThu%2C+04-Apr-13505050505%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=17273b27de04f135050505054; strategyABtestKey=%13505050505.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%2F13505050505%2F0%2F0%2F13505050505%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 += 1
for t in t_list:
t.join() # 遍历t_list里面所有的线程对象,等待所有的都执行完join才通过
四、图片验证码、打码平台、JS逆向将加密拿到本地
1.图片验证码
import requests
res = 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 requests
cookies = {
'Hm_lvt_387b8f4fdb89d4ea233922bdc13505050505': '13505050505',
'PHPSESSID': 'a3c14f78e68b82a9c91d890fcc45b15d313e35f4',
'time_diff': '1',
'XDEBUG_SESSION': 'XDEBUG_ECLIPSE',
'adbanner_city': '%E5%85%B0%E5%B7%9E%E5%B8%82',
'Hm_lpvt_387b8f4fdb89d4ea233922bdc13505050505': '13505050505',
'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_387b8f4fdb89d4ea233922bdc13505050505=13505050505; PHPSESSID=a3c14f78e68b82a9c91d890fcc45b15d313e35f4; time_diff=1; XDEBUG_SESSION=XDEBUG_ECLIPSE; adbanner_city=%E5%85%B0%E5%B7%9E%E5%B8%82; Hm_lpvt_387b8f4fdb89d4ea233922bdc13505050505=13505050505; login_fail_need_graphics=0',
'Device-Os': 'web',
'Device-Ver': '',
'Imei': '',
'NonceStr': '13505050505bnhju',
'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': '13505050505',
'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': 'ed47d61b13505050505b96b8f6c92a54810',
'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
}("1350505050513505050505"))
}
, 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": 13505050505,
"NonceStr": "13505050505goio1",
"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 json
def 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": "13505050505",
"password": "13505050505",
"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等于值B
res = 1 === 1 ? 99 : 88 # res=99
- 特殊的逻辑运算
v1 = 1===1 || 2===2 # Ture
v2 = 9 || 13505050505# 9
v3 = 0 || 13505050505# 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 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 os
os.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: "13505050505",
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=13505050505&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=13505050505&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=13505050505&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=13505050505&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 requests
res = requests.get(
url="https://www.toutiao.com/api/pc/list/feed?offset=0&channel_id=13505050505&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.document
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: "13505050505",
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 ? -13505050505f : 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 > 13505050505? 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
} else
A > 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]
} else
A > 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
} else
A > -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
}
else
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 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
}
} else
A < 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
} else
A > 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]
} else
A < 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
} else
A < 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
} else
A < 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
} else
A < 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 = "484e4f4a403f13505050505d2d1aea78184c36c3d13505050505ab13505050505b000b13505050505e13505050505e1c211b000b13505050505e18011b000b02041c16004c211b000b13505050505e13505050505b1c1b000b041e13505050505b000b13505050505a13505050505a13505050505c16001e13505050505c131f13505050505e00061a001d13505050505c1350505050513505050505d1b000b081e13505050505f13505050505a25000e211b000b13505050505f13505050505b25005b131e000c02000d02000e1a02221e000f24131e00100a13505050505c1c135050505051e13505050505a13505050505e00131e13505050505a1c211b000b0a13505050505b1c1b000b0a1e13505050505f13505050505b000b0b1a00221e13505050505a13505050505f0a1350505050513505050505e13505050505c13505050505e1350505050513505050505e1350505050513505050505a13505050505f0b02001b1350505050502001c1f13505050505f13505050505f0e180e13505050505011b000b0c221e001d241b000b0c221e001e240a13505050505e001f2a0a13505050505f06180e2e1f0e16ffcb13505050505f0c13505050505df13505050505f13505050505e13505050505c13221e13505050505a1350505050517001c1c1b000b051e00221e13505050505e13505050505a1350505050517000d1c211b000b13505050505e13505050505c1b000b08221e13505050505a13505050505e13505050505a13505050505a13505050505d1c211b000b0d13505050505e13505050505c1b000b0d221e13505050505a1350505050517000d1c211b000b0e13505050505e13505050505b020b07260a13505050505b000b0f13505050505e13505050505c1b000b0f221e13505050505a1350505050513505050505f0d13505050505a1350505050513505050505a281f13505050505e002b24131e000c02002c13505050505a020a13505050505f13505050505f13505050505e001f3a13505050505f13505050505e002d13505050505a13505050505e3e17001a13505050505e002f13505050505e001f0a13505050505f0816ffd13505050505e13505050505a13505050505e13505050505e002f13505050505e001f18081e001f0a13505050505d1f1216ff95001f0e1350505050506000a271f1350505050500001f06131e13505050505c131e13505050505e13505050505a13505050505f13505050505131e13505050505c131e13505050505e13505050505a13505050505f135050505051b020b0e13505050505b000b081e00340a13505050505f13505050505f0f13505050505c13505050505f13505050505f131e13505050505e13505050505e13505050505a13505050505c131e13505050505e13505050505e13505050505a13505050505c49016d48182a483c2a483c2a4903e82a1f061b000b13505050505d00341b000b13505050505a13505050505b000b0b1b000b0b1a00221e13505050505a13505050505a01221e13505050505a13505050505a281d13505050505f13505050505b25004c13505050505f1e05003f131e13505050505e13505050505e003c13505050505a13505050505c131e13505050505e13505050505e003c13505050505a13505050505c1b000b13505050505d13505050505f13505050505d2500a31b000b101a001f061b000b05221e003e13505050505f131e00061a13505050505c1b030b00201d13505050505d00410a13505050505c1b000b11221e13505050505a13505050505c13505050505c131e13505050505b1c131e00441e13505050505d00401b020b08260a1350505050500221c131e13505050505e1350505050500101c131e13505050505e1350505050513505050505d13505050505f13505050505a25002b13505050505001f1c1b000b051e00221e13505050505e13505050505e004b0a13505050505c3e001f13505050505d13505050505b020b07260a135050505054e1b000b0d13505050505c1b000b0d1e004e1b000b13505050505c02004f13505050505c13505050505091c135050505050f1c13505050505423a13505050505f13505050505b000b0d1e13505050505561b000b13505050505b000b05221e13505050505b000b0d0a13505050505f13505050505e13505050505a13505050505b13505050505c13505050505e13505050505a13505050505b13505050505081c131e13505050505b1c131e00581e13505050505e1c131e00581e00591e005a17002a13505050505f13505050505e131e00581e13505050505e005a240a13505050505b000b063e13505050505b02005c02005d02005e02005f13505050505135050505050a000b1f13505050505680a00031f13505050505fc918c13505050505fc13505050505c8191fca1318ca13505050505ffe13505050505fc918c13505050505b1fc13505050505c8191fca131e006918ca13505050505ffe4131e13505050505fc918c13505050505fc818c8221e006a24131e000c02006b13505050505a020a13505050505f1c131e006918c13505050505c13505050505ffcb12001f13505050505d2500c71b020b08260a13505050505b000b13221e006e13505050505f0a13505050505f13505050505c1b030b00201d006f001d00701b020b09260a13505050505b13505050505c271f1a181a1e00711b000b13505050505e13505050505e1c131e00311e001f48003e13505050505d006f13505050505e13505050505e135050505050a13505050505c131e13505050505e003c13505050505a13505050505c071b020b07260a13505050505e13505050505c131e13505050505c131e13505050505d006f001f13505050505b11b020b07260a13505050505a21b000b08221e13505050505a13505050505f13505050505e007a221e13505050505a13505050505e007b24131e000c02007c02007d1a13505050505a13505050505e13505050505e0a13505050505a13505050505b1c1b000b0d1e13505050505e13505050505a13505050505e007b24131e000c02007c02007d1a13505050505a13505050505e13505050505e0a13505050505a13505050505c1b000b0d1e004e221e13505050505a13505050505f13505050505f13505050505e000c13505050505a021f13505050505c131e13505050505b1c131e00821e13505050505c131e00821e00831f13505050505e13505050505a13505050505e13505050505c13505050505e13505050505a13505050505e13505050505c13505050505e000f13505050505a13505050505001f13505050505b020b1a1e13505050505b1b020b1a1e13505050505a271f1e13505050505b000b08221e13505050505a13505050505f0c180c221e13505050505a13505050505f0d180d221e008a13505050505b0a13505050505f0e180d221e008c24180e02008d190a13505050505f0f180d221e008c24180e02008e190a13505050505f10180f02008f13505050505f111b020b1a18111d13505050505f1b135050505051f061b020b1a1e13505050505f1b020b1a1e00911f061600fb48051f0e0a00001f0f1b000b0d1e004e1f13505050505c0a00001f13505050505f13505050505e3a1700b13505050505f3f0500a13505050505f130a00001f13505050505f13505050505e001f3a13505050505e13505050505a13505050505f13505050505e13505050505e13505050505a13505050505e00940a13505050505c18162d1f1616ffc418131e13505050505f13505050505e135050505051e13505050505f13505050505e13505050505f13505050505e13505050505a13505050505f15180f221e13505050505a13505050505c13505050505d1f1216ff47180f221e13505050505a13505050505f061b020b1a18061d13505050505e009a13505050505a13505050505f1c02009b13505050505b000b0d1e009c221e009d240a13505050505f061b000b0d1e009e221e009d240a13505050505f13505050505f13505050505f13505050505f0a48031f0b48041f0c48051f0d180d1f0e02009f1f0f0200a01f100200a11f110200a21f120200a31f130200a41f140200a51f150200a61f13505050505e13505050505a70a13505050505b13505050505c13505050505e13505050505a80a13505050505b17000a180c1f0e1600f13505050505e13505050505f0a13505050505b17000a18081f0e1600dd13505050505e13505050505a13505050505b17000a18091f0e1600c13505050505e13505050505a13505050505b13505050505c13505050505e13505050505a90a13505050505b13505050505c13505050505e13505050505aa0a13505050505b17000a180a1f0e16007b13505050505e13505050505a13505050505b13505050505c13505050505e13505050505a13505050505b13505050505c13505050505e13505050505a13505050505b13505050505c13505050505e13505050505ab0a13505050505b13505050505c13505050505e13505050505ac0a13505050505b17000a180b1f0e13505050505d1f0e13505050505e13505050505a13505050505b13505050505c180e1350505050513505050505e13505050505a13505050505b13505050505c13505050505e13505050505a13505050505b13505050505c13505050505e13505050505ad0a13505050505b13505050505c180e180a13505050505c180e1350505050500f13505050505e13505050505a13505050505b13505050505c13505050505e13505050505a13505050505b13505050505c13505050505e13505050505a13505050505b13505050505c13505050505e13505050505a13505050505b13505050505c180e180c13505050505c180e180b13505050505b13505050505e13505050505a13505050505a13505050505c13505050505e13505050505a13505050505a13505050505c13505050505e13505050505a13505050505a13505050505c13505050505e13505050505a13505050505a13505050505c13505050505e13505050505a13505050505a13505050505c13505050505e13505050505a13505050505a1f13505050505e180d3e13505050505f13505050505f13505050505f13505050505f1a48051f1b181b1f1c13505050505e13505050505ae0a13505050505b17000a18191f1c13505050505e13505050505af0a13505050505b13505050505c13505050505e13505050505b00a13505050505b17000a18181f1c13505050505e13505050505b10a13505050505b17000a18171f1c13505050505e13505050505b20a13505050505b13505050505c13505050505e13505050505b30a13505050505b17000a181a1f1c13505050505b1f1c1b020b1c260a13505050505e009d240a13505050505f1d1b020b1b260a13505050505e009d240a13505050505f1e181c18173f13505050505c181c18183f13505050505d1c131e13505050505c1b000b0d1e00b4221e13505050505a13505050505e13505050505b50a13505050505b13505050505c18173f13505050505c181c18183f13505050505c181d221e13505050505a13505050505b13505050505c181a3e13505050505a1c181e13505050505f13505050505f1d0200b62500da261f13505050505f271f121b000b081e00b71f13505050505b000b08221e00b13505050505b90a13505050505f13505050505e13505050505b000b08221e13505050505ba0a13505050505f070200bb1b000b13505050505b000b0c221e001e240a13505050505a480a0a13505050505bb281b000b0b1a00221e13505050505a13505050505f13505050505bc13505050505f13505050505d00bd135050505051b030b13505050505c13505050505f0c05001c1b030b06221e00be241b030b070a13505050505c131b030b13505050505d13505050505e00bf13505050505a13505050505c001f1e0200c02500be18001e001f1f13505050505f1350505050513505050505f13505050505f13505050505a13505050505c1350505050513505050505f13505050505f13505050505a17004a13505050505b000b16221e00c13505050505ff2f1350505050500ff2f1350505050500ff2f1350505050500ff2f0a13505050505d18092d1f0916ffb13505050505e13505050505a13505050505f0a13505050505a221e002f13505050505a13505050505a001f200200c225007f18001e001f1f13505050505f13505050505f13505050505d1f13505050505a1b000b13505050505a011f13505050505d16000d1b000b13505050505a011f13505050505f13505050505a17002c1350505050513505050505e00c13505050505a13505050505f13505050505d18092d1f0916ffd13505050505f210200c425000a13505050505c52f001f220200c135050505051350505050513505050505135050505058032f13505050505001f230200c13505050505e001f48043a17000a13505050505d001f13505050505f240200c82500d618001e001f1f13505050505f13505050505f13505050505f0a1b000b0c221e001d13505050505b280a13505050505f0d180d13505050505b020b22180a1b020b1f28041f0a180a13505050505f1f0b48001f0c180c18073a17003d13505050505c13505050505f13505050505c1b020b13505050505c191b020b13505050505a13505050505c180b18010a13505050505d271f09180c2d1f0c16ffc13505050505f13505050505b020b13505050505b020b13505050505a13505050505b18010a13505050505d271f09180d2e1f0d16ff13505050505f250200c92500d818001e001f1f13505050505f13505050505f081b000b0c221e001d13505050505b280a13505050505f0d1b020b22180d1b020b1f2a041f0a180a13505050505a13505050505f1f0b18071f0c180c13505050505d13505050505c13505050505f13505050505c1b020b13505050505c191b020b13505050505a13505050505c180b18010a13505050505d271f08180c2e1f0c16ffc13505050505f13505050505b020b13505050505b020b13505050505a13505050505b18010a13505050505d271f081b020b22180a1b020b1f29041f0a16ff6b13505050505f260200ca2501ac131e000c0200cb13505050505a02221e000f13505050505a135050505050a00001f13505050505e001f1f13505050505f13505050505f13505050505a13505050505e00c13505050505a13505050505f0a180a13505050505a13505050505221e002d13505050505a13505050505d16012a180a13505050505a17002a13505050505b000b16221e00c13505050505c0180a13505050505a483f2f300a13505050505d1600fa180a4a0000d8003a13505050505c1c180a4a0000dfff13505050505b000b16221e00c13505050505e0180a480c13505050505a13505050505f2f13505050505a483f2f300a13505050505d1600ae13505050505a13505050505e00c13505050505a13505050505f0b180a4a0000dc003a13505050505c1c4a0000dc00180b3c13505050505c1c180b4a0000dfff3c13505050505a4903ff2f480a33180b4903ff2f304a13505050505f0c13505050505b000b16221e00c13505050505f0180c13505050505f2f13505050505c480c34483f2f13505050505c13505050505f2f13505050505c483f2f300a13505050505d18082d1f13505050505d1b000b180200cc1a13505050505d1f13505050505d1f0916fe9a13505050505e13505050505a13505050505f270200cd25024e1b000b13505050505a011f13505050505f13505050505f13505050505e001f1f13505050505a13505050505c13505050505a13505050505e00c13505050505d1f080a13505050505f0a180a13505050505f0c180c13505050505c13505050505c13505050505c13505050505c13505050505c13505050505c13505050505c13505050505c480c13505050505b180c480d13505050505c480e13505050505c480f401700a13505050505d13505050505a0d13505050505a13505050505a481f2f13505050505e00c13505050505d1f080a13505050505f2f300d16000d1b000b180200ce1a1350505050513505050505a13505050505a480f2f480c13505050505e00c13505050505d1f080a13505050505f2f13505050505e00c13505050505d1f080a13505050505f2f300d16000d1b000b180200ce1a13505050505e13505050505a1700b4180a48072f13505050505e00c13505050505d1f080a13505050505f2f480c13505050505e00c13505050505d1f080a13505050505f2f13505050505e00c13505050505d1f080a13505050505f2f304a13505050505f0b13505050505b3c13505050505c1c180b4a000fffff3c17002f13505050505d1f07180b480a344903ff2f4a0000d800300d13505050505b4903ff2f4a0000dc00300d16001b1b000b180200cf180b221e13505050505a13505050505a13505050505d1b000b180200ce1a13505050505b1b000b180200d0180a221e13505050505a13505050505a13505050505d1f0716fdef13505050505a17000a13505050505d001f1b000b161e00c11b000b13505050505f280200d12502aa0a00001f061b000b174a13505050505a011f13505050505f13505050505f13505050505e001f1f0a13505050505a13505050505c13505050505a3a13505050505e00c13505050505d1f090a13505050505f0b180b13505050505f0e180e13505050505e13505050505e13505050505e13505050505e13505050505e13505050505e13505050505e13505050505e480c13505050505b180e480d13505050505e480e13505050505e480f401700a13505050505d13505050505b0d13505050505a3a13505050505b481f2f13505050505e00c13505050505d1f090a13505050505f2f300d16000d1b000b180200ce1a1350505050528180a3a13505050505b480f2f480c13505050505e00c13505050505d1f090a13505050505f2f13505050505e00c13505050505d1f090a13505050505f2f300d16000d1b000b180200ce1a13505050505e13505050505a3a1700b4180b48072f13505050505e00c13505050505d1f090a13505050505f2f480c13505050505e00c13505050505d1f090a13505050505f2f13505050505e00c13505050505d1f090a13505050505f2f304a13505050505f0c13505050505c3c13505050505c1c180c4a000fffff3c17002f13505050505d1f08180c480a344903ff2f4a0000d800300d13505050505c4903ff2f4a0000dc00300d16001b1b000b180200cf180c221e13505050505a13505050505a13505050505d1b000b180200ce1a13505050505b1b000b180200d0180b221e13505050505a13505050505a13505050505fff13505050505b13505050505f0d13505050505d1d001f13505050505e001f1b000b161e00c11b000b13505050505d13505050505d291f13505050505f13505050505d1f0816fdb1350505050513505050505d001f13505050505e001f1b000b161e00c11b000b13505050505d13505050505e13505050505a13505050505f290200d22500b418011b000b063e13505050505c13505050505e13505050505c13505050505a17000a18001e001f1f13505050505e13505050505e000c0200cb13505050505a02221e000f13505050505a13505050505c1c131e000c0200d13505050505a02221e000f13505050505a1350505050518001e001f3e135050505051e00d13505050505a13505050505a0000ffff3a13505050505b020b13505050505a13505050505b020b13505050505a13505050505f2a0200d525006b18001b000b063e13505050505c13505050505e13505050505c1c18001e001f48003e13505050505b020b13505050505f001b020b13505050505f011b020b20261b020b25261b020b13505050505a13505050505b020b241b020b13505050505a13505050505a13505050505a13505050505f2b0200d13505050505b000b063e13505050505c13505050505e13505050505c1c18001e001f48003e13505050505b020b13505050505f011b020b2a1b020b20261b020b26261b020b13505050505a13505050505b020b241b020b13505050505a13505050505a13505050505a13505050505f2c0200d725019d0200d81f13505050505a1f135050505051f13505050505f13505050505f13505050505f0a18001e001f180a13505050505b1700b13505050505e00c324180a222d1f0a0a13505050505ff2f13505050505e00c324180a222d1f0a0a13505050505ff2f13505050505e00c324180a222d1f0a0a13505050505ff2f301f13505050505e002d13505050505a00fc00002f13505050505a13505050505f13505050505e002d13505050505a0003f0002f480c340a13505050505f13505050505e002d13505050505fc02f13505050505a13505050505f13505050505e002d13505050505f2f0a13505050505f0816ff13505050505e001f180a13505050505a13505050505e00c324180a222d1f0a0a13505050505ff2f13505050505e001f180a13505050505a13505050505e00c324180a0a13505050505ff2f135050505051f13505050505e002d13505050505a00fc00002f13505050505a13505050505f13505050505e002d13505050505a0003f0002f480c340a13505050505f13505050505e001f180a13505050505a13505050505e002d13505050505fc02f13505050505a135050505051f13505050505f13505050505f2d0200d13505050505da221e13505050505a13505050505f2e0200db13505050505f13505050505f13505050505e001f13505050505a1700f61b020b2e13505050505e002d13505050505a13505050505f081b020b2e13505050505e002d13505050505a13505050505f091b020b2e13505050505e002d13505050505a13505050505f0a1b020b2e13505050505e002d13505050505a13505050505f0b18061b000b16221e00c1350505050513505050505a13505050505f13505050505e002d13505050505a13505050505a3f13505050505b000b16221e00c13505050505f02f180a13505050505f2f300a13505050505f13505050505e002d13505050505a13505050505a3f13505050505b000b16221e00c124180a13505050505c02f180b300a13505050505f13505050505f0716ff13505050505f2f0200dc25004a13505050505f2f1f001b000b16221e00c13505050505a3a1350505050513505050505a1350505050500483e3a17000b1350505050513505050505a13505050505f310200dd13505050505b020b311f135050505051350505050513505050505c1350505050513505050505001f320200de13505050505b020b121e00df0200e0281f061b020b1e1350505050518001e001f48083a1350505050506271f13505050505f1b020b2c261b020b2f13505050505e009a13505050505a13505050505e009a13505050505a13505050505a13505050505f0c180c0200e13e13505050505b020b13505050505a13505050505c13505050505c0200e23e13505050505b020b13505050505a13505050505c07000a13505050505c001f370200e325004e1b020b13505050505d00e13505050505f1e13505050505e13505050505e13505050505e13505050505e518010a13505050505c131e13505050505e13505050505e13505050505e518010a13505050505c07001f380200e62500a13505050505f13505050505f13505050505f131e13505050505e13505050505e13505050505e50a13505050505f135050505051c131e13505050505e13505050505e13505050505e50a13505050505f1350505050513505050505f13505050505b020b2c261b020b2f13505050505e009a13505050505a13505050505e009a13505050505a13505050505a13505050505f13505050505e13e13505050505e13505050505e23e13505050505f390200e13505050505f061b020b121e00e4203e13505050505f13505050505b020b121e00e4123e13505050505f13505050505e1b020b39260a13505050505f06131e00061a13505050505d00e822121d00e922121d13505050505d00ea22121d00eb22121d13505050505d00ec22121d00ed22121d13505050505d006f22121d00ee220200ef13505050505f13505050505d000f1f13505050505b020b0d260a13505050505d00eb18071e00eb13505050505b020b13505050505c1b020b13505050505c18071b020b14260a13505050505d00ec18071b020b15260a13505050505d00ed18071b020b16260a13505050505d13505050505b020b18260a13505050505d00ee18071b020b19260a13505050505d13505050505b020b1d260a13505050505d00e13505050505f3a0200f025005c1b000b05221e00f13505050505a13505050505f13505050505f13505050505e001f13505050505f13505050505b135050505051350505050513505050505f13505050505e001f13505050505301f13505050505e1f0816ffcc13505050505f3b0200f13505050505f13505050505e001f3a13505050505a13505050505f2a13505050505e00c13505050505a13505050505f13505050505d1f0616ffd13505050505f3c0200f13505050505f13505050505e001f3a13505050505e00c13505050505a13505050505a13505050505f2a13505050505f13505050505d1f0616ffd13505050505f3d0200f42500a348001f13505050505e001f3a13505050505e00c13505050505a13505050505f13505050505a0000d8003b13505050505c1c18074a0000dbff3c13505050505c1c13505050505e001f3a13505050505e00c13505050505a13505050505f13505050505a0000fc002f4a0000dc003d13505050505ff2f480a13505050505ff2f284a13505050505f13505050505f13505050505a13505050505f2a13505050505f13505050505d1f0616ff6a13505050505f3e0200f135050505050071c13505050505f13505050505e007b24131e000c0200f13505050505a13505050505a13505050505f13505050505e13505050505e00a1350505050513505050505e00d13505050505e13505050505e00a13505050505a13505050505f1350505050513505050505f1f13505050505f3f0200f72500b13505050505c13505050505f13505050505e006a24131e000c0200f13505050505a020a13505050505f1350505050513505050505e00d13505050505a135050505051f135050505051e002b240200f90a13505050505f08131e00061a001f13505050505f0a180a18081e001f3a13505050505a19221e002b13505050505a0a135050505050a19221e002b13505050505a0a13505050505d180a2d1f0a16ffc13505050505f400200fa1350505050500171c1b000b19221e00fb13505050505a13505050505fc3e17000a131e00061a00001b000b05221e00f13505050505a13505050505e00fd240a13505050505f06131e00061a001f13505050505f13505050505e001f3a13505050505a1350505050513505050505280d13505050505135050505050d18102d1f1016ffc13505050505f410200fe13505050505b000b17221e00ff13505050505a135050505051e13505050505b020b420a13505050505b000b13505050505b000b05221e00f13505050505a13505050505e00fd240a13505050505f0c180c221e1350505050513505050505b020b421b030b13505050505d13505050505e00061a000a13505050505f13505050505d13505050505c1b000b19221e00fb13505050505a13505050505fc3e13505050505b000b05221e00f13505050505a13505050505e00fd240a13505050505f13505050505f13505050505f13505050505e001f3a13505050505190a13505050505a13505050505280200f928281f13505050505d1f1016ffd13505050505f13505050505cb1b000b08221e13505050505a13505050505f13505050505d13505050505d13505050505e13505050505a13505050505f13505050505d13505050505e13505050505a13505050505c0a13505050505c13505050505d010b13505050505d010c13505050505d1d010e13505050505e010f1350505050548020a13505050505c13505050505e13505050505a13505050505c13505050505e007a240a13505050505f13505050505f13505050505a17002c18004a13505050505f2a13505050505e00c13505050505e001f2c0a13505050505f13505050505d1f0916ffd13505050505f1350505050513505050505c271f0c13505050505d1b020b13505050505f1350505050501131d13505050505d13505050505f13505050505a13505050505f0c13505050505b131e13505050505f13505050505a13505050505f0c13505050505b131e13505050505f13505050505a13505050505f0c13505050505b131e13505050505f13505050505b020b0b1b020b49260a13505050505b020b0b1b020b48260a13505050505b020b0b1b020b47260a13505050505f4a13505050505e011a1f13505050505e13505050505bb13505050505e13505050505bb13505050505e011b28001f4b02011c13505050505e011a1f13505050505e011d0200bb13505050505e011e28001f4c02011f13505050505b000b1a135050505051b000b0d13505050505b000b0d221e13505050505a13505050505e135050505051b040b13505050505bb1350505050500bb1350505050500bb135050505051c000a13505050505c16000a13505050505c001a01001f4d13505050505d13505050505f13505050505f07211b000b0d13505050505000f1b000b0d13505050505f13505050505c211b000b0d13505050505000c1b000b0d13505050505f13505050505f50121f13505050505b000b08221e13505050505a13505050505c201f13505050505a13421f13505050505bb13505050505bb13505050505f4e02012b13505050505b000b0b1a001f13505050505e012c13505050505a13505050505c13505050505e012d13505050505a13505050505c13505050505e012e240a13505050505f13505050505e012d24480b0a13505050505c13505050505e012e240a13505050505f081b000b0c221e012f13505050505a13505050505f4f13505050505dd135050505050a00031f06131e00061a001f07131e00061a001f081b000b081e00b13505050505a13505050505f1b181b13505050505f1a1b000b08221e13505050505a13505050505f1c181c13505050505d13505050505c1e13505050505d13505050505c1e13505050505a1d013a1b000b081e00b7221e00bf24181c0a13505050505c13505050505a181c1e013b0d13505050505a181c1e013c0d1b000b081e00b7221e00be24181c0a13505050505c16ff8e02013d02013e02013f13505050505135050505051350505050513505050505a02014b02014c02014d02014e02014f13505050505135050505051350505050513505050505a001d1f13505050505f0b271f0a271f0c48001f1a181a18091e001f3a1700b13505050505f1c181c13505050505f1f1b1b000b08221e13505050505a13505050505f1d181d13505050505d13505050505d1e13505050505d13505050505d1e13505050505a13505050505a28181b281d013a1b000b081e00b7221e00bf24181d0a13505050505c181d1e013b13505050505b13505050505f1c181d1e013c13505050505b19401f1e1b000b081e00b7221e00be24181d0a13505050505c181e13505050505a481e3a17000d13505050505a33180a301f0a13505050505ff60181a2d1f1a16ff48180a221e13505050505a13505050505f13505050505b13505050505c271f0c180c1e13505050505e1b000b1b02015c1a011c07001f13505050505d13505050505b000b1c221e13505050505a13505050505e001f001f13505050505e2501e81b020b07260a13505050505d1c1b020b09260a13505050505c1b000b0d1e009c221e009d240a13505050505e13505050505f0a1350505050513505050505e13505050505c131e13505050505c131e01621f061b000b1a13505050505d13505050505d271f6a13505050505c13505050505b030b13505050505a1b030b06131e00061a13505050505e00061a13505050505d01640a00011d01651a011f13505050505f07131e000c13505050505a021f08131e000c13505050505d1a021f13505050505e13505050505a13505050505c1b000b1d13505050505d1b040b13505050505c004901f40a13505050505c13505050505e13505050505a13505050505f0a180a1b000b1a13505050505a221e135050505051b040b06221e016a13505050505a13505050505a13505050505e13505050505000a13505050505c13505050505e13505050505c1b040b06221e016a13505050505b040b071b040b070a13505050505c13505050505a13505050505c1350505050513505050505c18001e016b13505050505c1c18001e016b1e016b13505050505b040b08221e016c13505050505e016b1e016b0a13505050505f1350505050513505050505e006a241b040b090a13505050505f13505050505e1b040b13505050505c001d016d16000a13505050505c07001a01001f13505050505e25005d02016f221e007b24131e000c13505050505d1a13505050505e1b000b0c221e001e240a13505050505a13505050505f13505050505d13505050505b13505050505f13505050505f13505050505e13505050505a13505050505a13505050505f135050505051e001f48223e13505050505b020b3c13505050505e002f13505050505a13505050505a13505050505f13505050505e13505050505a13505050505e002f13505050505a13505050505e002f13505050505a13505050505e13505050505f13505050505d1b020b0f13505050505f13505050505b1c1b020b13505050505001b020b54260a13505050505f13505050505b020b3c13505050505a13505050505e002f13505050505a13505050505f061b020b13505050505a13505050505c13505050505f1350505050513505050505b020b0c13505050505f13505050505b020b2d261b020b2b13505050505a13505050505a13505050505f13505050505d13505050505a48001f0b48001f0c180c18001e001f3a13505050505c191e13505050505c13505050505b222d1f0b191d13505050505c2d1f0c16ffd13505050505f13505050505e017a13505050505b1b03220b061b020b0b18001e13505050505b28281d017c000a13505050505c18061b020b0a260a13505050505f061b020b54260a13505050505f071b000b0c221e001d13505050505e00c13505050505a13505050505b0a13505050505e00c13505050505a13505050505c281f13505050505e002f13505050505a13505050505f091b020b2d1b020b2b13505050505a13505050505f061b020b12221e017d02017e1b000b1e13505050505f928281d017d271f0a1b020b1e26180a13505050505d13505050505f13505050505d13505050505a1c135050505051b020b121b020b13505050505d01811b020b13505050505d01821b020b1350505050580190a13505050505c000a13505050505c001f13505050505a1b000b0d13505050505c13505050505c1b000b13505050505e00061a13505050505d13505050505d13505050505e01851d13505050505e00061a13505050505d13505050505d13505050505b020b0a1d13505050505e00061a13505050505a1d13505050505d13505050505b020b4a1d13505050505e00061a13505050505d13505050505d13505050505b020b451d13505050505e00061a13505050505b1d13505050505d13505050505b020b0a1d13505050505e00061a13505050505e1d13505050505d13505050505e00061a13505050505c1d13505050505d13505050505e00061a13505050505d1d13505050505d13505050505e00061a13505050505e1d13505050505d13505050505e00061a13505050505d13505050505d13505050505e00061a13505050505f1d13505050505d13505050505b020b4b1d13505050505e00061a13505050505d13505050505d13505050505b020b4c1d13505050505e00061a13505050505d13505050505d13505050505e00061a13505050505d13505050505d13505050505e00061a13505050505d13505050505d13505050505e00061a13505050505d13505050505d13505050505e00061a13505050505d13505050505d13505050505b020b4d1d13505050505d13505050505e00061a13505050505d13505050505d13505050505b020b4e1d13505050505e00061a13505050505d13505050505d13505050505b020b4f1d13505050505e00061a13505050505d13505050505d13505050505b020b0a1d13505050505e00061a13505050505d13505050505d13505050505b020b1b1d13505050505e00061a13505050505a1d13505050505d13505050505b020b501d13505050505e00061a13505050505b1d13505050505d13505050505b020b1c1d13505050505e00061a13505050505c1d13505050505d13505050505b020b0a1d13505050505e00061a13505050505c1d13505050505d13505050505e00061a13505050505d1d13505050505d13505050505b020b0f1d13505050505d019e131e00061a13505050505f1d13505050505d13505050505b020b511d13505050505e00061a13505050505a01d13505050505d13505050505b020b521d13505050505e00061a13505050505a11d13505050505d13505050505b020b531d13505050505d13505050505e00061a13505050505d13505050505d13505050505e00061a13505050505a21d13505050505d13505050505b020b061e01a31d13505050505e00061a13505050505a41d13505050505d13505050505b020b561d13505050505e00061a13505050505a51d13505050505d13505050505b020b0a1d13505050505e00061a13505050505a61d13505050505d01870a00221f060a00001f13505050505f13505050505db1f13505050505e01871f13505050505e135050505051350505050513505050505a13505050505b020b0b1b000b0d13505050505e13505050505d13505050505c1350505050510191e13505050505d13505050505191b000b13505050505e13505050505d13505050505f13505050505e13505050505b000b1a13505050505e13505050505e13505050505e13505050505e019e0a13505050505a13505050505c1350505050513505050505e13505050505e135050505051e019e0a13505050505d017916ff241b000b1a13505050505b000b1a221e01a13505050505a13505050505e135050505051b020b58261b030b13505050505a13505050505c000a13505050505c16000b1b020b13505050505c001f590201a13505050505b000b13505050505b1c1b000b081e01a13505050505b020b5b08031f0d180d13505050505f1f0c1b000b08221e01a924180c1b020b5b180c190a13505050505c16ffe0001f5d0201aa13505050505e001f4900c13505050505e01ab13505050505a13505050505c18001e001f13505050505e13505050505e001f13505050505f0c18011e01ac180c1e01ac13505050505c13505050505a1c0201ad13505050505f1c18011e13505050505c1e01713d13505050505f1c18011e01ad180c1e01ad3d13505050505e13505050505a13505050505c001f610201ae13505050505f13505050505e01af13505050505c18001e01b13505050505c18001e01b13505050505c18001e01b13505050505f061b020b61261b020b60131e00061a13505050505d13505050505b000b0b221e01b3240a13505050505d01ac0a13505050505c001f620201b425006d18001f13505050505e00941f13505050505e01b13505050505a1c13505050505b63e13505050505e01b13505050505f061b02201d01b8131e00061a13505050505e01b91d13505050505e01ba1d01ad221b000b0b221e01b3240a13505050505d01ac1f081b020b61261b020b5e18080a13505050505c001f630201bb25006d18001f13505050505e00941f13505050505e01b13505050505a1c13505050505bc3e13505050505e01b13505050505f061b02201d01b8131e00061a13505050505e01b91d13505050505e01ba1d01ad221b000b0b221e01b3240a13505050505d01ac1f081b020b61261b020b5f18080a13505050505c001f640201bd13505050505e13505050505b020b650a13505050505e001f2b001f670201be13505050505e001f48013c13505050505b020b13505050505f13505050505e13505050505b18001b030b13505050505a13505050505f071b000b0c221e01bf13505050505e13505050505b020b660a13505050505e13505050505b020b650a13505050505e001f13505050505b0a13505050505f680201c02500d548001f13505050505f13505050505e001f13505050505ba0a00001f13505050505f13505050505e001f13505050505a1350505050528191f0a13505050505f0b180a1e01ac180b1e01ac291f0c180c1350505050508221e13505050505c2b0a13505050505c13505050505e13505050505b000b0c221e01bf241b020b66180a1e13505050505b1e13505050505b020b66180a1e01ad180b1e01ad13505050505a13505050505c2b0a13505050505c18092d1f0916ff741b020b13505050505f061b020b13505050505f13505050505d13505050505c11f13505050505a13505050505f690201c13505050505f13505050505f13505050505b1b000b13505050505b1c1b000b081e13505050505b000b08221e13505050505a13505050505c201f06071b020b69261b020b5e48010a13505050505f071b020b69261b020b13505050505a13505050505f13505050505f13505050505c1b020b5c17000a13505050505f091b020b5e1e001f48003e17000d13505050505f1350505050513505050505a13505050505f091b020b5f1e001f48003e17000a13505050505f091b020b601e001f48003e17000d13505050505f135050505051401c13505050505a13505050505f13505050505e13505050505a13505050505f0a180a1e001f48013e17000e0201c4180a281f0a13505050505a1e001f48023e17000b02001a180a281f0a180a001f6a0201c525002d13505050505f13505050505f0e13505050505b020b0e260201c61b000b081e00340a13505050505f13505050505f6b0201c13505050505b000b19221e00fb24131e00061a13505050505d000e221b000b1f1b000b19221e00fb13505050505e00b70a13505050505d01c13505050505d01860a13505050505f061b020b2d13505050505a13505050505f13505050505f6c0201c135050505050023e13505050505c1c1350505050517000a1c18001e01ca13505050505d1b020b460201cb1a13505050505f13505050505f074a0000fff11f081b000b0b1a00221e13505050505a13505050505e82b13505050505f091b020b061e01cc13505050505e1c1b020b3d261b020b3d135050505050a13505050505b000b0e1e13505050505e002f241b000b0e1e01cd1e001f13505050505a13505050505a13505050505c1f13505050505a13505050505e13505050505a13505050505f0a180a1f0b180a1e001f13505050505b180a221e002f24180a1e001f13505050505a13505050505f0b16003c180a1e001f48203a13505050505f13505050505f13505050505a1e001f293a13505050505a281f13505050505d1f7116ffe13505050505b281f0b0201ce1f0c0201cf1f0d0201d01f0e180e180d28180c28180b281f061b000b13505050505a13505050505f061b020b3d135050505050a13505050505f0f1b020b3a260a13505050505f13505050505e13505050505d13e13505050505d13505050505f13505050505a18011f13505050505e1b020b5a1e01d2221e13505050505d318000a13505050505c18001e00b13505050505a1c1b000b19221e00fb13505050505e00b70a13505050505fc13505050505f48001fc318001e01d13505050505b020b3e13505050505b000b19221e00fb241b020b13505050505e00b718001e01d40a13505050505a13505050505a13505050505fc13505050505b020b3e13505050505b000b19221e00fb241b020b13505050505e00b7040a13505050505a13505050505fc30201d518c13505050505f9281f111b020b13505050505e01ca041fc218001e01d617001a1b000b05221e01d72418c218001e01d60a13505050505c21fc218111b020b4318c204281f13505050505d8281b020b3f18001e01ca13505050505f9281f13505050505d13505050505da281f111b020b5a1e01d2221e13505050505db18110a13505050505c1b020b3b13505050505f121b020b061e01cc13505050505d1c1b020b45260a13505050505f131b020b061e01cc13505050505e1c1b020b121e13505050505c1b020b571b020b0f13505050505f141b020b13505050505b020b13505050505dc2b13505050505b020b13505050505b020b331b020b3d26180f1b020b061e01cc13505050505b1c1b000b0d1e009c221e13505050505a13505050505a13505050505c13505050505b020b3d26180f13505050505a13505050505c13505050505b020b13505050505b020b061e01dd135050505051b020b13505050505f151b020b13505050505c13505050505a13505050505f151b020b6a260a13505050505c0201de1f160200bb1b020b6d281b020b061e01df281f13505050505f13505050505b020b6e13505050505f171b020b3e13505050505a13505050505e13505050505a13505050505f13505050505e009a13505050505e001f13505050505e001f0a13505050505f13505050505f13505050505f1a1b020b6b260a13505050505f1b181b17001f1b020b6c26181b13505050505a13505050505f1a13505050505e028181a281f13505050505f6f0201e13505050505e00061a001f13505050505f13505050505a1f13505050505f13505050505f0a21180a13505050505e13505050505c180a263e13505050505f0a180a13505050505a1c21180a13505050505e13505050505c1c21180a13505050505e13505050505f0a13505050505a0d16ffa13505050505f700201e225004b0201e30201e402009e0201e13505050505c0201e13505050505e70200b40201e80201e90201ea0201eb0201ec0201ed0201ee0a00111f061b020b70261b000b0d18060a13505050505f710201ef13505050505f13505050505f10201f20201f13505050505f40201f50201f60201f13505050505f80201f90201fa0201fb0a00101f061b020b13505050505a13505050505f720201fc13505050505fd0201fe13505050505ff13505050505a00051f061b020b70261b000b13505050505a13505050505f13505050505b000b08221e13505050505a13505050505f06261f13505050505f13505050505e13505050505a13505050505c13505050505e13505050505a13505050505f135050505051f13505050505f13505050505221e008a13505050505a13505050505c13505050505e008a13505050505a13505050505c13505050505e008a13505050505a13505050505f135050505051e008c13505050505e02070a13505050505f13505050505e13505050505f13505050505001f13505050505b61b020b1a1e13505050505b1b020b1a1e13505050505b020b74260a13505050505f13505050505a131e00061a13505050505e00061a13505050505e020a240a13505050505c0a00001d020b13505050505e020c240a13505050505e020d1d020d13505050505e008c13505050505e020e0a13505050505d020f13505050505e008c13505050505e02100a13505050505d13505050505e008c13505050505e02120a13505050505d13505050505b020b13505050505d13505050505e008c13505050505e02140a13505050505d13505050505e008c13505050505e02160a13505050505d13505050505e008c13505050505e02180a13505050505d13505050505e008c13505050505e021a0a13505050505d021b13505050505e008c13505050505e021c0a13505050505d021d13505050505e008c13505050505e021e0a13505050505d021f13505050505e008c13505050505e02200a13505050505d13505050505e008c13505050505e02220a13505050505d13505050505e008c13505050505e02240a13505050505d13505050505e008c13505050505e02260a13505050505d13505050505e008c13505050505e02280a13505050505d13505050505e008c13505050505e022a0a13505050505d022b13505050505e008c13505050505e022c0a13505050505d00961f071b020b1a18071d13505050505f13505050505d13505050505e00061a00221b020b71260a13505050505d022e221b020b72260a13505050505d022f221b020b73260a13505050505d13505050505b020b76260a13505050505d13505050505b020b1b260a13505050505d13505050505b020b1c260a13505050505d004e1f061b020b1a18061d13505050505f13505050505e00061a001f061b020b1a1e13505050505f1b020b1a1e02311f13505050505e1b020b77260a13505050505f13505050505b000b0b221e01b3240a13505050505d02331b020b0c13505050505f13505050505b020b2d261b020b2b261b000b19221e00fb13505050505a13505050505a13505050505a13505050505f13505050505f13505050505b48001f13505050505b020b121e02351e001f3a13505050505b020b121e13505050505e000f13505050505a13505050505062d1f0616ffd112001f13505050505ac131e02371e00221f13505050505e006e1f13505050505e02381f13505050505e02391f13505050505e023a1f0a18061e023b13505050505201d023b135050505051e023c13505050505e023d221e13505050505e00061a13505050505d023e221b041d023f0a13505050505c131e000c13505050505e1a02221e000f13505050505a13505050505a13505050505e13505050505a13505050505e009d240a13505050505e002b13505050505a13505050505d02421b030b08111b13505050505d1350505050512111b041d02431b030b0a111b13505050505d023a135050505050a00001d023d111e023d221e13505050505e00061a13505050505e1d023e221b041d023f0a13505050505c13505050505d13505050505d02451b030b07111b13505050505d006e1350505050513505050505a02024b0a00071f0b13505050505f11201d023c1b020b79111e13505050505e13505050505e13505050505c0a1350505050517000c1b030b09111b13505050505d024d111e024e1f06111e02461f07111e00701f08111e02471f09111e02481f0a111e02491f0b111e024a1f0c111e024b1f0d111e024f1f0e111e02501f0f131e00061a001f13505050505f2a182a1b030b0b1e001f3a13505050505b030b0b182a19111e02511b030b0b182a19190d182a2d1f2a16ffd8131e00061a00221b020b82261b030b00111e02450a13505050505d01ca1f11111e13505050505d17003c111e13505050505e13505050505c1c111e13505050505e17001a1b020b13505050505e13505050505e024d0a13505050505c16000c1b030b09111b13505050505b020b851b030b13505050505c1b030b00221e13505050505b000b060201d10a13505050505b020b6f13505050505b000b060201d10a13505050505f121b020b13505050505e13505050505a13505050505f13111e023d13505050505c111e023d13505050505e13505050505e3f13505050505e023d1f13505050505fa418a418141e001f3a13505050505a448003e13505050505a4191e023f13505050505d13505050505a13505050505e13505050505a4191e023f101c18a42d1fa416ffc5111e13505050505e111e023a11111e13505050505c13505050505d091b020b121e13505050505e11221e13505050505b020b061e02571b020b78260a13505050505a13505050505c13505050505d024e13505050505d13505050505d13505050505d13505050505a1d13505050505b1d13505050505c1d024a11180d1d024b11180e1d024f11180f1d13505050505f13505050505b030b0b1e001f3a13505050505e02511b030b0b13505050505b030b0b13505050505d18902d1f9016ffd81b030b09111b13505050505d13505050505f7a13505050505f13505050505c13505050505a1c131e00061a001f011b020b7b13505050505b1c18001b000b20411f13505050505f13505050505a1f13505050505e01ca1f13505050505e025b1f13505050505f13505050505e025b13505050505e025b221e025c240a13505050505f13505050505a13505050505a1c13505050505000c1c1b020b13505050505b030b13505050505a13505050505e00061a00221b020b82261b030b13505050505a13505050505d01ca1f13505050505d1701fc1b020b7f13505050505a13505050505e002b13505050505a13505050505e009d240a13505050505f13505050505e13505050505a1c13505050505e1701af13505050505c13505050505e025d240a13505050505e025e240a13505050505e135050505051b020b80261b040b091b040b13505050505a13505050505c1b020b851b030b13505050505e1b030b00221e13505050505b040b091b000b060201d10a13505050505b020b6f261b040b091b000b060201d10a13505050505f061b020b83261b040b13505050505a13505050505f071b020b81261b040b13505050505a13505050505f081b030b13505050505b040b010a13505050505161b000b1a13505050505b050b13505050505a01000a13505050505e21b020b13505050505e00b70a13505050505c1b020b851b030b13505050505c1b030b00221e13505050505b000b060201d10a13505050505b020b6f13505050505b000b060201d10a13505050505fa21b020b13505050505a20a13505050505fa31b020b121e13505050505f13505050505a131e00061a13505050505e00061a00221b020b061e02571b020b78260a13505050505d1d025f1f13505050505e025f13505050505e00061a00221b020b061e02571b020b78260a13505050505d1d025f13505050505e025f1b020b061e02571b020b78260a13505050505d1b030b062618a318010a13505050505b030b13505050505a1350505050502025a3e1700fb1b020b851b030b13505050505c1b030b00221e13505050505b000b060201d10a13505050505b020b6f13505050505b000b060201d10a13505050505f4e1b020b13505050505e0a13505050505f4f13505050505b020b13505050505f1b000b060a13505050505f501b030b13505050505a13505050505b020b121e13505050505f13505050505a131e00061a13505050505e00061a00221b020b061e02571b020b78260a13505050505d1d025f1f13505050505e025f13505050505e00061a00221b020b061e02571b020b78260a13505050505d1d025f13505050505e025f1b020b061e02571b020b78260a13505050505d1b030b13505050505f18010a13505050505b030b13505050505a13505050505f071b020b7e260a135050505051e1350505050513201d13505050505e02611f13505050505d13505050505f7d13505050505e13505050505f7e13505050505d13505050505f061b020b7b13505050505b1c18001b000b13505050505e025f221e13505050505a13505050505f13505050505f13505050505091c18011e025f1700c61b020b7c13505050505e1c18011e025f1b000b13505050505e025f221e13505050505a13505050505f13505050505f13505050505e025f1b000b13505050505f13505050505e025f1e001f3a13505050505e025f13505050505e009d240a13505050505d17000f18011e025f135050505052d1f4716ffc618011e025f1b000b13505050505e025f08031f8f188f13505050505f8e188e221e009d240a13505050505e17000c18011e025f188e190016ffdc13505050505f7f13505050505ba13505050505e13505050505a1c13505050505e135050505051e13505050505a13505050505f13505050505e13505050505d01d13505050505e002b240200f90a13505050505f0c131e00061a001f0d180c17004a48001f0e180e180c1e001f3a17003b180d180c180e19221e002b13505050505a0a13505050505b000b22180c180e19221e002b13505050505a0a13505050505d180e2d1f0e16ffc13505050505d1d00b13505050505b000b19221e13505050505a13505050505d00b13505050505f135050505051e025f1f061b020b121e13505050505f13505050505e13505050505b020b061e02571b020b78260a13505050505a13505050505c1b000b13505050505e00061a13505050505e025b1d025b13505050505d025f13505050505d00b13505050505e02691d13505050505e026a1d026a13505050505e026b1d026b13505050505e01eb1d01eb13505050505e026c1d026c13505050505e026d1d026d13505050505e026e1d026e1a02001f13505050505f13505050505f061b020b121e02701e001f13505050505f13505050505b020b121e02701e001f3a17006c1b020b121e13505050505f13505050505e000f13505050505a135050505051e007b13505050505b020b121e13505050505a13505050505f061b020b5a1e01d2221e135050505051350505050513505050505a13505050505c16000b18082d1f0816ff8a1b000b13505050505d17000c1b000b1f13505050505f13505050505e13505050505e00a13505050505f13505050505151c13505050505e13505050505a13505050505d13505050505e00d13505050505a13505050505f13505050505e00d13505050505e001f0a13505050505f13505050505e002b13505050505a13505050505e13505050505a13505050505f13505050505f13505050505d13505050505e13505050505e00a1350505050517000c1350505050513505050505f13505050505a13505050505b020b7a13505050505c1b020b7d13505050505c001f13505050505b25000b18001b020b13505050505f13505050505c13505050505b000b19221e13505050505b020b860a13505050505d027d001f13505050505e2500c01b020b061e01cc13505050505b020b13505050505a111e027d13505050505b020b121f061b000b05221e01d13505050505a13505050505c1b020b8a13505050505c18061e027a13505050505b020b8b18061e027f041c1b020b8c18061e13505050505c1b020b13505050505c18061e13505050505b000b1d261b020b13505050505a13505050505c1b020b5d260a13505050505c1b020b121e13505050505c18061e13505050505b020b12201d02811b020b37260a13505050505c1b000b1d261b020b13505050505a13505050505c001f135050505051e13505050505e13505050505c1c1b000b0c221e001d13505050505e01850a13505050505e01853f17000d1b020b13505050505a13505050505e027a17002a18001e027f1e001f48003e13505050505d1c18001e027f1e13505050505d1b020b13505050505a13505050505f8a13505050505f48001f13505050505e001f3a17002f13505050505f1b020b121e13505050505e13505050505b000b13505050505a010a13505050505c18062d1f0616ffcc001f8b13505050505f18001b000b13505050505f13505050505e001f3a13505050505b020b121e13505050505e13505050505b000b135050505051a135050505050a00020a13505050505c18062d1f0616ffc6001f8c13505050505e13505050505c13505050505f8d13505050505b020b0f1b020b061e028a13505050505c13505050505f061b020b111b020b061e028a041c13505050505b3d17000b13505050505f135050505053d17000c1b000b081e02691f135050505051d13505050505f8e211b000b051e01d13505050505c71b000b05221e003e241b000b050201d7131e00061a13505050505d13505050505e13505050505b1c18001b000b063e17000d1b000b13505050505c1a01471b000b13505050505f13505050505f13505050505b031e001f3a17005b1b13505050505f13505050505b1c18081b000b135050505051f13505050505c1f091b000b051e00221e028d221e13505050505a13505050505d135050505050d16ffd318072d1f0716ffa13505050505f8f188f1d028e22201d028f22201d02900a13505050505c1b000b051e00f13505050505b000b13505050505b000b051e00221e028d1f06131e00061a13505050505d13505050505e13505050505a13505050505f1350505050513505050505d13505050505d0a00071f13505050505e001f1f13505050505b1350505050513505050505c1350505050513505050505c13505050505e17000d1b000b13505050505a01470a00001f13505050505f13505050505a1f071b030b06221e13505050505a135050505051e13505050505a13505050505c16ffd51b030b13505050505f13505050505b030b093a13505050505b030b06221e13505050505b030b13505050505a135050505051e13505050505b030b13505050505a13505050505c18082d1f0816ffc13505050505a13505050505d00f1131e00061a13505050505d01a13505050505d01dd22121d01cc13505050505d028a13505050505d01df13505050505d02571f06131e00061a13505050505d13505050505d13505050505d13505050505d13505050505d027a220a00001d027f220a00001d13505050505a00001d13505050505a00001d13505050505a1d017d13505050505b1d00df13505050505c1d029d1f12131e00061a001f1a14029e1f1f48001f13505050505e1b021b020b351d029f1b13505050505d02a01b020b13505050505f34271f13505050505a1b021b020b361d029f1b020b30481c13505050505f061b13505050505d02a01b020b13505050505f13505050505b021b020b341d029f1b020b321b020b30481a13505050505b020b13505050505f36131e00061a135050505051f061b020b13505050505f111e027d1e02991f13505050505c1b020b121e02991f13505050505c1b000b11221e13505050505a13505050505a13505050505a318010a13505050505c001d01d21f5a131e00061a13505050505d02a13505050505d01b13505050505d02a13505050505d01bc13505050505d02a61f5b121f5c0a00001f5e0a00001f5f0a00001f1350505050513505050505f1350505050518002a001f660202a71f6d0202a81f6e1b000b13505050505d1c1b000b201b000b05411f7b1b000b13505050505d1c1b000b211b000b05411f7c1b000b19221e00fb13505050505a13505050505f86186f1f13505050505e13505050505d027e18871e13505050505d13505050505e13505050505d1d13505050505b1c180d260a13505050505d01cc188e260a13505050505c13505050505d027c13505050505d1d13505050505d027e13505050505d02551b000b05221e003e13505050505a9131e00061a13505050505d028e0a13505050505c000a13505050505c0002aa00066d13505050505c13505050505b6c13505050505c61766b6d6c03636f13505050505a726d13505050505d13505050505e607b13505050505d13505050505e13505050505b714b470c666d61776f676c764f6d13505050505b71446b13505050505d7a086b13505050505b13505050505a720b616d6c13505050505d70016b13505050505b4a564f4e476e676f676c13505050505d13505050505b6c13505050505d1350505050563706b50676f6d76674c6d766b646b13505050505b6d6c5f13505050505b13505050505a4c6d766b646b13505050505b6d6c0c13505050505b6f13505050505f13505050505b6f13505050505e13505050505d6d6e67636c13505050505c70636c666d6f13505050505b6c653e13505050505a3b13505050505a6b68696e6f6c6d13505050505a7b13505050505a4b48494e4f4c4d13505050505a5b13505050505e6d6d13505050505c666d6f066e676c65766a09666d6f13505050505f596d13505050505b6c666d755f13505050505d766d767b13505050505e6e076b6c66677a4d13505050505d61776f676c13505050505d13505050505c63746b13505050505d705f10596d13505050505a6b71766d707b5f0a13505050505d6f13505050505b6c65013f13505050505e6b13505050505f06616a1350505050513505050505b6c13505050505d6d696b670e13505050505b6d6c51766d13505050505b76676f0c6e6d61636e51766d13505050505d6d696b13505050505d6d696b13505050505b76676f313f13505050505a726b13505050505f4f6d6c2e13505050505135050505051350505050513505050505a3f2d390a13505050505a726b13505050505f0b766d454f13505050505b6c13505050505a3f2d13505050505e416d6d696b670a70676f6d74674b76676f0e1350505050513505050505e13505050505b6c13505050505d13505050505b026b1350505050513505050505e6d13505050505d6c716d6e13505050505b13505050505a6d13505050505b66766a0a6b6c6c13505050505b66766a0b6d13505050505a676b656a760b6b6c6c67704a676b656a760a6c6d1350505050572706d13505050505d13505050505d13505050505f0d726a636c766d6f13505050505e77656b6c71085d726a636c766d6f0b61636e6e526a636c766d6f0b5d5d6c6b656a766f13505050505b6d13505050505c13505050505c13505050505b6c65416d6c76677a13505050505f13505050505b1350505050513505050505b13505050505d756c52706d13505050505b4c636f13505050505e636c13505050505a706d6f13505050505c766b6f13505050505d6c6c13505050505d5d13505050505b13505050505d13505050505e13505050505d5d71676e676c6b776f5d13505050505e13505050505b5d5d13505050505b13505050505d13505050505b72765d64776c61766b6d6c175d5d13505050505b13505050505d13505050505b72765d64776c61155d5d13505050505b13505050505d13505050505b72765d646c135d5d647a66706b13505050505d13505050505e13505050505d5d66706b13505050505d776c13505050505d5d13505050505b13505050505d776c13505050505d5d66706b13505050505d13505050505e13505050505d5d71676e676c6b776f5d776c13505050505d5d647a66706b13505050505d776c13505050505d71676e676c6b776f0c61636e6e51676e676c6b776f165d51676e676c6b776f5d4b46475d13505050505d13505050505d61776f676c76056f13505050505a0a5e13505050505f785f66615d13505050505a675d0f6b6c616d656c6b766d13505050505d72676c096b6c616d656c6b766d076d6c13505050505d13505050505d13505050505d56435d475a13505050505d13505050505d6f13505050505b4a13505050505b13505050505b6c66677a13505050505c526d6b6c13505050505c760e4f51526d6b6c13505050505c760a6a6d6d13505050505d13505050505e676f676c13505050505c13505050505d13505050505e13505050505e13505050505e13505050505a6c63766b13505050505d13505050505d13505050505e77656b6c13505050505b5f0e6e6d13505050505b6d6c13505050505a5c6a13505050505d385e2d5e2d2a59322f3b5f79332e317f2a5e2c59322f3b5f79332e317f2b79317f7e59632f64322f3b5f79332e367f2a13505050505f64322f3b5f79332e367f2b79357f2b086e6d13505050505b6d6c046a13505050505b6e67106a13505050505d2d6e6d61636e6a6d1350505050513505050505b4c444d0a13505050505d6c76677a13505050505e0c13505050505a76676c716b6d6c13505050505e5d13505050505d70676c13505050505d6b6c646d0c13505050505f13505050505c4f13505050505d54474c464d505d13505050505e17574c4f13505050505d50474c13505050505d13505050505e012d0a13505050505e77656b6c13505050505e57454b4c046b76676f13505050505a04767b13505050505c636f13505050505b6d6c08646b6e676c636f13505050505d6b6c13505050505e6b61670c616d6c716b13505050505a1350505050565676c760b766d4e6d135050505056e13505050505d706f07756b6c666d13505050505b6c07636c66706d6b66056e6b6c777a066b726a6d6c67046b13505050505b726d66036f13505050505f63616b6c766d716a0c6f63615d726d13505050505b13505050505d71037a13505050505b6d13505050505a6b6d13505050505b13505050505b13505050505d7a2d066d13505050505d05226d72702d07616a706d6f672d13505050505b66676c762d046f716b13505050505c666d13505050505d6d656e13505050505d6c13505050505d667b13505050505e676f676c13505050505b13505050505c636f67046a13505050505b13505050505d13505050505e6e13505050505f13505050505b70676f6d13505050505a6b6e660b13505050505c66416a6b6e660e766d406b6c63707b13505050505b6c650c64706d6f416a13505050505d66670d766d576b6c13505050505b0a616a13505050505d13505050505b6c13505050505a36303b363b13505050505b37026f7a04646b7a13505050505c61707b13505050505b6c13505050505b13505050505b13505050505b6c13505050505b0a13505050505a476c616d66670e5c595e7a32322f5e7a35645f13505050505f636e646d706f13505050505b6c13505050505a13505050505d13505050505a6d13505050505b6c651f576c646b6c6b716a13505050505f3a226d13505050505676c13505050505a13505050505d13505050505b13505050505e6b13505050505c6b616d13505050505c13505050505a13505050505f3a22676c616d666b6c13505050505a13505050505a13505050505d66674e6d6c13505050505b6c650a13505050505a13505050505d66670e5c595e7a32322f5e7a64645f13505050505057a7a13505050505b72760e135050505056c13505050505656a13505050505a322d4f13505050505a4b13505050505e476b354c4e606d735b564d13505050505f13505050505c707b7a3b4a1350505050513505050505d616a63704b6c66677a13505050505a4b48494e4f4c4d13505050505a5b13505050505a6b68696e6f6c6d13505050505a7b135050505053a3b292d13505050505636c13505050505d135050505055d616a13505050505d13505050505636f13505050505f57706e013d026d6c036d13505050505b76616a0e5d13505050505f51756b76616a4d6c0f5d607b13505050505d13505050505f5d13505050505b76616a44706d6f13505050505a670f13505050505c6d6f636e6b67710a666b13505050505b656c0a616d6c716b13505050505c13505050505b76616a03666d6f046c6d13505050505a636c766d6f046a6d6d690b1350505050570670e13505050505f606e13505050505e13505050505b710b13505050505f5d13505050505e13505050505f13505050505f5d13505050505e675d726d6c7b13505050505a222a6a13505050505e2d5e2d7e6a13505050505e2d5e2d7e5e2d5e2d2b3d595c5e2d5f135050505057b0e593d5f2a5e75293f2c28243d2b13505050505d13505050505d13505050505b6c656b647b02797f04716d13505050505d6c516d13505050505b13505050505b036f13505050505076d135050505056c13505050505d646b6c13505050505b6c13505050505b66766a066a676b656a13505050505a13505050505a13505050505b13505050505d6c13505050505b6e6e56677a7604c09f9a8e138e22c0acbf0a716a63666d75406e77700b716a6d754d13505050505a046e6b6f13505050505a6d75416d6e6d135050505056d13505050505c13505050505a13505050505b303a37373b0f416d6c646b65477a13505050505b6d6c076f13505050505a13505050505b6d6c51766d13505050505f6a63714e6d61636e51766d13505050505c6a63714b6c66677a13505050505c13505050505b6e6b766b67710d13505050505d6e77766b6d6c13505050505c0a616d6e6d13505050505a13505050505b6e13505050505d6e77766b6d6c0a13505050505b6e556b66766a0b13505050505b6e4a676b656a760e135050505057b4b6c646d0a135050505057b04766a676c08616a13505050505b6c650c616a13505050505b6c65566b6f670f666b71616a13505050505b6c65566b6f67056e13505050505e0c13505050505d77616a4b6c646d0e6f637a566d77616a526d6b6c76710b135050505056c760a566d77616a13505050505c760c6d6c766d77616a13505050505b13505050505b6f67786d6c1350505050513505050505f6d6c766a13505050505b6f67786d6c674d13505050505f6b6c13505050505d6c13505050505f6d6c6d13505050505a71636c712f13505050505b13505050505b13505050505c0d6f6f6f6f6f6f6f6f6f6f6e6e6b096b6c6c67704a564f4e13505050505b6e13505050505a08646d6c76516b78670a646d6c13505050505f6b6e7b0b6d13505050505b66766a0c6d13505050505a676b656a760c13505050505a13505050505f13505050505b6c65666b6c13505050505b6e13505050505c13505050505d13505050505b0a416d6c13505050505c766b630b516b6f51776c2f477a13505050505f13505050505a13505050505e6b6f0a4e67676e135050505056c13505050505f676b707b6d13505050505b6c13505050505d70666b1350505050563686b13505050505b706b13505050505e63766b6c6d0a416d6e6d6c6c63224f13505050505e637b606b6e6e08486d13505050505f636c13505050505a6f676c760a4f51224d77766e6d6d13505050505c224f56064d52564b4f1350505050513505050505c4b500c43706b636e224a13505050505a13505050505d7b67224e13505050505e6e63700a4f5b504b13505050505d012e0e13505050505b6c76637a13505050505d1350505050513505050505d13505050505f13505050505c63766b74674e676c65766a13505050505b720b746b746d60706d1350505050513505050505d6c6c13505050505b6d6c146f6d135050505056d6c6c13505050505b6d6c13505050505b135050505056d6c6c13505050505b6d6c1c13505050505c13505050505c2c6e2c656d6d656e672c616d6f38333b13505050505e710a6b135050505053e2a59322f3b5f79332e317f2a5e2c59322f3b5f79332e317f2b79317f7e59632f64322f3b5f79332e367f2a13505050505f64322f3b5f79332e367f2b79357f2b355c2a333b305e2c33343a5e2c7e33343b5e2c13505050505e2c7e33325e2c7e13505050505e2c2a13505050505f3b5f7e305e667e13505050505f2b2b1350505050513505050505a636c6c676e0b13505050505d13505050505e6d61636e13505050505b72766b6d6c13505050505c666b13505050505a67610e6d6c6b13505050505c666b13505050505b66207a7a7a7a7a7a7a7a7a7a7a7a367a7a7a7b7a7a7a7a7a7a7a7a7a7a7a7a7a7a7a04597a7b5f017a0d616a13505050505e6b676c764b660b13505050505e6b676c764b13505050505b660d676c61707b13505050505b135050505054a4b48494e4f4c4d13505050505a5b13505050505a6b68696e6f6c6d13505050505a7b135050505053a3b2f2c0e13505050505f606e13505050505f13505050505d13505050505a025c5c01340c13505050505d646b6e13505050505e033d733f13505050505d616d13505050505e5d607b13505050505d13505050505d666b660c5d13505050505d13505050505d666b13505050505d71616b13505050505b66016c135050505056b6f13505050505b6e6b766b67710a766b6f13505050505f13505050505a13505050505d6c13505050505c617b0c13505050505b61674f676f6d707b086e636c13505050505a13505050505d6e77766b6d6c0f13505050505b6e13505050505d6e77766b6d6c13505050505c566d720a13505050505c4e13505050505b13505050505b7a676e13505050505b6d0a72706d1350505050513505050505b09766d77616a4b6c646d08766b6f67786d6c670a766b6f13505050505f13505050505b6c646d0b13505050505d6c76714e6b71760b726e77656b6c714e6b71760a766b6f13505050505f72310a13505050505d6d696b67016f0b717b6c76637a13505050505d700c6c63766b74674e676c65766a13505050505b13505050505b6d6c0b5d5d13505050505b6d6c5d5d08616e6b676c764b660a766b6f13505050505f72360b677a76676c66446b676e13505050505e6e13505050505b6f726b646b1350505050574676c764e6b13505050505c13505050505d4e6b13505050505e6b13505050505b136a636c666e13505050505b606d13505050505c13505050505e13505050505b13505050505e49677b076f13505050505b08716a6b13505050505b036c6d75136a636c666e67526d716b766b6d6c13505050505c760e616a636c13505050505d77616a13505050505d77616a6f6d13505050505d77616a13505050505b13505050505e6b676c765a07616e6b676c765b106a636c666e67416e6b13505050505c760a766d77616a13505050505e614f67636c13505050505e13505050505c13505050505b63766b6d6c13505050505e13505050505c13505050505b6f726e6b646b13505050505e13505050505c1350505050513505050505b660b5d5d63615d13505050505b660f65676c135050505054e6d13505050505c13505050505b656c13505050505e2c6c6d6c13505050505f13505050505c226d13505050505b766a13505050505e13505050505d13505050505b230b666d6f4c6d13505050505e6b13505050505d766d616d6e1350505050513505050505646d13505050505e13505050505c6d6c61670b606d667b54636e13505050505a606d667b5d6a63716a3f13505050505b13505050505b656c13505050505a6c636f673f13505050505d13505050505b663f13505050505b663f086c6d6c13505050505a36303b363b13505050505b13505050505b6d6c13505050505b13505050505a13505050505b6d6c01280a13505050505e13505050505c63746b13505050505d70516b656c636e710b13505050505d66674c636f13505050505c636f13505050505d135050505056e13505050505d13505050505c666d13505050505a666d4c6d13505050505b13505050505b13505050505c766b636e13505050505d13505050505b13505050505f67666b13505050505b517b13505050505f13505050505e13505050505d6d766a0d756b6c666d75516b656c636e71054b6f135050505056c5a13505050505c5b0f6b13505050505d6c76677a13505050505d6d6e13505050505b6e6d13505050505b6d6c13505050505d13505050505b74675a4d13505050505a13505050505c636e0b726d71764f13505050505b13505050505b135050505056c6b6f63766b6d6c13505050505f670d406e13505050505d6d766a57574b46086c13505050505f666d61776f676c76516b656c636e710c616a13505050505760a616d6f13505050505f6d13505050505e637b13505050505b6f13505050505e13505050505e41636c13505050505a13505050505b6f676c76636e2f13505050505e0d6f637a436c6b716d76706d727b1e475a565d76677a13505050505d646b6e13505050505d636c6b716d76706d726b13505050505b565d475a565d76677a13505050505d646b6e13505050505d636c6b716d76706d726b61224f4d585d475a565d76677a13505050505d646b6e13505050505d636c6b716d76706d726b611e4f435a5d56475a13505050505d4f435a5d434c4b514d56504d525b5d475a560c13505050505e516b656c636e13505050505e13505050505d13505050505a76676c716b6d6c13505050505d13505050505a76676c716b6d6c13505050505d6c76677a13505050505b13505050505c766b636e6b13505050505e57475d404b13505050505e13505050505b76710a13505050505a5d404b13505050505a406b76710a13505050505c5d404b13505050505c406b13505050505f435a5d414d4f404b4c47465d56475a13505050505d4b4f13505050505d574c4b56511c6f637a416d6f606b6c13505050505a13505050505b6f13505050505c6b13505050505f435a5d13505050505d4f43525d56475a13505050505d514b13505050505f637a13505050505f13505050505a13505050505b78671c4f435a5d13505050505f474c565d574c4b444d504f5d13505050505d13505050505f637a13505050505f676c76576c6b646d706f13505050505d13505050505f435a5d50474c135050505055d514b13505050505f637a50676c13505050505516b13505050505f435a5d56475a13505050505d4b4f13505050505d574c4b13505050505f637a56677a13505050505b6f13505050505c6b13505050505f435a5d56475a13505050505d514b58470e6f637a56677a13505050505b13505050505f435a5d13505050505b4b4c455d13505050505d13505050505f637a13505050505b6b6c13505050505d13505050505f435a5d13505050505a5d13505050505b13505050505f637a13505050505a13505050505b60711e4f435a5d13505050505a5d56475a13505050505d4b4f13505050505d574c4b56511a6f637a13505050505a56677a13505050505b6f13505050505c6b76711a4f435a5d13505050505a5d574c4b444d504f5d13505050505d13505050505f637a13505050505a576c6b646d706f13505050505d13505050505a43464b4c455d4e434c13505050505d13505050505b4d4c16716a63666b6c654e636c135050505056b6d6c0c13505050505c414b4e5d404b56510b13505050505c616b6e406b13505050505b4d4c13505050505a13505050505c63746b13505050505d13505050505b6c666d135050505054b4c444d0a13505050505b6c646d09766b6f13505050505f720d6b71476c63606e13505050505a145d676c63606e13505050505a4e6b13505050505a0c6b6c13505050505a4a500e5a4f4e4a135050505051350505050513505050505a13505050505c66106d13505050505b66674f6b6f67567b72670f5d63615d6b6c13505050505055d71676c66155d607b13505050505d6b6c13505050505d6e6b13505050505c13505050505f676c76710e5c616d6c76676c762f767b13505050505e5d607b13505050505d616d6c76676c76115d6d13505050505b66674f6b6f67567b72670d5d607b13505050505d6f67766a6d660a5d607b13505050505d77706e076d6c63606d13505050505d6c6e6d13505050505d6c6e6d13505050505c660b6d6c6e6d13505050505a6d6c72706d13505050505d6c766b6f676d77760b5d716b656c13505050505f0b5d607b13505050505d606d667b126d6c13505050505b13505050505a636c65670c13505050505d6c13505050505b13505050505b6f676d13505050505e6d13505050505d13505050505e6b13505050505b6d6c2d7a2f13505050505f646d706f2f77706e676c616d13505050505e6b13505050505b6d6c2d68716d6c04716b656c13505050505b0d13505050505b6c646d4a13505050505e6b6c1350505050576616a135050505056a13505050505f67766a6d660b766d1350505050505616e6d6c13505050505a76076a13505050505d5d63615d6b6c135050505055d13505050505a13505050505a0d13505050505d13505050505a145d13505050505a416d6c76676c76567b72670c616d6c76676c762f767b72670b13505050505c6d6c13505050505f60776b6e664c135050505051350505050513505050505e135050505056d6e6b617b046f6d13505050505a13505050505b13505050505b6c13505050505b767b0e13505050505b13505050505e105d77706e13505050505b13505050505e67710b13505050505b13505050505e22084d504b454b4c38220b13505050505b13505050505b6e13505050505b6c66677a4d13505050505776b6e13505050505e0c245d716b656c13505050505f0c3d5d716b656c13505050505f096b6c13505050505b714b6c13505050505c61674d64407b13505050505e67700d407b13505050505e13505050505d72766b6d6c71046b6c6b760e676c63606e13505050505a4e6b71760f77706e13505050505b13505050505e13505050505d13505050505f74636e6b13505050505d72766b6d6c711e6d72766b6d6c22636b662a4b6c13505050505b226b71226c13505050505d72766b6d6c22676c63606e13505050505a4e6b71762a13505050505b2b226b71226c135050505056c13505050505a4e6b13505050505a13505050505c57706e13505050505b13505050505a0a13505050505700c5d5d63615d1350505050567636e13505050505616a670a135050505057b0a5d5d63615d606e636c692a41636c6c6d13505050505d6c13505050505c13505050505b6c13505050505d70226c776e6e22766d226d13505050505e6a63714d756c52706d13505050505b13505050505e13505050505b13505050505e670c616d6c646b13505050505e13505050505d13505050505b4b71476c776f13505050505e670e766d4e6d61636e13505050505b6c13505050505e77674d640d6b13505050505d766d767b72674d64204d13505050505c69677b13505050505e6e13505050505d6c226c6d6c2f6d13505050505c33332c13505050505d0c5a2f4f13505050505f4b6c646d03606d67296a13505050505d2d7a7a60652c716c13505050505c616d6f2d13505050505d74332d13505050505b6c646d236a13505050505d2d7a7a60652c716c13505050505c616d6f2d13505050505d74332d72236a13505050505d2d7a7a60652c716c13505050505c616d6f2d13505050505d74332d13505050505e0a135050505053b13505050505a13505050505f3c0d616d6e6d13505050505096f6d13505050505f6d13505050505b666d756c096f6d13505050505d756c13505050505a5d5d67714f6d66776e67";
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=13505050505&max_behot_time=0&category=pc_profile_channel&disable_raw_data=true&aid=24&app_name=toutiao_web"
# _02B4Z6wo00f01vu4PgAAAIDBBEfB.ftCImL7mjqAANsre0
import 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=13505050505&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 os
os.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=13505050505&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 Workbook
base_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.text
return page_text
def list_to_str(my_list):
my_str = "".join(my_list)
return my_str
def get_abstract(url):
response = requests.get(url=url, headers=headers)
page_text = response.text
tree = etree.HTML(page_text)
abstract = tree.xpath('//div[@class="xx_font"]//text()')
return abstract
def 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_info
def write_to_excel(info, search_word):
wb = Workbook()
ws = wb.active # 创建子表
ws.title = search_word
title = ['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()