Python模拟登录上海西南某高校校园网 (jaccount)

Posted 黑冰5

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python模拟登录上海西南某高校校园网 (jaccount)相关的知识,希望对你有一定的参考价值。

好久没写东西了,最近学习了一下模拟登录,以校园网为例,作一记录。

去年的时候写过一篇模拟登录的文章,用的是登录后的cookies,这种操作比较傻瓜,也不智能,不够自动化,本质还是手动登录。
这次我尝试把登录过程用python进行,预先提供账号、密码即可。

众所周知(本校兄弟姐妹),本校所有身份认证现已完全由jaccount进行,只要通过了这一层验证,就相当于登录成功了。

以登录校园邮箱为例,先分析一下登录流程:

  1. 输入邮箱网址mail....edu.cn
  2. 跳转到jaccount验证页
  3. 输入账号、密码、验证码登录
  4. 跳转回邮箱页面,登录完成

难点分析:

  1. 跳转过程中有哪些数据需要携带?
  2. 验证码如何获取?如何识别?

刚开始想用requests解决所有问题,直到试了许多次也未能成功解决登录跳转的问题,只好放弃,转用更简单的selenium。selenium是一款可见即可得的自动化测试工具,在爬虫上用起来十分方便,它通过模拟人实际的操作实现对浏览器的控制,比如输入、点击、拖动等事件。

依次按照上述流程,进行编码(完整代码见文末):

步骤一、打开浏览器,输入邮箱网址

browser.get(\'https://mail.sjtu.edu.cn\')

此时,会弹出浏览器,自动打开该网页,当然,也会自动跳转到jaccount验证页面。

步骤二、输入账号、密码、验证码

账号、密码都比较好搞定,自己预设好就行了。然后通过开发者工具定位文本框位置,由以下命令可以输入到相应的文本框内。

input_user = browser.find_element_by_id(\'user\')
input_user.send_keys(user)
input_pass = browser.find_element_by_id(\'pass\')
input_pass.send_keys(pswd)

麻烦的还是验证码。首先要找到验证码图片源,再通过OCR工具进行识别。
通过分析,发现验证码是由https://jaccount.sjtu.edu.cn/jaccount/captcha这个站点生成的。要获取到正确的验证码,需要传入相应的uuid参数,以及cookies。OCR工具目前比较好用的是tesseract,所幸我们这个验证码比较简单,识别率很高。

通过对源码进行搜索,终于找到uuid了,就在这个登录表单里,通过xpath获取一下,拿到value

uuid = browser.find_element_by_xpath(\'//form/input[@name="uuid"]\')
params = {
    \'uuid\': uuid.get_attribute(\'value\')
}

此处为了便捷,我使用requests进行验证码下载,而selenium的cookies也和requests不同,selenium是比较完整的信息,如下:

[{\'domain\': \'mail.sjtu.edu.cn\', \'httpOnly\': True, \'name\': \'JSESSIONID\', \'path\': \'/\', \'secure\': False, \'value\': \'12l9qesot3vw61sz8brl8i74ir\'}, {\'domain\': \'mail.sjtu.edu.cn\', \'httpOnly\': True, \'name\': \'ZM_AUTH_TOKEN\', \'path\': \'/\', \'secure\': False, \'value\': \'0_7b1bfd5665cabda2816d04d7e4f8438022c54538_69643d33363a35373935373238652d346539362d346434372d383837332d6331666264356130343337643b6578703d31333a313536393836323130303632323b747970653d363a7a696d6272613b753d313a613b7469643d31303a323134323231343838363b76657273696f6e3d31333a382e382e395f47415f333031393b\'}, {\'domain\': \'.sjtu.edu.cn\', \'expiry\': 1569818955, \'httpOnly\': False, \'name\': \'_gat\', \'path\': \'/\', \'secure\': False, \'value\': \'1\'}, {\'domain\': \'.sjtu.edu.cn\', \'expiry\': 1569905295, \'httpOnly\': False, \'name\': \'_gid\', \'path\': \'/\', \'secure\': False, \'value\': \'GA1.3.452166840.1569818896\'}, {\'domain\': \'.sjtu.edu.cn\', \'expiry\': 1632890895, \'httpOnly\': False, \'name\': \'_ga\', \'path\': \'/\', \'secure\': False, \'value\': \'GA1.3.1066557857.1569818896\'}]

而我们传入requests的只需要cookie名字和值即可,故可通过字典推导式,生成requests所需的cookies:

cookies = browser.get_cookies()
cookies = {i["name"]: i["value"] for i in cookies}

这样一来就可以获取验证码了,

response = requests.get(captcha_url, cookies=cookies, params=params)
with open(\'img.jpeg\', \'wb+\') as f:
    f.writelines(response)

这样验证码就被保存到img.jpeg文件中,识别验证码只需要以下两行代码即可:

image = Image.open(\'img.jpeg\')
code = pytesseract.image_to_string(image)

最后,输入验证码,并确定,就可以跳转回登录后的邮箱界面。

input_code = browser.find_element_by_id(\'captcha\')
input_code.send_keys(code)
input_code.send_keys(Keys.ENTER)

如果你用的是可视化浏览器,这时候就可以看到自己的邮箱了。
可以再看看当前的url,是不是已经跳转回邮箱的url了呢?

print(browser.current_url)

成功登录之后,要爬取什么东西都很简单了,比如课程表、好大学在线的课件等等~

完整代码

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import requests
import pytesseract
from PIL import Image

browser = webdriver.Chrome()

url = "https://mail.sjtu.edu.cn/"
captcha_url = "https://jaccount.sjtu.edu.cn/jaccount/captcha"
user = \'ben\'
pswd = \'********\'


def get_captcha(captcha_url, cookies, params):
    response = requests.get(captcha_url, cookies=cookies, params=params)
    with open(\'img.jpeg\', \'wb+\') as f:
        f.writelines(response)

try:
    browser.get(url)
    cookies = browser.get_cookies()
    cookies = {i["name"]: i["value"] for i in cookies}
    uuid = browser.find_element_by_xpath(\'//form/input[@name="uuid"]\')
    params = {
        \'uuid\': uuid.get_attribute(\'value\')
    }
    get_captcha(captcha_url, cookies, params)
    image = Image.open(\'img.jpeg\')
    code = pytesseract.image_to_string(image)
    print(code)
    input_user = browser.find_element_by_id(\'user\')
    input_user.send_keys(user)
    input_pass = browser.find_element_by_id(\'pass\')
    input_pass.send_keys(pswd)
    input_code = browser.find_element_by_id(\'captcha\')
    input_code.send_keys(code)
    input_code.send_keys(Keys.ENTER)
    print(browser.current_url)
finally:
    print(\'success!\')

以上是关于Python模拟登录上海西南某高校校园网 (jaccount)的主要内容,如果未能解决你的问题,请参考以下文章

Natural Language Processing with Python - Chapter 0

华为 1+X《网络系统建设与运维(中级)》认证 模拟实验上机试题及其答案全解析

python爬虫 模拟登陆校园网-初级

Go语言进校园 · 西南交大站活动回顾

全国高校python网络爬虫与文本挖掘技术培训(上海)

校区智慧化建造——造就校园的神经网络