Python 实现大连海事校园网登录

        大连海事的校园网每次开机登录都需要手动输入密码,虽然浏览器有密码记忆功能,但还是免不了手动点击一下,本着自动化的原则,特分析其认证过程,通过Python代码实现一键登录。

        当然,已有同学对登录过程进行了研究,不过其实现方式是通过selenium的方式,需要调用浏览器实现自动登录,而本方法是通过提交post请求实现认证,速度有更多提升且对运行环境降低了要求。

        模拟登录的难点是认证需要经过多次重定向,且访问重定向网址带的cookie有所不同。在login步骤中,通过post提交的数据中密码加密方式是des加密,密钥在认证页面的源码能够找到,为base64格式,加密后的密码也为base64格式。

实现代码如下:

# -*- coding:utf-8 -*-

import requests
import re
from pyDes import des, PAD_PKCS5, ECB
import binascii
import time


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, padmode=PAD_PKCS5)
    return en  # 得到加密后的16位进制密码 <class 'bytes'>


def encrypt(pd='12345', key='aM51f8FuE/s='):
    """
    密码加密过程:
    1 从认证页面中可获得base64格式的秘钥
    2 将秘钥解码成bytes格式
    3 输入明文密码
    4 通过des加密明文密码
    5 返回base64编码格式的加密后密码
    :param pd: 明文密码
    :param key: 秘钥
    :return: 加密后的密码(base64格式)
    """
    key = binascii.a2b_base64(key.encode('utf-8'))  # 先解码 <class 'bytes'>
    pd_bytes = des_encrypt(pd, key)  # 得到加密后的16位进制密码 <class 'bytes'>
    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)

    # 提取认证链接并访问,经历一次重定向得到认证页面,且会返回一个session值
    url = re.search(r"href='(.*?)'</script>", resp.text).group(1)
    resp = session.get(url)

    # '''从认证页面正则得到 croypto(密钥 base64格式) 与 execution(post参数)的值 '''
    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)
    # 构建post数据 填入自己的学号 密码
    data = {
        'username': username,  # 学号
        'type': 'UsernamePassword',
        '_eventId': 'submit',
        'geolocation': '',
        'execution': execution,
        'captcha_code': '',
        'croypto': croypto,  # 密钥 base64格式
        'password': encrypt(password, croypto)  # 密码 经过des加密 base64格式
    }

    # 添加cookie值
    session.cookies.update({'isPortal': 'false'})

    # 提交数据,进行登录,这里禁止重定向,因为会有cookie限制
    url = 'https://id.dlmu.edu.cn/login'
    resp = session.post(url, data=data, allow_redirects=False)

    # 得到上一步返回的重定向网址,继续访问(需要清空cookie值)
    # 这里实际经过了三次重定向
    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)

只写了实现登录的过程,不过已经能够较快的实现登录了,另外大连海事的服务大厅认证过程和这个有很多相似,不过服务大厅的重定向更多,最终获得的cookie也更加的复杂。

  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值