How to Automate Course Registration on a Legacy University System with Python
Learn to automate course enrollment on outdated university portals by simulating login with Python, extracting session data, handling CAPTCHAs, constructing POST requests, and parsing responses, enabling fast, reliable class registration even when schedules conflict.
When university course selection times clash with personal schedules, a Python script can automate the registration process. The first step is to simulate login, preserve the session, and then perform the necessary actions.
Attempt Login
Open the university’s academic system in a browser, fill in any values, and submit the form. Use Chrome DevTools → Network to capture the request.
Filter out CSS and images; you will see a request to default.aspx.
If the system does not use cookies, the real request URL looks like:
http://110.65.10.xxx/(bdq1aj45lpd42o55vqpfgpie)/default2.aspxThe part inside the parentheses changes each time; it is a session identifier used by ASP.NET when cookies are disabled.
Get Session Information (No Cookie)
Use the requests library and spoof the User‑Agent header.
class Spider:
def __init__(self, url):
self.__uid = ''
self.__real_base_url = ''
self.__base_url = url
self.__headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36',
}
def __set_real_url(self):
request = requests.get(self.__base_url, headers=self.__headers)
real_url = request.url
self.__real_base_url = real_url[:len(real_url) - len('default2.aspx')]
return requestThe returned URL contains the session information; store it as your_ip/(bdq1aj45lpd42o55vqpfgpie)/ for later requests.
Get Session Information (Using Cookie)
If the system uses cookies, simply capture the cookie on the first GET request and reuse it:
def get_cookie():
request = requests.get('http://xxx.xxx.xxx.xxx') # example URL
cookie = request.cookies
return cookie
def use_cookie(cookie):
request = requests.get('http://xxx.xxx.xxx.xxx', cookies=cookie)For the school in this tutorial, the no‑cookie method is used.
CAPTCHA Handling
The login page includes a CAPTCHA image with src="CheckCode.aspx". Download it with requests and display it for manual input:
def __get_code(self):
request = requests.get(self.__real_base_url + 'CheckCode.aspx', headers=self.__headers)
with open('code.jpg', 'wb') as f:
f.write(request.content)
im = Image.open('code.jpg')
im.show()
code = input('Please input the code:')
return codeConstruct Login Data
Parse the login page to obtain the hidden __VIEWSTATE field using BeautifulSoup:
def __get_login_data(self, uid, password):
request = self.__set_real_url()
soup = BeautifulSoup(request.text, 'lxml')
__VIEWSTATE = soup.find('input', attrs={'name': '__VIEWSTATE'})['value']
code = self.__get_code()
data = {
'__VIEWSTATE': __VIEWSTATE,
'txtUserName': self.__uid,
'TextBox2': password,
'txtSecretCode': code,
'RadioButtonList1': '学生'.encode('gb2312'),
'Button1': '',
'lbLanguage': '',
'hidPdrs': '',
'hidsc': ''
}
return dataSubmit the login request and verify success by checking for the student’s name in the returned page:
def login(self, uid, password):
while True:
data = self.__get_login_data(uid, password)
request = requests.post(self.__real_base_url + 'default2.aspx', headers=self.__headers, data=data)
soup = BeautifulSoup(request.text, 'lxml')
try:
name_tag = soup.find(id='xhxm')
self.__name = name_tag.string[:len(name_tag.string)-2]
print('欢迎' + self.__name)
return True
except Exception:
print('Unknown Error, try to login again.')
time.sleep(0.5)
continueFetch Course Information
After logging in, request the public course selection page. Add a Referer header pointing to the current page. Encode the student name in gb2312 before sending.
def __enter_lessons_first(self):
data = {
'xh': self.__uid,
'xm': self.__name.encode('gb2312'),
'gnmkdm': 'N121103',
'TextBox1': '',
'dpkcmcGrid:txtChoosePage': '1',
'dpkcmcGrid:txtPageSize': '200',
# other hidden fields omitted for brevity
}
self.__headers['Referer'] = self.__real_base_url + 'xs_main.aspx?xh=' + self.__uid
request = requests.get(self.__real_base_url + 'xf_xsqxxxk.aspx', params=data, headers=self.__headers)
self.__headers['Referer'] = request.url
soup = BeautifulSoup(request.text, 'lxml')
self.__set__VIEWSTATE(soup)Parse Course List
Define a Lesson class to store course details, then extract each row from the course table:
class Lesson:
def __init__(self, name, code, teacher_name, time, number):
self.name = name
self.code = code
self.teacher_name = teacher_name
self.time = time
self.number = number
def __search_lessons(self, lesson_name=''):
self.__base_data['TextBox1'] = lesson_name.encode('gb2312')
request = requests.post(self.__headers['Referer'], data=self.__base_data, headers=self.__headers)
soup = BeautifulSoup(request.text, 'lxml')
self.__set__VIEWSTATE(soup)
return self.__get_lessons(soup)
def __get_lessons(self, soup):
lesson_list = []
lessons_tag = soup.find('table', id='kcmcGrid')
lesson_tag_list = lessons_tag.find_all('tr')[1:]
for lesson_tag in lesson_tag_list:
td_list = lesson_tag.find_all('td')
code = td_list[0].input['name']
name = td_list[1].string
teacher_name = td_list[3].string
time = td_list[4]['title']
number = td_list[10].string
lesson = Lesson(name, code, teacher_name, time, number)
lesson_list.append(lesson)
return lesson_listSelect Courses
For each desired lesson, set its hidden field to on and submit the form. Capture any JavaScript alert messages to inform the user about errors such as time conflicts.
def __select_lesson(self, lesson_list):
data = copy.deepcopy(self.__base_data)
data['Button1'] = ' 提交 '.encode('gb2312')
for lesson in lesson_list:
data[lesson.code] = 'on'
request = requests.post(self.__headers['Referer'], data=data, headers=self.__headers)
soup = BeautifulSoup(request.text, 'lxml')
self.__set__VIEWSTATE(soup)
error_tag = soup.html.head.script
if error_tag is not None:
error_text = error_tag.string
for msg in re.findall("alert\('(.+?)'\);", error_text):
print(msg)
# print already selected courses (omitted for brevity)Summary
The script completes the whole workflow: simulate login, maintain the session (with or without cookies), solve the CAPTCHA, retrieve hidden viewstate, fetch the list of available courses, and automatically submit selections. Because the legacy system uses simple ASP.NET session handling, the process is relatively straightforward, though adjustments may be required for different university deployments.
Author: 小苏打 Source: https://vhyz.me/2018/06/12/用Python实现模拟登录正方教务系统抢课/ GitHub: https://github.com/vhyz/ZF_Spider
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
MaGe Linux Operations
Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
