js逆向是一座大山
一、浏览器的问题
1.Elements
里面的东西是页面源代码 =>可以经过js进行整容(script),浏览器进行二次渲染(如table或其他标签),=>elements里面的代码
2.Console
控制台,这里可以写js代码
3.Sources
放着页面源代码和网页的所有资源,后期会作为调试js的主要工具
4.Network:
headers:
- User-agent:请求的设备版本,以后所有请求至少给一个这个东西
- Refer:防盗链,在抓包工具中,双击url,如果能跳转获取到你需要的东西,就不需要加Refer,Refer其实就是判断上一个url是什么
Payload:请求参数,get,post
get请求
query String parameters
把参数通过url进行传递
通过params传递参数
pythonurl = “http://www.baidu.com” dict = { name: "coder", age: 18 } requests.get(url, params = dict) #上述参数最终也会放到url里
post请求
发送请求默认
Content-Type是application/x-www-form-urlencodedForm Data
python#直接给字典就行 url = “http://www.baidu.com” data = { name: "coder", age: 18 } requests.post(url, data = data) #上述参数最终也会放到url里Request Payload
请求挂载,传输的数据大多情况下是json字符串,在payload里面可以观察到是json格式的数据,或者在请求头里面看到
Content-Type:application/json通过data传递数据
pythonimport json url = “http://www.baidu.com” data = { name: "coder", age: 18 } headers = { Content-Type: "application/json;charset=utf-8" } requests.post(url, data = json.dumps(data, separators=(",", ":")), headers = headers)通过requests中的json直接处理,不过有坑!
pythonurl = “http://www.baidu.com” data = { name: "coder", age: 18 } requests.post(url, json = data)坑就是:python自动进行字典转换为json的时候,会有空格,很多后台在做反爬时会判断,这种时候没法解决,只能换data方式
如果在protocol里面看到h2的时候,表示当前请求用的是http2.0的版本,大多数网页都是兼容http1.1的,有些网页会屏蔽http1.1,python的requests模块不支持http2.0,如果你能使用的所有手段都测试过了发现还是不行,可以考虑用一下http2的请求,python发送http2的请求使用httpx
pip install httpximport httpx
client = httpx.Client(http2=True)
#后面和requests一样
client.get()
client.post()5.Application:cookies
在requests中详解
6.无痕模式
去除缓存的干扰,建议使用
二、requests
几个关键点
可以直接使用session来代替requests,建议使用session
- 优点1是保存cookie信息
- 优点2是保存headers信息
import requests
session = requests.session()
url = ""
resp = session.get(url)
print(resp.cookies)
print(session.cookies)#已经拿到了
#修改cookies或headers
session.cookies.set("name", "hello")
session.headers = {
"user-agent": "xxxx"
}
#后面可以直接使用session来发送请求,不用每次都传入headers
session.get(url)三、数据解析
- html
bs4 xpath
js代码
使用re,正则来做
jsonp:js代码+数据(jd为例)

obj = re.compole(r"\((?P<data>.*)\)")
r = obj.search(res)
# print(r.group("data"))
import json
resp = json.loads(r.group('data'))
print(resp)json数据
pythonresp = session.get() print(resp.text) # 先看一下获取的东西是不是json dic = resp.json()png,jpg图片,m3u8,mp4….
css样式文件 直接保存即可
字体文件 直接保存即可
其他
一些加密数据,看js是怎么加密的我们就怎么解密
四、存储
1.存储csv
lst = [
(1,"a", "aaaa"),
(2,"b", "bbbb"),
(3,"c", "cccc"),
]
with open("数据.csv", mode="w", encoding="utf-8") as f:
for item in lst:
f.write('"'+str(item[0])+'"')
f.write(",")
f.write(str(item[1]))
f.write(",")
f.write(str(item[2]))
f.write("\n")
# 如果数据中有逗号
with open("数据.csv", mode="w", encoding="utf-8") as f:
for item in lst:
f.write('"'+str(item[0])+'"')
f.write(",")
f.write('"'+str(item[1])+'"')
f.write(",")
f.write('"'+str(item[2])+'"')
f.write("\n")
# 如果有一些奇怪符号如引号,那就更换分隔符
# 要告诉客户分隔符是什么
with open("数据.csv", mode="w", encoding="utf-8") as f:
for item in lst:
f.write(str(item[0]))
f.write("|")
f.write(str(item[1]))
f.write("|")
f.write(str(item[2]))
f.write("\n")
import pandas as pd
r = pd.read_csv("数据.csv", sep="|", header=None)
print(r)
#转存到excel
r.to_excel("data.xlsx")2.mysql
sqlite好用
3.sqlite3
import sqlite3
conn = sqlite3.connect("data.db")
cur = conn.cursor()
try:
sql = ""
cur.excute(sql, (p1, p2, ...))
cur.commit()
except Exception as e:
print(e)4.普通文件下载
import requests
url = ""
resp = requests.get(url)
with open("", mode="wb") as f:
f.write(resp.content)五、如何提高爬虫效率
多线程
直接上线程池,控制好并发
相似或者相同的任务适合多线程
pythonfrom concurrent.futures import ThreadPoolExecutor def work(i): print("爬取", i) # 10是并发量,注意控制 if __name__ == '__main__': with ThreadPoolExecutor(10) as t: for i in range(100): t.submit(work, i) print("done")多进程
多个任务之间关联不大的时候可用多进程
协程
电影:m3u8一般不设防,一堆URL,下载文件,一般是云服务,
六、爬虫框架
scrapy,一般不用
七、找到加密入口方案
目标:
- 参数加密前什么样
- 怎么加密的
1. 找浏览器的initiator
启动器,下下策,它记录着浏览器js执行的过程
request call stack
断点
- 可以查看当前这个位置所有能够使用到的标量
- 可以查看当前位置可以执行的函数是什么?以及函数执行之后的结果是什么,甚至可以改变当前位置的函数声明
- 可以在断电状态下,选择一个变量或函数,鼠标划上去,看一下有什么东西
- 可以在断点状态下,在console中输入一个变量或者函数,来看该函数或变量的内容,通过call stack可以查看上一步调用位置的参数,数据,内存,函数(可能会有风险,但是问题不大),但是不要去单步调试,尽可能在当前断点位置进行调试

加密相关

类似上面这种,一般是第三方库,Crypto-js
如何抠代码:
找到入口,把入口拿下来,尝试一个函数一个函数的去填补,过程非常曲折
找到代码的边界
一个大闭包?两个闭包之间?肯定是具有相似性的,需要人为去判别
找第三方库
2.在Search中进行搜索,这是最好的方案
搜url,在url的?前面一个单词接一个单词的搜索
搜参数,请求上的各种参数,主要针对加密参数
拦截器,该网站使用的异步,Promise
没有100%的方案,又快又准确,没有哟!
八、加密
1.md5
当在网站上看到一些加密逻辑,发现计算结果是32位字符串长,该字符串的组成是0-9a-f(十六进制) 然后去尝试,把123456丢进去,看看结果,如果是e10开头,直接标准md5,就可以开始写python代码了
from hashlib import md5
# md5可以加盐,默认是放在待加密数据前面
# obj = md5(b'jdklajflauei')
obj = md5(b'jdkajflajf')
obj.update("hello".encode("utf-8"))
md5_val = obj.hexdigest()
# 0aee8e7baca0a10ea2f97c6f5c6b1f27
print(md5_val)
print(len(md5_val))
def get_md5(s):
obj = md5()
obj.update(s.encode("utf-8"))
return obj.hexdigest()
# 0aee8e7baca0a10ea2f97c6f5c6b1f27
print(get_md5("jdkajflajfhello"))sha1 sha512等等都一样,可以查网站https://1024tools.com/hash
| # | 算法 | 结果 | 结果(大写) | 长度 | 备注 |
| 1 | md5 | e10adc3949ba59abbe56e057f20f883e | E10ADC3949BA59ABBE56E057F20F883E | 32 | 前16位: 小写:e10adc3949ba59ab 大写:E10ADC3949BA59AB |
| 2 | sha1 | 7c4a8d09ca3762af61e59520943dc26494f8941b | 7C4A8D09CA3762AF61E59520943DC26494F8941B | 40 | |
| 3 | sha256 | 8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92 | 8D969EEF6ECAD3C29A3A629280E686CF0C3F5D5A86AFF3CA12020C923ADC6C92 | 64 | |
| 4 | sha512 | ba3253876aed6bc22d4a6ff53d8406c6ad864195ed144ab5c87621b6c233b548baeae6956df346ec8c17f5ea10f35ee3cbc514797ed7ddd3145464e2a0bab413 | BA3253876AED6BC22D4A6FF53D8406C6AD864195ED144AB5C87621B6C233B548BAEAE6956DF346EC8C17F5EA10F35EE3CBC514797ED7DDD3145464E2A0BAB413 | 128 | |
| 5 | adler32 | 042e0136 | 042E0136 | 8 | |
| 6 | crc32 | 70930f27 | 70930F27 | 8 | |
| 7 | crc32b | 0972d361 | 0972D361 | 8 | |
| 8 | crc32c | 41357186 | 41357186 | 8 | |
| 9 | fnv132 | eb008bb8 | EB008BB8 | 8 | |
| 10 | fnv164 | 10f897e26c4b9478 | 10F897E26C4B9478 | 16 | |
| 11 | fnv1a32 | 9995b6aa | 9995B6AA | 8 | |
| 12 | fnv1a64 | f6e3ed7e0e67290a | F6E3ED7E0E67290A | 16 | |
| 13 | gost | 84cdecc9c273927ff6d9cca1ae75945990a2cb1f81e5daab52a987f6d788c372 | 84CDECC9C273927FF6D9CCA1AE75945990A2CB1F81E5DAAB52A987F6D788C372 | 64 | |
| 14 | gost-crypto | 7db20e3a7d652bde0b1a1b7486076a2e11f795e99bf7f5fe700fb83f15b19ef2 | 7DB20E3A7D652BDE0B1A1B7486076A2E11F795E99BF7F5FE700FB83F15B19EF2 | 64 | |
| 15 | haval128,3 | 1d8071d4a59f25a2a92a9a4844ba1e05 | 1D8071D4A59F25A2A92A9A4844BA1E05 | 32 | |
| 16 | haval128,4 | 2019090003211f11c03adb877bf3ae20 | 2019090003211F11C03ADB877BF3AE20 | 32 | |
| 17 | haval128,5 | 60271b45e6d4b8eea7d9f474e69c848b | 60271B45E6D4B8EEA7D9F474E69C848B | 32 | |
| 18 | haval160,3 | 83e612afb8ed267198b696759a49561375f70c81 | 83E612AFB8ED267198B696759A49561375F70C81 | 40 | |
| 19 | haval160,4 | 3da690924ffb8d3f5bff8b608279f3c419bdb9c9 | 3DA690924FFB8D3F5BFF8B608279F3C419BDB9C9 | 40 | |
| 20 | haval160,5 | ee85271e7bb4b7f2ec4c5418b47804eb1be9e91f | EE85271E7BB4B7F2EC4C5418B47804EB1BE9E91F | 40 | |
| 21 | haval192,3 | d2cfda5179fd9b6037ba35f261c576b2300717151a8db6a5 | D2CFDA5179FD9B6037BA35F261C576B2300717151A8DB6A5 | 48 | |
| 22 | haval192,4 | 7e1e573209c8d7f39919bea0d1466df325f3dbdd1fd3057a | 7E1E573209C8D7F39919BEA0D1466DF325F3DBDD1FD3057A | 48 | |
| 23 | haval192,5 | 9e8acd170a8fe1b929c0c652397b6b494abf1cd095371ad7 | 9E8ACD170A8FE1B929C0C652397B6B494ABF1CD095371AD7 | 48 | |
| 24 | haval224,3 | d59e77b4c4d7aa6e02708683381c5631ee79b9e50ab9eaeb4dc38b9a | D59E77B4C4D7AA6E02708683381C5631EE79B9E50AB9EAEB4DC38B9A | 56 | |
| 25 | haval224,4 | 64d007c6e75ee71244bf33a876c8f380c17e64b18d3d9be67000b277 | 64D007C6E75EE71244BF33A876C8F380C17E64B18D3D9BE67000B277 | 56 | |
| 26 | haval224,5 | dbcdd0348d0b23a89fe3e190abd8b279a5d8d4fa4e62d1e02ad0a6ff | DBCDD0348D0B23A89FE3E190ABD8B279A5D8D4FA4E62D1E02AD0A6FF | 56 | |
| 27 | haval256,3 | 0e3b78d8380844b0f697bb912da7f4d210382c6714194fd16039ef2acd924dcf | 0E3B78D8380844B0F697BB912DA7F4D210382C6714194FD16039EF2ACD924DCF | 64 | |
| 28 | haval256,4 | 84095060071ad0f4f41fa629653511074720aaa94c4f0d873e317d58002f8020 | 84095060071AD0F4F41FA629653511074720AAA94C4F0D873E317D58002F8020 | 64 | |
| 29 | haval256,5 | 2f014311e0926fa8b3d6e6de2051bf69332123baadfe522b62f4645655859e7a | 2F014311E0926FA8B3D6E6DE2051BF69332123BAADFE522B62F4645655859E7A | 64 | |
| 30 | joaat | eef833c1 | EEF833C1 | 8 | |
| 31 | md2 | d4541250b586296fcce5dea4463ae17f | D4541250B586296FCCE5DEA4463AE17F | 32 | |
| 32 | md4 | 585028aa0f794af812ee3be8804eb14a | 585028AA0F794AF812EE3BE8804EB14A | 32 | |
| 33 | ripemd128 | d6d56cab46e0f3af2c756289f2b447e0 | D6D56CAB46E0F3AF2C756289F2B447E0 | 32 | |
| 34 | ripemd160 | d8913df37b24c97f28f840114d05bd110dbb2e44 | D8913DF37B24C97F28F840114D05BD110DBB2E44 | 40 | |
| 35 | ripemd256 | 77093b1266befed58d512e67b3a8a15398c3ce5c1333d66a190becc9baa329e9 | 77093B1266BEFED58D512E67B3A8A15398C3CE5C1333D66A190BECC9BAA329E9 | 64 | |
| 36 | ripemd320 | a2ee4b6b9e3144c7db61b1ffc748bf2c728b65819e3f69a021f515acb044995b90f03d60974b6b4a | A2EE4B6B9E3144C7DB61B1FFC748BF2C728B65819E3F69A021F515ACB044995B90F03D60974B6B4A | 80 | |
| 37 | sha224 | f8cdb04495ded47615258f9dc6a3f4707fd2405434fefc3cbf4ef4e6 | F8CDB04495DED47615258F9DC6A3F4707FD2405434FEFC3CBF4EF4E6 | 56 | |
| 38 | sha3-224 | 6be790258b73da9441099c4cb6aeec1f0c883152dd74e7581b70a648 | 6BE790258B73DA9441099C4CB6AEEC1F0C883152DD74E7581B70A648 | 56 | |
| 39 | sha3-256 | d7190eb194ff9494625514b6d178c87f99c5973e28c398969d2233f2960a573e | D7190EB194FF9494625514B6D178C87F99C5973E28C398969D2233F2960A573E | 64 | |
| 40 | sha3-384 | 1fb0da774034ba308fbe02f3e90dc004191df7aec3758b6be8451d09f1ff7ec18765f96e71faff637925c6be1d65f1cd | 1FB0DA774034BA308FBE02F3E90DC004191DF7AEC3758B6BE8451D09F1FF7EC18765F96E71FAFF637925C6BE1D65F1CD | 96 | |
| 41 | sha3-512 | 64d09d9930c8ecf79e513167a588cb75439b762ce8f9b22ea59765f32aa74ca19d2f1e97dc922a3d4954594a05062917fb24d1f8e72f2ed02a58ed7534f94d27 | 64D09D9930C8ECF79E513167A588CB75439B762CE8F9B22EA59765F32AA74CA19D2F1E97DC922A3D4954594A05062917FB24D1F8E72F2ED02A58ED7534F94D27 | 128 | |
| 42 | sha384 | 0a989ebc4a77b56a6e2bb7b19d995d185ce44090c13e2984b7ecc6d446d4b61ea9991b76a4c2f04b1b4d244841449454 | 0A989EBC4A77B56A6E2BB7B19D995D185CE44090C13E2984B7ECC6D446D4B61EA9991B76A4C2F04B1B4D244841449454 | 96 | |
| 43 | sha512/224 | 007ca663c61310fbee4c1680a5bbe70071825079b23f092713383296 | 007CA663C61310FBEE4C1680A5BBE70071825079B23F092713383296 | 56 | |
| 44 | sha512/256 | 184b5379d5b5a7ab42d3de1d0ca1fedc1f0ffb14a7673ebd026a6369745deb72 | 184B5379D5B5A7AB42D3DE1D0CA1FEDC1F0FFB14A7673EBD026A6369745DEB72 | 64 | |
| 45 | snefru | 3321dcaf8911d3842e14a7a415be2fb1a337f4306a4fb8290fd7fe33be269df7 | 3321DCAF8911D3842E14A7A415BE2FB1A337F4306A4FB8290FD7FE33BE269DF7 | 64 | |
| 46 | snefru256 | 3321dcaf8911d3842e14a7a415be2fb1a337f4306a4fb8290fd7fe33be269df7 | 3321DCAF8911D3842E14A7A415BE2FB1A337F4306A4FB8290FD7FE33BE269DF7 | 64 | |
| 47 | tiger128,3 | 5b2715f7cb7488ce2deb8544f0aa91b6 | 5B2715F7CB7488CE2DEB8544F0AA91B6 | 32 | |
| 48 | tiger128,4 | effe440b596c7d1766d435a2fd16641e | EFFE440B596C7D1766D435A2FD16641E | 32 | |
| 49 | tiger160,3 | 5b2715f7cb7488ce2deb8544f0aa91b6f0eec76f | 5B2715F7CB7488CE2DEB8544F0AA91B6F0EEC76F | 40 | |
| 50 | tiger160,4 | effe440b596c7d1766d435a2fd16641e27d32af5 | EFFE440B596C7D1766D435A2FD16641E27D32AF5 | 40 | |
| 51 | tiger192,3 | 5b2715f7cb7488ce2deb8544f0aa91b6f0eec76fb3b74265 | 5B2715F7CB7488CE2DEB8544F0AA91B6F0EEC76FB3B74265 | 48 | |
| 52 | tiger192,4 | effe440b596c7d1766d435a2fd16641e27d32af54ec875c2 | EFFE440B596C7D1766D435A2FD16641E27D32AF54EC875C2 | 48 | |
| 53 | whirlpool | fd9d94340dbd72c11b37ebb0d2a19b4d05e00fd78e4e2ce8923b9ea3a54e900df181cfb112a8a73228d1f3551680e2ad9701a4fcfb248fa7fa77b95180628bb2 | FD9D94340DBD72C11B37EBB0D2A19B4D05E00FD78E4E2CE8923B9EA3A54E900DF181CFB112A8A73228D1F3551680E2AD9701A4FCFB248FA7FA77B95180628BB2 | 128 |
2.URLEncode和Base64
(1)URLEncode
quote和quote_plus可以帮我们完成字符串的处理
在逆向的过程中,有可能需要我们在处理cookie的时候,可能会用到
from urllib.parse import quote, quote_plus
# %26%3Dlove/
print(quote("&=love/"))
# %26%3Dlove%2F
print(quote_plus("&=love/"))反向使用unquote,unquote_plus
2.base64
base64的encode作用是将字节ascII范围内的字节,3个字节变成4个字节,
26个大写字母+26个小写字母+10个数字+2个特殊字符(+和/),它是一种摘要算法,跟加密解密没有关系
import base64
# encode过程
s = "我爱上天".encode("utf-8") # b'\xe6\x88\x91\xe7\x88\xb1\xe4\xb8\x8a\xe5\xa4\xa9'
# 先使用base64编码,编码后bs4同样是字节,不过都是ascII范围内的
bs4 = base64.b64encode(s) # b'5oiR54ix5LiK5aSp'
# 将字节处理成base64字符串
print(bs4.decode()) # 5oiR54ix5LiK5aSp
# decode过程
s = "5oiR54ix5LiK5aSp"
bs = base64.b64decode(s) # b'\xe6\x88\x91\xe7\x88\xb1\xe4\xb8\x8a\xe5\xa4\xa9'base64的末尾可能是=,是用来填充的
base64既然可以把字节处理成字符串,有的网站就会把一些小的图片(头像,图标)处理成base64,学会吧base64的图片转存为真实的图片
pythons = "data:image/png;base64, xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxjfklafjdla" s = s.split(',')[1] bs = base64.b64decode(s) with open('xxx.png', mode='wb') as f: f.write(bs)有些时候,有的网站会把base64进行特殊的处理,比如把
+替换成-,把/替换成_应对方案一:
replace(“-”, "+").replace("_", "/")应对方案二:使用base64自动处理
pythonsy = "Z21kD9ZK1ke6ugku2ccWu-MeDWh3z252xRTQv-wZ6jddVo3tJLe7gIXz4PyxGl73nSfLAADyElSjjvrYdCvEP4pfohVVEX1DxoI0yhm36ytQNvu-WLU94qULZQ72aml65Eb-" bsy = base64.b64decode(sy,altchars=b"_-")如果通过上述转换后,进行解密操作发现数据不对,或者根本无法解密,调换一下顺序即可。
字符串可以转换为十六进制的数字,转化逻辑:字节=>8个二进制=>数字=>十六进制,可以使用一个库来操作,那就是
binasciipythonimport binascii # 字符串转换成十六进制 bs = "abcd我喜欢你".encode("utf-8") #字符串变字节 res = binascii.b2a_hex(bs) print(res) # b'61626364e68891e5969ce6aca2e4bda0' # 十六进制转换为字节 s = "61626364e68891e5969ce6aca2e4bda0" print(binascii.a2b_hex(s)) # b'abcd\xe6\x88\x91\xe5\x96\x9c\xe6\xac\xa2\xe4\xbd\xa0'
3.AES
标准库:
- 对称加密:加密和解密时使用的是同一个密钥
- 非对称加密:加密和解密时使用的密钥不是同一个
python的一个第三方库提供了加密逻辑,PyCrypto,一般装不上,使用pycrytodome进行平替
pip install pycryptodome安装成功后,有可能加密包无法使用(不一定能用)
```python
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
# 创建一个aes加密器
aes = AES.new(key=b'1234567890123456',IV=b'1234567890123456',mode=AES.MODE_CBC)
ming = "这是一个测试用例"
ming = ming.encode("utf-8")
# 注意这里加密必须要填充成16字节的倍数,可以使用自带的pad来进行填充
# Data must be padded to 16 byte boundary in CBC mode
ming = pad(ming, 16)
mi = aes.encrypt(ming)
print(mi)
# 解密
aes = AES.new(key=b'1234567890123456',IV=b'1234567890123456',mode=AES.MODE_CBC)
mi = base64.b64decode(mi)
ming = aes.decrypt(mi)
ming = unpad(ming, 16)
print(ming.decode("utf-8"))
```
key通常是16位的字节
new创建一个密码器,AES的key有16位、24位、32位字节几种情况,我们在使用时不对了可以切换再试,一般网站上给出的key可能是16进制字符串(32)位,这种情况99%的可能是使用16字节的key,转换关系为每2个字符串对应于一个字节,使用binascii.a2b_hex(xxxx)

mode
ECB:不需要给IV
CBC:需要给一个16位的IV
总结:
加密:明文字符串-处理成字节-填充pad至16字节倍数-加密-密文(字节)-base64处理成16进制字符串-加密字符串
解密:倒过来,先用base64将字符串转为字节,再通过aes解密为字节,unpad成可识别的utf-8编码字节后decode
4.DES
和AES基本一样,区别的是加密的字节需要是8字节的倍数,区别就在pad和unpad的参数,DES是8
import base64
from Crypto.Cipher import DES
from Crypto.Util.Padding import pad, unpad
# 加密
# create a DES encryptor
des = DES.new(key=b'12345678', IV=b'12345678', mode=DES.MODE_CBC)
ming = "我爱你,宝贝"
ming = ming.encode()
print(ming)
ming = pad(ming, 8)
mi = des.encrypt(ming)
print(mi)
mi = base64.b64encode(mi).decode()
print(mi)
# 解密
des = DES.new(key=b'12345678', IV=b'12345678', mode=DES.MODE_CBC)
dmi = "mv8qg9CMzRDzwxmtMQh5zjmjgPo8PTxV"
dmi = base64.b64decode(dmi)
print('===', dmi)
dmi = des.decrypt(dmi)
print(dmi, len(dmi))
dmi = unpad(dmi, 8)
print(dmi, len(dmi))
dmi = dmi.decode()
print(dmi)实际案例:

全国招标公告公示搜索引擎-中国招标投标公共服务平台 (ctbpsp.com)
import base64
import json
import requests
session = requests.session()
session.headers = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.43"
}
url = "https://custominfo.cebpubservice.com/cutominfoapi/recommand/type/5/pagesize/10/currentpage/1"
resp = session.get(url=url)
# print(resp.text)
mi = resp.text.strip('"')
# 解密
from Crypto.Cipher import DES
from Crypto.Util.Padding import pad, unpad
key_str = "1qaz@wsx3e"
des = DES.new(key=key_str[:8].encode("utf-8"), mode=DES.MODE_ECB)
mi = base64.b64decode(mi)
ming = des.decrypt(mi)
ming = unpad(ming, 8)
s = ming.decode()
dic = json.loads(s)
print(dic)
# print(s)
5.非对称加密 RSA
非对称加密,加密和解密的密钥不一样,加密的是公钥,解密的是私钥,公钥和私钥是一对,在生成密钥的时候会同时生成,必须配合使用才行。rsa最为常用,可以说是一加独大,python中主要有两个库支持rsa,只需掌握一个。在前端js,rsa加密逻辑有两个:
- No Padding:这种方案不推荐直接用python搞,推荐用js库弄
- PKCS padding:python中只能搞这种
rsa两个特征:
65537010001(16进制,转为10进制就是65537)70%是noPading,建议使用js来做JSEncrypt js的一个第三方加密库,专门用来做rsa加密, PKCs,padding
publicKey一定是rsa加密,如果穿进去的是一个base64字样的东西,99%是PCKS padding
生成公钥he私钥的方式:
from Crypto.PublicKey import RSA # 这个RSA帮我们生成公钥和私钥
# 如何生成公钥和私钥,一定要一起生成,先生成私钥再生成公钥,默认导出的key都是pem格式
# 生成的key是私钥
key = RSA.generate(bits=1024, e=65537)
with open("private.pem", mode="wb") as f:
f.write(key.exportKey())
# 公钥是用私钥来生成
with open("public.pem", mode="wb") as f:
f.write(key.public_key().exportKey())
加密处理:
# 加密
import base64
from Crypto.Cipher import PKCS1_v1_5
from Crypto.PublicKey import RSA # 这个RSA帮我们生成公钥和私钥
# 明文
s = "这是一个测试"
# 明文转换成字节才能加密
ming_s = s.encode()
# 读取公钥
f = open("public.pem", mode="rb")
pub_key = RSA.importKey(f.read())
# 加密器
rsa = PKCS1_v1_5.new(pub_key)
# 加密完成生成的是字节
mi_bs = rsa.encrypt(ming_s)
print(mi_bs)
# 使用base64将字节转换为字符串
mi_s = base64.b64encode(mi_bs).decode()
print(mi_s)解密处理: