作者:7777-丿M | 来源:互联网 | 2024-11-29 16:42
本文旨在指导读者如何利用Python编程技术,实现对学校教务系统的成绩数据抓取、分析及存储。具体来说,我们将通过模拟登录的方式,从教务系统中抓取成绩信息,包括学期、课程名称、总成绩、课程性质和学分等关键数据,接着使用Matplotlib库绘制成绩分布图,并将这些数据导入MySQL数据库中进行持久化存储。
一、准备工作
在开始之前,确保你已经安装了必要的Python库,如Selenium、BeautifulSoup、Matplotlib和PyMySQL。此外,了解基本的HTML、CSS和Javascript知识对于调试和理解代码逻辑非常有帮助。
二、模拟登录教务系统
1. 首先,定义教务系统的登录页面URL和成绩查询页面URL。
# 定义URL
url_login = '你学校的教务系统登录页面URL'
url_score_query = '成绩查询页面URL'
2. 使用Selenium打开Chrome浏览器,设置不加载图片以加快页面加载速度,并最大化窗口。
# 设置Chrome选项
optiOns= webdriver.ChromeOptions()
options.add_argument('blink-settings=imagesEnabled=false')
driver = webdriver.Chrome(optiOns=options)
driver.maximize_window()
print("正在访问登录页面...")
driver.get(url_login)
3. 模拟输入用户名和密码,点击登录按钮完成登录操作。
# 输入用户名和密码
driver.find_element_by_id('username').send_keys('你的学号')
driver.find_element_by_id('password').send_keys('你的密码')
# 点击登录按钮
login_btn = driver.find_element_by_id('login_btn')
login_btn.click()
三、抓取成绩信息
1. 登录成功后,切换到成绩查询页面。
# 跳转到成绩查询页面
driver.get(url_score_query)
2. 由于成绩查询页面可能加载较慢,设置适当的等待时间以确保页面完全加载。
# 等待页面加载
time.sleep(10)
3. 选择每页显示50条记录,以便一次性抓取所有成绩数据。
# 选择每页显示50条记录
driver.find_element_by_class_name('bh-pull-right.jqx-widget').click()
time.sleep(0.5)
driver.find_element_by_xpath('//span[text()="50"]').click()
time.sleep(1)
4. 使用BeautifulSoup解析页面源码,提取成绩数据。
# 解析页面源码
html = driver.page_source
soup = BeautifulSoup(html, 'lxml')
trs = soup.find_all('tr')
# 存储成绩数据
scores = []
subjects = []
for tr in trs:
row = [td.text.strip() for td in tr.find_all('td')]
if len(row) > 1:
scores.append(row[5]) # 假设成绩在第6列
subjects.append(row[1]) # 假设科目名称在第2列
四、绘制成绩分布图
使用Matplotlib绘制成绩分布图,直观展示成绩情况。
# 绘制成绩分布图
plt.plot(range(len(scores)), scores)
plt.xlabel('科目编号')
plt.ylabel('成绩')
plt.title('成绩分布图')
plt.show()
五、将数据存储到MySQL数据库
最后,将抓取的成绩数据存储到MySQL数据库中,以便后续查询和分析。
# 连接MySQL数据库
cOnn= pymysql.connect(host='localhost', user='root', password='你的密码', database='score_db')
cursor = conn.cursor()
print("数据库连接成功!")
# 插入数据
insert_sql = "INSERT INTO scores (semester, subject, score, nature, credit) VALUES (%s, %s, %s, %s, %s)"
for i in range(len(scores)):
data = (trs[i+1].find_all('td')[0].text, trs[i+1].find_all('td')[1].text, scores[i], trs[i+1].find_all('td')[8].text, trs[i+1].find_all('td')[10].text)
cursor.execute(insert_sql, data)
conn.commit()
print("数据插入成功!")
# 关闭数据库连接
cursor.close()
conn.close()
print("数据库连接已关闭!")