爬虫"/>
【Python爬虫
如果遇到问题可以留言,欢迎技术交流。交换意见
一,Python中运行JS代码
1-1 解决中文乱码或者报错问题
import subprocess
from functools import partial
subprocess.Popen = partial(subprocess.Popen, encoding='utf-8')
import execjs
1-2 常用函数
print(execjs.get().name) # 获取js代码执行环境res = execjs.eval(js) # 执行一段js代码#先编译
jj = execjspile(""" function an(a, b){return a + b }
""")
# call() 运行代码中的xxx函数. 后续的参数是xxx的参数
ret = jj.call("an", 10, 20)#读取js文件
f = open("01.js",mode="r",encoding="utf-8")
js_code = f.read()
# 执行js代码函数
js = execjspile(js_code)
js.call(函数)obj = repile(r"window\._INIT_STATE__ = (?P<code>.*?);",re.S) # 正则表达式
code = obj.search(js_code).group("code") #匹配正则表达式
print(type(code)) #这里的code是字符串# execjs这个库会把运行的结果自动转化成对象
result = execjs.eval(code)# 拿到的是一个JS代码运行的结果
print(result) #是个字典,Python会自动转换成字典
print(type(result)) # dictexecjs._exceptions.ProgramError: Error: Malformed UTF-8 data
js报错了,返回的数据两端有引号或者双引号,需要去掉
二,CryptoJS加密特征(逆向时)
function b(a, b) {var c = CryptoJS.enc.Utf8.parse(b), d = CryptoJS.enc.Utf8.parse("0102030405060708"), e = CryptoJS.enc.Utf8.parse(a), f = CryptoJS.AES.encrypt(e, c, {iv: d,mode: CryptoJS.mode.CBC});return f.toString()}#转换为UTF8
CryptoJS.enc.Utf8
# 转换为base64
CryptoJS.enc.Base64
三,md5加密解密
3-1 不加盐
from hashlib import md5obj = md5()
obj.update("alex".encode("utf-8"))
# obj.update("wusir".encode('utf-8')) # 可以添加多个被加密的内容bs = obj.hexdigest()
print(bs)
3-2 加盐
# 加盐
from hashlib import md5
salt = "我是盐.把我加进去就没人能破解了"obj = md5(salt.encode("utf-8")) # 加盐
obj.update("alex".encode("utf-8"))bs = obj.hexdigest()
print(bs)
3-3 傻系列加密
sha1,sha256,sha512用法跟md5一样
from hashlib import sha1, sha256
sha = sha256(b'salt')
sha.update(b'alex')
print(sha.hexdigest())
四,URLencode
from urllib.parse import quote, unquote, quote_plus, unquote_plus, urlencode# 单独编码字符串 用 quote
wq = "米饭怎么吃"
print(quote(wq)) # %E7%B1%B3%E9%A5%AD%E6%80%8E%E4%B9%88%E5%90%83
print(quote(wq, encoding="gbk")) # %C3%D7%B7%B9%D4%F5%C3%B4%B3%D4# 多个数据统一进行编码 用urlencode ,比如字典进行编码
dic = {"wq": "米饭怎么吃","new_wq": "想怎么吃就怎么吃"
}print(urlencode(dic)) # wq=%E7%B1%B3%E9%A5%AD%E6%80%8E%E4%B9%88%E5%90%83&new_wq=%E6%83%B3%E6%80%8E%E4%B9%88%E5%90%83%E5%B0%B1%E6%80%8E%E4%B9%88%E5%90%83
print(urlencode(dic, encoding="utf-8")) # 也可以指定字符集# 一个完整的url编码过程
base_url = "?"
params = {"wd": "大王"
}url = base_url + urlencode(params)
print(url) # =%E5%A4%A7%E7%8E%8B#解码
s = "=%E5%A4%A7%E7%8E%8B"
print(unquote(s)) # =大王print(quote("a /b/c=", safe="")) # 传递safe="" 可以保持和浏览器一致
print(quote_plus("a /b/c="))
五,base64
5-1 base64编码解码
import base64bs = "我要吃饭".encode("utf-8")
# 把字节转化成b64
print(base64.b64encode(bs).decode())# 把b64字符串转化成字节
s = "5oiR6KaB5ZCD6aWt"
print(base64.b64decode(s).decode("utf-8"))
5-2 base64解码时报错问题
#base64报错问题
import base64s = "ztKwrsTj0b0"
bb = base64.b64decode(s)
print(bb)此时运行出现以下问题
Traceback (most recent call last):File "D:/PycharmProjects/rrrr.py", line 33, in <module>bb = base64.b64decode(s)File "D:\Python38\lib\base64.py", line 87, in b64decodereturn binascii.a2b_base64(s)
binascii.Error: Incorrect padding# 解决办法s = "ztKwrsTj0b0"
s += ("=" * (4 - len(s) % 4))
print("填充后", s)
bb = base64.b64decode(s).decode("gbk")
print(bb)# 注意事项
由于标准的Base64编码后可能出现字符+和/,但是这两个字符在URL中就不能当做参数传递,所以就出现了Base64URL,下面是它们的区别:1. Base64编码后出现的+和/在Base64URL会分别替换为-和_
2. Base64编码中末尾出现的=符号用于补位,这个字符和queryString中的key=value键值对会发生冲突,所以在Base64URL中=符号会被省略,去掉=后怎么解码呢?因为Base64是把3个字节变为4个字节,所以,Base64编码的长度永远是4的倍数,因此,需要加上=把Base64字符串的长度变为4的倍数,就可以正常解码了。我们的应对方案:
在处理base64的时候.如果遇到了没有+和/的情况. 可以采用下面的方案来替换掉+和/
b64 = base64.b64decode(mi, b"-_")
六,AES加解密
6-1 AES加密
1-1 第一种
# AES加密
from Crypto.Cipher import AES
import base64
"""
长度16: *AES-128*24: *AES-192*32: *AES-256*MODE 加密模式.常见的 ECB 可以没有ivCBC 需要iv的
"""
# 创建加密器 注意秘钥和iv必须是16个字节
aes = AES.new( key= b"alexissbalexissb", mode=AES.MODE_CBC, iv=b"0102030405060708") # 分别是秘钥,模式,iv
data = "我吃饭了"# 加密的内容必须是字节,所以先进行编码
data_bs = data.encode("utf-8")# 需要加密的数据必须是16的倍数
# 填充规则: 缺少数据量的个数 * chr(缺少数据量个数)
pad_len = 16 - len(data_bs) % 16
data_bs += (pad_len * chr(pad_len)).encode("utf-8")
# 再对编码后的字节进行加密
bs = aes.encrypt(data_bs)
#用base64对结果进行编码
result = base64.b64encode(bs).decode()
1-2 第二种:
用pad对字节进行填充达到规定的长度
# AES加密
from Crypto.Cipher import AES
import base64
from Crypto.Util.Padding import pad
"""
长度16: *AES-128*24: *AES-192*32: *AES-256*MODE 加密模式.常见的 ECB 可以没有ivCBC 需要iv的
"""
# 创建加密器 注意秘钥和iv必须是16个字节
aes = AES.new( key= b"alexissbalexissb", mode=AES.MODE_CBC, iv=b"0102030405060708") # 分别是秘钥,模式,iv
data = "我吃饭了"# 加密的内容必须是字节,所以先进行编码
data_bs = data.encode("utf-8")# 需要加密的数据必须是16的倍数
# 用pad工具进行填充
data_bs = pad(data_bs,16)
# 再对编码后的字节进行加密
bs = aes.encrypt(data_bs)
#用base64对结果进行编码
result = base64.b64encode(bs).decode()
print(result)
1-3 加密结果转换为base64
# 转换成base64 bs是AES加密得到的字节
result = base64.b64encode(bs).decode()#转换成16进制
import binascii
res = binascii.b2a_hex(bs).decode()# 也可以转换成16进制,跟上面一个效果一样
bs.hex()
6-2 AES解密
from Crypto.Util.Padding import pad,unpad# base64编码后的密文
s = '9noPO0fcQizMbPkXcVOTDg=='
# 创建解密器
aes = AES.new(key= b"alexissbalexissb", mode=AES.MODE_CBC, iv=b"0102030405060708")
# 首先把base64编码转换成正常的字节
data = base64.b64decode(s)
res = aes.decrypt(data)
# 明文有可能有问题,因为字节是填充过得
# 用unpad 去除填充的内容,注:需要导入unpad
res = unpad(res,16)
# 得到明文
mingwen = res.decode("utf-8")
print(mingwen)
七,DES加密解密
7-1 DES加密
from Crypto.Cipher import DES
from Crypto.Util.Padding import pad,unpad
import base64
mingwen = '艾尼在学爬虫'# DES key 是 8个字节
# iv 在CBC 模式下使用 长度8个字节
des = DES.new(key=b'aininora', mode=DES.MODE_CBC,iv=b'ainiaini')# 明文进行编码
data = mingwen.encode('utf-8')
# 对编码后的字节进行填充
r = pad(data,8)
# 对填充后的字节进行des加密后的字节
res = des.encrypt(r)
# 对加密后的字节进行base64编码
base64_res = base64.b64encode(res).decode()
print(base64_res)
7-2 DES解密
from Crypto.Cipher import DES
from Crypto.Util.Padding import pad,unpad
import base64#base64密文
miwen = 't4TYyzRnIkmVmI81n+cdsVQfprHN5AtG'
#转换成base64字节
base64_byt = base64.b64decode(miwen)
# 创建解密器对象
des = DES.new(key=b'aininora', mode=DES.MODE_CBC,iv=b'ainiaini')
# 进行解密
r = des.decrypt(base64_byt)
# 得到的结果去掉填充部分
data = unpad(r,8)
# 对得到的字节进行解码
mingwen = data.decode('utf-8')
print(mingwen)
注:DES3 与AES,DES加密,解密规则一样,都是兄弟
注:js里的秘钥可以超过8位,js默认去前八位进行解密(JavaScript语言里)
八,RSA加解密
8-1 RSA加密特征(逆向时)
setMaxDigits,
RSAKeyPair,
encryptedString
8-2 RSA生成秘钥和公钥
#生成和处理秘钥的
from Crypto.PublicKey import RSA
# 加密和解密
from Crypto.Cipher import PKCS1_v1_5import base64# 生成私钥
#bits = 2048 是秘钥的长度
rsa_key = RSA.generate(bits=2048)
# 把秘钥导出来
# 秘钥的本质是字节# export_key 有个参数叫format,默认为PEM,背后的含义是把秘钥转换成了base64
key = rsa_key.export_key().decode()with open('./rsa_miyao.pem',mode='w',encoding='utf-8') as f:f.write(key)# 把format换成DER,拿到的是字节
# key = rsa_key.export_key(format='DER')# 把字节手动转换成base64
# result = base64.b64encode(key).decode()#生成公钥
public_key = rsa_key.public_key()
# 把公钥导出来
p_key = public_key.export_key()with open('./rsa_gongyao.pem',mode='wb') as f:f.write(p_key)
8-3 RSA加密
3-1 第一种
#加密解密
from Crypto.Cipher import PKCS1_v1_5
#加载key
from Crypto.PublicKey import RSAimport base64# 导入的key可以是PEM格式的秘钥,或者是直接形式的秘钥也可以
# 读取秘钥
f = open('./rsa_gongyao.pem',mode='r',encoding='utf-8')
# 拿到已经生成好的秘钥
pub_key = f.read()
f.close()mingwen = "我要好好学习爬虫"rsa_key = RSA.importKey(pub_key)
# 生成加密对象
rsa = PKCS1_v1_5.new(key=rsa_key)
# 对明文进行编码,处理成字节
mingwen_bs = mingwen.encode('utf-8')
# 对明文字节进行加密,得到密文字节
mi_bs = rsa.encrypt(mingwen_bs)
# 转换成base64
base_64 = base64.b64encode(mi_bs).decode()
#rsa每次加密后的结果可能不一样
print(base_64)# 如果用了没有填充的算法,那每一次算出来的结果固定的
# 如果同一个明文反复计算结果是一样的那么考虑用js来完成逆向工作
3-2 第二种
// JSEncrypt
// setPublicKey// 用的是固定的第三方库,库的名字叫jsencrypt
// 但是这个库只能在浏览器环境使用
// 我们用的是Node环境,所以不能直接是哟和// 我们需要换一个库, 名字叫 node-jsencrypt
// 安装 npm install node-jsencryptvar {JSEncrypto} = require('node-jsencrypt')
var o = new JSEncrypt
o.setPublicKey('xxxxxxxxxxxxxxxxxxxxxxxx')
r = o.encrypt("加密的内容")// 可以直接把网站的内容拿过来
8-4 RSA解密
4-1 第一特征
1,如果用了没有填充的算法,那每一次算出来的结果固定的
2,如果同一个明文反复计算结果是一样的那么考虑用js来完成逆向工作
// 特征:
// "010001" -> 这是16进制 -> 65537
// setMaxDigits
// RSAKeyPair
// encryptedStringconst {setMaxDigits,RSAKeyPair,encryptedString
} = require("./Ras加密");function c(a,b,c){var d,e;return setMaxDigits(131),d = new RSAKeyPair(b,"",c),e = encryptedString(d,a)
}
注:./RSA加密 这个文件内容过长,如果需要请留言,我单独分享
例如:网易云案例
const CryptoJS = require("crypto-js")
var window = thisconst {setMaxDigits,RSAKeyPair,encryptedString
} = require("./Ras加密");
!function() {function a(a) {var d, e, b = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", c = "";for (d = 0; a > d; d += 1)e = Math.random() * b.length,e = Math.floor(e),c += b.charAt(e);return c}function b(a, b) {var c = CryptoJS.enc.Utf8.parse(b), d = CryptoJS.enc.Utf8.parse("0102030405060708"), e = CryptoJS.enc.Utf8.parse(a), f = CryptoJS.AES.encrypt(e, c, {iv: d,mode: CryptoJS.mode.CBC});return f.toString()}function c(a, b, c) {var d, e;return setMaxDigits(131),d = new RSAKeyPair(b,"",c),e = encryptedString(d, a)}function d(d, e, f, g) {var h = {}, i = a(16);return h.encText = b(d, g),h.encText = b(h.encText, i),h.encSecKey = c(i, e, f),h}function e(a, b, d, e) {var f = {};return f.encText = c(a + e, b, d),f}window.asrsea = d,window.ecnonasr = e
}();var params = {csrf_token: "",encodeType: "aac",ids: "[1325905146]",level: "standard"}var second = '010001'var third = '00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7'var forth = '0CoJUm6Qyw8W8jud'function fn(params) {return window.asrsea(JSON.stringify(params),second,third,forth)
4-2 RSA普通解密
#加密解密
from Crypto.Cipher import PKCS1_v1_5
#加载key
from Crypto.PublicKey import RSAimport base64f = open('./rsa_miyao.pem',mode='r',encoding='utf-8')
# 拿到已经生成好的秘钥
pri_key = f.read()
f.close()
# 拿到秘钥
rsakey = RSA.importKey(pri_key)
# 生成解密器对象
rsa = PKCS1_v1_5.new(key=rsakey)
miwen = 'mmf28CJEtFU2Y6C/qx10xoaRmsiY2at3LBjHR5DFdnG9V+5sGPFaMGDGM4OBVWKKJNuSFZgGL9Y409mbh32IKRL4TZYnc0RvJH/0t38d7AmnqnHAyTRUvpKlPzzJg559md6BcTA/ZpYZ4WAtXRuysMvuPTdlRvog2ceGJDXURajU3KyzHXFA9Hc+AamVL75D+YKrOB6n9YeV7n4+DK5mqouNlLp6Plee39vYBzN0IKkzyD6RatmVVUIxJCsUJmeJgIdnBGEuRA9bGNOG3VQa7NF/syWjiRNbKYz+KZHx+RtQ9GuzmPhtJbjh8anPeR2kzNwgfD1HiKhIBDQKVQH/eA=='
#对密文进行base64解码转换成字节
base64_2bs = base64.b64decode(miwen)
#对拿到的字节进行rsa解密得到明文字节
# 解密第二个参数给个None,意思是解密时出错了返回None
mingwen_bs = rsa.decrypt(base64_2bs,None)
#对明文字节进行解码得到明文
mingwen = mingwen_bs.decode('utf-8')
print(mingwen)
如果遇到问题可以留言,欢迎技术交流。交换意见
更多推荐
【Python爬虫
发布评论