《Python爬虫模拟登陆教务处并且保存数据到本地》
一、引言
在高校信息化建设中,教务系统作为核心管理平台,存储着学生成绩、课程安排、考试信息等关键数据。然而,部分教务系统因安全考虑未提供开放API接口,导致数据获取需依赖手动操作。本文将通过Python爬虫技术,模拟用户登录教务处系统,自动抓取所需数据并保存至本地,为后续数据分析或自动化处理提供基础。
二、技术准备
1. 核心库依赖
需安装以下Python库:
pip install requests beautifulsoup4 lxml pandas
requests:处理HTTP请求
BeautifulSoup4:解析HTML文档
lxml:提升解析效率
pandas:数据存储与处理
2. 开发环境配置
建议使用Python 3.8+版本,配合Jupyter Notebook或PyCharm开发工具。需确保网络环境可访问目标教务系统。
三、登录流程分析
1. 登录机制识别
通过浏览器开发者工具(F12)分析登录请求:
- Network选项卡捕获POST请求
- 查看Form Data或Request Payload
- 识别加密参数(如token、rsa加密等)
2. 常见验证方式
(1)表单提交型
直接提交用户名密码到/login接口:
{
"username": "20230001",
"password": "123456",
"captcha": "A7b9"
}
(2)Cookie验证型
需先获取会话Cookie:
session = requests.Session()
session.get("http://jw.xxx.edu.cn/login")
# 从响应中提取关键Cookie
(3)加密参数型
使用JavaScript动态生成加密参数:
# 示例:模拟某高校RSA加密
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
def rsa_encrypt(password, public_key):
rsa_key = RSA.import_key(public_key)
cipher = PKCS1_OAEP.new(rsa_key)
return cipher.encrypt(password.encode())
四、完整实现示例
以某高校教务系统为例,实现步骤如下:
1. 获取初始页面
import requests
from bs4 import BeautifulSoup
base_url = "http://jw.xxx.edu.cn"
login_url = f"{base_url}/login"
session = requests.Session()
response = session.get(login_url)
soup = BeautifulSoup(response.text, 'lxml')
# 提取隐藏表单字段(如lt、execution等)
lt = soup.find('input', {'name': 'lt'})['value']
execution = soup.find('input', {'name': 'execution'})['value']
2. 处理验证码
(1)显示型验证码
from PIL import Image
import io
captcha_url = f"{base_url}/captcha.jpg"
captcha_response = session.get(captcha_url)
img = Image.open(io.BytesIO(captcha_response.content))
img.show() # 手动输入验证码
captcha = input("请输入验证码:")
(2)计算型验证码(如滑块)
需使用Selenium模拟鼠标操作:
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Chrome()
driver.get(login_url)
# 定位滑块元素
slider = driver.find_element_by_id("slider")
action = ActionChains(driver)
action.click_and_hold(slider).perform()
action.move_by_offset(200, 0).perform() # 模拟滑动距离
action.release().perform()
3. 提交登录请求
login_data = {
"username": "20230001",
"password": "encrypted_password",
"lt": lt,
"execution": execution,
"_eventId": "submit",
"captcha": captcha
}
headers = {
"User-Agent": "Mozilla/5.0",
"Referer": login_url
}
login_response = session.post(login_url, data=login_data, headers=headers)
if login_response.url.endswith("/main"):
print("登录成功")
else:
print("登录失败:", login_response.text)
4. 数据抓取与存储
(1)成绩查询示例
score_url = f"{base_url}/student/score"
score_response = session.get(score_url)
score_soup = BeautifulSoup(score_response.text, 'lxml')
# 解析表格数据
scores = []
table = score_soup.find('table', {'class': 'datelist'})
for row in table.find_all('tr')[1:]: # 跳过表头
cols = row.find_all('td')
scores.append({
'course': cols[0].text.strip(),
'credit': cols[1].text.strip(),
'score': cols[2].text.strip()
})
(2)保存为CSV文件
import pandas as pd
df = pd.DataFrame(scores)
df.to_csv('student_scores.csv', index=False, encoding='utf-8-sig')
print("数据已保存至student_scores.csv")
五、反爬策略应对
1. 常见反爬机制
- IP限制:单IP请求频率过高
- Cookie验证:缺失关键会话信息
- JavaScript渲染:动态加载内容
- 行为分析:鼠标轨迹、点击频率
2. 解决方案
(1)IP代理池
proxies = {
'http': 'http://123.123.123.123:8080',
'https': 'https://123.123.123.123:8080'
}
response = session.get(url, proxies=proxies)
(2)请求头伪装
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"Accept": "text/html,application/xhtml+xml",
"Accept-Language": "zh-CN,zh;q=0.9",
"Connection": "keep-alive"
}
(3)Selenium无头模式
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument('--headless')
options.add_argument('--disable-gpu')
driver = webdriver.Chrome(options=options)
六、法律与伦理考量
1. 遵守robots协议
检查目标网站的/robots.txt文件,禁止爬取的路径不应访问:
User-agent: *
Disallow: /admin/
Disallow: /private/
2. 合理使用条款
- 仅用于个人学习研究
- 控制请求频率(建议间隔3-5秒)
- 不存储敏感个人信息
- 不进行商业用途
3. 数据脱敏处理
# 示例:隐藏学号中间四位
def desensitize_id(student_id):
return student_id[:4] + "****" + student_id[-4:]
七、完整代码示例
import requests
from bs4 import BeautifulSoup
import pandas as pd
import time
import random
class JWSystemCrawler:
def __init__(self):
self.base_url = "http://jw.xxx.edu.cn"
self.session = requests.Session()
self.headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"Referer": self.base_url
}
def get_login_params(self):
response = self.session.get(f"{self.base_url}/login")
soup = BeautifulSoup(response.text, 'lxml')
return {
'lt': soup.find('input', {'name': 'lt'})['value'],
'execution': soup.find('input', {'name': 'execution'})['value']
}
def login(self, username, password, captcha):
params = self.get_login_params()
data = {
"username": username,
"password": password,
"lt": params['lt'],
"execution": params['execution'],
"_eventId": "submit",
"captcha": captcha
}
response = self.session.post(
f"{self.base_url}/login",
data=data,
headers=self.headers
)
return response.url.endswith("/main")
def get_scores(self):
response = self.session.get(f"{self.base_url}/student/score")
soup = BeautifulSoup(response.text, 'lxml')
scores = []
table = soup.find('table', {'class': 'datelist'})
for row in table.find_all('tr')[1:]:
cols = row.find_all('td')
scores.append({
'course': cols[0].text.strip(),
'credit': cols[1].text.strip(),
'score': cols[2].text.strip()
})
return scores
def save_to_csv(self, data, filename):
df = pd.DataFrame(data)
df.to_csv(filename, index=False, encoding='utf-8-sig')
def run(self, username, password):
captcha = input("请输入验证码:")
if not self.login(username, password, captcha):
print("登录失败")
return
print("登录成功,正在获取数据...")
time.sleep(random.uniform(1, 3)) # 随机延迟
scores = self.get_scores()
self.save_to_csv(scores, "student_scores.csv")
print("数据保存完成")
if __name__ == "__main__":
crawler = JWSystemCrawler()
crawler.run("20230001", "your_password")
八、总结与展望
本文通过完整的Python爬虫实现,展示了模拟登录教务系统的技术流程。关键点包括:
- 动态参数提取与加密处理
- 多类型验证码应对策略
- 反爬机制的有效规避
- 数据存储的规范化处理
未来可扩展方向:
- 集成自动化测试框架
- 开发图形化操作界面
- 实现多账号批量处理
- 对接数据库存储方案
关键词:Python爬虫、教务系统、模拟登录、数据抓取、反爬策略、Requests库、BeautifulSoup、Selenium、数据存储
简介:本文详细介绍了使用Python爬虫技术模拟登录高校教务系统的方法,涵盖登录机制分析、验证码处理、数据抓取与存储等关键环节,提供了完整的代码实现和反爬策略解决方案,同时强调了合法合规的使用原则。