1. 程式人生 > >【4月20日】使用requests登陸教務處網站並查詢課表

【4月20日】使用requests登陸教務處網站並查詢課表

最近上課總是記不住是哪個教室,感覺每次都要人工登陸教務處網站去查教室很麻煩。正好在學習爬蟲,於是想直接寫個爬蟲去幫我查課表資訊豈不美哉?

說幹就幹。使用requests,個人感覺比較好用的第三方庫,基於py3;解析用beautifulsoup。開啟Chorme,登陸南理工的教務處網站並跟蹤登陸過程的網路行為。


可以看見,需要輸入的資訊有三樣。使用者名稱和密碼好辦,主要是驗證碼的及時識別。擬採取的策略為:下載驗證碼檔案到本地,然後再人工輸入。點選登陸,繼續跟蹤網路行為,發現在此輸入的資料(連同其他一些附帶資料)被post到了http://gsmis.njust.edu.cn/中。


進一步檢視這個post的FormData就可以找到這三個資料了,分別為UserName,PassWord以及ValidateCode。


找到了這裡已經解決了驗證碼走那條路(post)以及要到哪裡去(http://gsmis.njust.edu.cn/)的問題,接下來要解決從哪裡來的問題。在HTML上檢查驗證碼的元素,可以發現其src為Public/ValidateCode.aspx?image=一串無關緊要的數字。也就是說要在http://gsmis.njust.edu.cn/Public/ValidateCode.aspx?image=中拿到驗證碼檔案。這樣一來,驗證碼的來龍去脈就可以釐清了,從src中獲取驗證碼連結並下載到本地,再通過post將驗證碼及其他必要資訊傳送http://gsmis.njust.edu.cn/。


登陸之後,用相似的方式分析一下課表查詢時資料以及網路行為,就可以自動課表了(雖然課是真的少,但是事情是真的多啊~~~)。另外,我發現這個方法也很麻煩,還不如直接上網查呢。鄙視


下面,直接上程式碼:

# -*- coding: utf-8 -*-
"""
@author: Tree
"""

import requests
from bs4 import BeautifulSoup

# 登入地址,以及查詢課表的地址
LoginUrl = "http://gsmis.njust.edu.cn/UserLogin.aspx?exit=1"
class_url = "http://gsmis.njust.edu.cn/Gstudent/Course/StuCourseWeekQuery.aspx"
session = requests.session()

# 登入主函式
def login():
    headerdic = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36',
        'Host': 'gsmis.njust.edu.cn',
        'Referer': 'http://gsmis.njust.edu.cn/',
        'Accept': '*/*',
        'Connection': 'Keep-Alive',
    }

    postdic = {
        'UserName': "學號",
        'PassWord': "密碼",
        'drpLoginType': '1',
        '__ASYNCPOST': 'true',
        'ScriptManager1': 'UpdatePanel2|btLogin',
        '__EVENTTARGET': 'btLogin',
        '__VIEWSTATE': '/wEPDwULLTE5OTkyNTM4MzEPZBYCAgMPZBYGAg0PZBYCZg9kFgICAQ8PFgIeCEltYWdlVXJsBSp+L1B1YmxpYy9WYWxpZGF0ZUNvZGUuYXNweD9pbWFnZT02ODA3OTUyOTFkZAIRD2QWAmYPZBYCAgEPEGRkFgFmZAIVD2QWAmYPZBYCAgEPDxYCHgtOYXZpZ2F0ZVVybAUtfi9QdWJsaWMvRW1haWxHZXRQYXNzd2QuYXNweD9FSUQ9VHVyOHZadXVYa3M9ZGQYAQUeX19Db250cm9sc1JlcXVpcmVQb3N0QmFja0tleV9fFgEFDVZhbGlkYXRlSW1hZ2W5HJlvYqz666q9lGAspojpOWb4sA==',
        '__EVENTVALIDATION': '/wEdAAoKNGMKLh/WwBcPaLKBGC94R1LBKX1P1xh290RQyTesRQa+ROBMEf7egV772v+RsRJUvPovksJgUuQnp+WD/+4LQKymBEaZgVw9rfDiAaM1opWKhJheoUmouOqQCzlwTSNWlQTw3DcvmMLY3PAqFoA+uFSTy5ozCEG4XBxL/Ykep0cgC/Irwlr9d8VObb8MnYO0GRqRfbdgDIW2dtIsr6rbUIwej/LsqVAg3gLMpVY6UeARlz0=',
        '__EVENTARGUMENT': '',
        '__LASTFOCUS': ''
    }

    login_header = {
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
        'Accept-Encoding': 'gzip, deflate',
        'Accept-Language': 'zh-CN,zh;q=0.8',
        'Host': 'gsmis.njust.edu.cn',
        'Referer': 'http://gsmis.njust.edu.cn/UserLogin.aspx?exit=1',
        'Upgrade-Insecure-Requests': '1',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3067.6 Safari/537.36'
    }

    # 執行getCheckCode,將驗證碼資訊存入postdic中
    img_url = "http://gsmis.njust.edu.cn/Public/ValidateCode.aspx?image="
    postdic = getCheckCode(img_url, postdic, headerdic)

    # 獲取本週課表,使用get構造帶有引數的訪問
    eid = {'EID': 'j747VIAgTbv89k5pIqOcwJMucc!p3AXikfLcF!otxmBkw0iDLfKWdA=='}
    session.post("http://gsmis.njust.edu.cn/", data=postdic, headers=login_header)
    sclass = session.get(class_url, params=eid, headers=headerdic)
    soup = BeautifulSoup(sclass.text, "lxml")
    print("這周要上的課:")
    for i in range(len(soup.select('td[rowspan="4"]'))):
        print(soup.select('td[rowspan="4"]')[i].get_text())
    for i in range(len(soup.select('td[rowspan="2"]'))):
        print(soup.select('td[rowspan="2"]')[i].get_text())

# 獲取驗證碼並將其在本地儲存
def getCheckCode(url, postdic, headerdic):
    r = session.get(url, headers=headerdic)
    with open('captcha.jpg', 'wb') as f:
        f.write(r.content)
        f.close()
    captcha = input("please input the captcha\n>")
    postdic["ValidateCode"] = captcha
    return postdic

if __name__ == '__main__':
    login()