今天打开电脑发现之前的登陆脚本挂了,重启也没用,尝试根据报错修改xpath,还是无法定位元素,又重试了其他方法,发现还是无法定位到元素(其实最开始用xpath就是因为其他方法定位失败了),而很巧的是在昨天我的评论区出现了一个老哥给我发了他的方法:Python 实现大连海事校园网登录。
我测试了一下发现确实好用。仔细阅读了一下代码,发现老哥的功底确实好,好几处我认为可以优化或者需要修改的地方在我改完之后都不能用了。仔细研究了原理之后发现我的理解是错的,原本的代码就是最简洁的写法。
import binascii
import re
import time
import requests
from pyDes import ECB, PAD_PKCS5, des
def des_encrypt(s, key):
"""
DES 加密
:param key: 秘钥
:param s: 原始字符串
:return: 加密后字符串,16进制
"""
secret_key = key
k = des(secret_key, mode=ECB, pad=None, padmode=PAD_PKCS5)
en = k.encrypt(s)
return en
def encrypt(pd, key):
"""
密码加密过程:
1 从认证页面中可获得base64格式的秘钥
2 将秘钥解码成bytes格式
3 输入明文密码
4 通过des加密明文密码
5 返回base64编码格式的加密后密码
:param pd: 明文密码
:param key: 秘钥
:return: 加密后的密码(base64格式)
"""
key = binascii.a2b_base64(key.encode('utf-8'))
pd_bytes = des_encrypt(pd, key)
pd_base64 = binascii.b2a_base64(pd_bytes, newline=False).decode('utf-8')
return pd_base64
def login(username, password):
start_time = time.process_time()
session = requests.session()
headers = {
'Connection': 'keep-alive',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,'
'application/signed-exchange;v=b3;q=0.9',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/95.0.4638.69 Safari/537.36',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Content-Type': 'application/x-www-form-urlencoded'
}
session.headers = headers
url = 'http://bilibili.com/'
resp = session.get(url, verify=False)
url = re.search(r"href='(.*?)'</script>", resp.text).group(1)
resp = session.get(url)
croypto = re.search(r'"login-croypto">(.*?)<', resp.text, re.S).group(1)
execution = re.search(r'"login-page-flowkey">(.*?)<', resp.text, re.S).group(1)
data = {
'username': username,
'type': 'UsernamePassword',
'_eventId': 'submit',
'geolocation': '',
'execution': execution,
'captcha_code': '',
'croypto': croypto,
'password': encrypt(password, croypto)
}
session.cookies.update({'isPortal': 'false'})
url = 'https://id.dlmu.edu.cn/login'
resp = session.post(url, data=data, allow_redirects=False)
url = resp.headers['Location']
session.cookies.clear()
resp = session.get(url)
end_time = time.process_time()
print(end_time - start_time)
if resp.status_code == 200:
print('成功登录')
if __name__ == '__main__':
username = ''
password = ''
login(username, password)
有几点是值得提一下的: 1.des_encrypt和encrypt当中的函数方法的返回值的类型是非常值得注意的,因为对于bytes和string两种数据类型方法是不同的。而数据处理过程中也并不是所有的数据都能转换为string,因为密钥原本就不是可打印字符,而是使用了base64变成了可打印字符。 2.自定义的encrypt方法和des实例里的encrypt方法重名了,但其实不是一个方法,调用的形式也不一样。阅读代码时注意区分即可。 3.原文代码当中自定义的encrypt方法中形参有默认值,估计是测试用的,我删除了。 4.今天下午仔细研读了老哥的代码,发现没有可以优化的地方了,但是我的水平也有限,如果有优化建议可以到原文留言区留言,也非常欢迎跟我讨论。
开机自启
可以将代码的快捷方式复制到开机自启文件夹,win+r,输入shell:startup即可打开。
|