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 = '0123456789abcdef'.encode() # 秘钥: 因为aes-128模式,所以必须16字节
iv = 'abcdabcdabcdabcd'.encode() # 偏移量:因为aes-128模式,所以必须16字节
text = 'Self-improvement is a lifelong process!' # 加密内容,因为aes-128模式,所以字节长度必须是16的倍数
# while len(text.encode('utf-8')) % 16 != 0: # 如果text不足16位的倍数就用空格补足为16位
# text += '\0'
text = pad(text.encode(), 16) # pad在这里如果加密不足16位就会block_size:16填充
print("完整text:", text)
aes = AES.new(key, AES.MODE_CBC, iv) # 创建一个aes对象,传key,iv;中间值是个固定值模式,用AES中CBC模式
en_text = aes.encrypt(text) # 加密明文encrypt
print("aes加密数据:::", en_text) # b"_\xf04\x7f/R\xef\xe9\x14#q\xd8A\x12\x8e\xe3\xa5\x93\x96'zOP\xc1\x85{\xad\xc2c\xddn\x86"
en_text = base64.b64encode(en_text).decode() # 将返回的字节型数据转进行base64编码,防止混淆,歧义
print(en_text) # Pwhs4f1/GxersDcWwZa6fxJTS4YfeV3FoOWvcq14jSLdG+clB/H3+kqBnAfwmZ03
CBC解密案例:先解码,再解密
from Crypto.Cipher import AES
import base64
from Crypto.Util.Padding import unpad
key = '0123456789abcdef'.encode()
iv = 'abcdabcdabcdabcd'.encode()
aes = AES.new(key, AES.MODE_CBC, iv)
text = 'Pwhs4f1/GxersDcWwZa6fxJTS4YfeV3FoOWvcq14jSLdG+clB/H3+kqBnAfwmZ03'.encode() # 需要解密的文本
ecrypted_base64 = base64.b64decode(text) # base64解码成字节流
source = aes.decrypt(ecrypted_base64) # 解密decrypt
print("aes解密数据:::", source.decode())
print("aes解密数据:::", unpad(source, 16).decode())
1.在Python中进行AES加密解密时,所传入的密文、明文、秘钥、iv偏移量、都需要是bytes(字节型)数据。python 在构建aes对象时也只能接受bytes类型数据。
2.当秘钥,iv偏移量,待加密的明文,字节长度不够16字节或者16字节倍数的时候需要进行补全。
3.CBC模式需要重新生成AES对象,为了防止这类错误,无论是什么模式都重新生成AES对象就可以了。
3.2 毛毛租的python逆向
毛毛租平台:https://www.maomaozu.com/#/build
3.2.1 加密
绝招:加一个断点
找key和iv:
3.2.2 解密
import json
import requests
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import base64
cookies = {
'PHPSESSID': '6rhg42ce8egfeulonevjnfj4sv',
'Hm_lvt_6cd598ca665714ffcd8aca3aafc5e0dc': '1706941076',
'SECKEY_ABVK': 'aJ99/mmPcgDcnVNO8MQjq74LRk9XDbNZo7uGOCGoln0%3D',
'Hm_lpvt_6cd598ca665714ffcd8aca3aafc5e0dc': '1706941479',
'BMAP_SECKEY': 'IN6Q3NYbpjYXemaxNcEdhP7dkIvDfrO09kOcuQx3rurdS546vjNWE-mY8RexJlLiLTvJaySgMcDcsFIr0mbjJKoCPrsissHnmXCxfpEUr4az4OxDtbb-s1bmRsoQs0yz9nVTEtFnE5dWUcYecms3m4YY8bV6rl2Sj6HvoQPViznasWG2OkGUebHlE5loh2dV',
}
headers = {
'Accept': '*/*',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
'Content-Type': 'application/json; charset=UTF-8',
# 'Cookie': 'PHPSESSID=6rhg42ce8egfeulonevjnfj4sv; Hm_lvt_6cd598ca665714ffcd8aca3aafc5e0dc=1706941076; SECKEY_ABVK=aJ99/mmPcgDcnVNO8MQjq74LRk9XDbNZo7uGOCGoln0%3D; Hm_lpvt_6cd598ca665714ffcd8aca3aafc5e0dc=1706941479; BMAP_SECKEY=IN6Q3NYbpjYXemaxNcEdhP7dkIvDfrO09kOcuQx3rurdS546vjNWE-mY8RexJlLiLTvJaySgMcDcsFIr0mbjJKoCPrsissHnmXCxfpEUr4az4OxDtbb-s1bmRsoQs0yz9nVTEtFnE5dWUcYecms3m4YY8bV6rl2Sj6HvoQPViznasWG2OkGUebHlE5loh2dV',
'Origin': 'https://www.maomaozu.com',
'Pragma': 'no-cache',
'Referer': 'https://www.maomaozu.com/',
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Site': 'same-origin',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0',
'sec-ch-ua': '"Chromium";v="122", "Not(A:Brand";v="24", "Microsoft Edge";v="122"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
}
# # 批量爬
# for i in range(1, 10):
# data = {
# "Type": 0,
# "expire": 1706974966977,
# "page": 5,
# }
#
# key = '55b3b62613aef1a0'.encode()
# iv = '55b3b62613aef1a0'.encode()
# text = json.dumps(data)
#
# text = pad(text.encode(), 16)
# print("完整text:", text)
#
# aes = AES.new(key, AES.MODE_CBC, iv) # 创建一个aes对象
#
# en_text = aes.encrypt(text) # 加密明文
# print("aes加密数据:::", en_text)
#
# en_text = base64.b64encode(en_text).decode()
# print(en_text)
#
# # data = 'i1gpLEJyKvluv3sQVGr/h6RZxT9vv00IpxineW3h2Y8GGtjqGm2Gl46nX7lTrD7H' # 加密值
#
# response = requests.post('https://www.maomaozu.com/index/build.json', cookies=cookies, headers=headers,
# data=en_text)
# print(response.text)
# 数据加密3个加密项
data = {
"Type": 0,
"expire": 1706974966977,
"page": 5,
}
key = '55b3b62613aef1a0'.encode()
iv = '55b3b62613aef1a0'.encode()
text = json.dumps(data)
text = pad(text.encode(), 16)
print("完整text:", text)
aes = AES.new(key, AES.MODE_CBC, iv) # 创建一个aes对象
en_text = aes.encrypt(text) # 加密明文
print("aes加密数据:::", en_text)
en_text = base64.b64encode(en_text).decode()
print(en_text)
# data = 'i1gpLEJyKvluv3sQVGr/h6RZxT9vv00IpxineW3h2Y8GGtjqGm2Gl46nX7lTrD7H' # 加密值
response = requests.post('https://www.maomaozu.com/index/build.json', cookies=cookies, headers=headers, data=en_text)
print(response.text)
# 解密数据逻辑
key = "0a1fea31626b3b55".encode()
iv = "0a1fea31626b3b55".encode()
aes = AES.new(key, AES.MODE_CBC, iv)
ecrypted_base64 = base64.b64decode(response.text.encode()) # base64解码成字节流
source = aes.decrypt(ecrypted_base64) # 解密
print("aes解密数据:::", source.decode())
print("aes解密数据:::", unpad(source, 16).decode())