這是一篇介紹如何通過Python實作模擬登陸學校教務系統并爬取成績相關資訊(學期,課程名,總成績,課程性質,學分)然后繪制成績分布折線圖最后匯入MySQL資料庫中的文章
為了利用充分利用selenium的功能和成功爬取資料,需要有前置的html、css、簡單爬蟲的相關知識
說明:我學校的成績查詢頁面是通過加載js框架進而動態實時加載顯示表格及資料的,如果僅僅是用一般的爬蟲方法直接爬取頁面資訊,是不能成功的,因為那樣是直接獲取網頁原始碼,其中并沒有成績資料,當然,采用某些爬蟲方法肯定也能實作爬取js動態網頁,但是我為了簡單起見,直接用了selenium模擬登陸系統然后爬取資訊,
一、匯入主要模塊
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.keys import Keys
import matplotlib.pyplot as plt
import time
import pymysql
二、利用selenium模擬登陸教務系統
1.首先給出系統登陸頁面url和成績查詢頁面url(方便登陸成功后直接跳轉,省去了滑鼠點擊相關鏈接的操作)
# 給出所需的url
url_login_page = ("你學校的教務系統登錄頁面url")
url_cjcx=("成績查詢頁面url")
2.打開系統登錄頁面
# 啟動Chorme驅動,開始模擬(不能用靜默模式啟動)
option = webdriver.ChromeOptions()
# 不加載圖片,提高訪問速度
option.add_argument('blink-settings=imagesEnabled=false')
driver = webdriver.Chrome(chrome_options=option)
driver.maximize_window()
print("正在訪問......")
driver.get(url_login_page)
3.模擬輸入賬號密碼并點擊登陸按鈕
這里需要你自己用F12去查看自己學校系統登陸頁面的網頁元素然后找到賬號密碼輸入框、登錄按鈕的元素名稱(這里我通過find_element_by_id找到了所需的輸入框及按鈕)

# 自動輸入賬號密碼
driver.find_element_by_id("username").send_keys("你的學號")
driver.find_element_by_id("password").send_keys("你的密碼")
# 找到并點擊登錄按鈕,實作登錄
login_button = driver.find_element_by_id("login_submit")
actions = ActionChains(driver)
actions.key_down(Keys.CONTROL).click(login_button).key_up(Keys.CONTROL).perform()
三、爬取成績資訊
1.在新頁面打開成績查詢頁面
# 打開新的地址
driver.switch_to.window(driver.window_handles[-1])
driver.get(url_cjcx)
2.等待成績查詢頁面加載完畢
我學校的查詢頁面與學校資料庫對接較緩慢,所以我設定了10s等待時間,否則頁面加載不出來會報錯
# 等待頁面加載完畢
time.sleep(10)
3.找到“每頁顯示50條資料”的按鈕并點擊
這里我想點擊“每頁顯示50條資料”按鈕是因為這樣可以直接爬取所有資料而不需要點擊“下一頁”按鈕,同樣地,這里根據個人需要調整引數即可

# 找到每頁顯示數目選擇框并點擊"50"
driver.find_element_by_class_name("bh-pull-right.jqx-widget.jqx-dropdownlist-state-normal.jqx-rc-all.jqx-fill-state-normal").click()
time.sleep(0.5)
driver.find_element_by_xpath("//span[text()='50']").click()
# 等待頁面加載完畢
time.sleep(1)
4.爬取成績查詢頁面的資訊
這里采用的方法是先用driver.page_source+BeautifulSoup的方法獲取當前頁面的原始碼然后采用一般的爬蟲方法獲取相關資訊

# 準備爬取成績查詢頁面的資訊
data = driver.page_source
soup = BeautifulSoup(data, 'lxml')
trs = soup.find_all("tr")
total_container = []
for tr in trs:
row_container = []
for span in tr:
row_container.append(span.string)
total_container.append(row_container)
# 初始化score subjects串列
score = []
subjects = []
# 輸出最近兩學期成績資料
print("近兩學期所有科目成績如下:")
subject_num = int(len(total_container)/2)
for i in range(1,subject_num+1):
print(total_container[i-1][1], total_container[i-1][2], total_container[i-1][6], total_container[i-1][9], total_container[i-1][11])
subjects.append(total_container[i-1][2])
score.append(total_container[i-1][6])
print("\n原始成績:",score,"\n")
# 規范化成績
for i in range(1,subject_num+1):
if score[i-1] == '優秀' or score[i-1] =='621':
score[i-1] = 95
elif score[i-1] == '良好':
score[i-1] = 85
elif score[i-1] == '通過':
score[i-1] = 75
elif score[i-1] == None:
score[i-1] = 98
else:
score[i-1] = int(score[i-1])
print("科目:",subjects,"\n")
print("規范化后的成績:",score)
結果:

四、繪制成績分布統計圖
我們采用matplotlib.pyplot畫圖
# 繪圖
print("\n正在繪制成績分布折線圖...")
x = range(subject_num)
# plt.xticks(x,subjects) # 可以設定坐標字
plt.plot(x, score)
plt.xlabel("Subject(The xth)") #X軸標簽
plt.ylabel("Score") #Y軸標簽
plt.title('Score Distribution Chart')
plt.show()
結果:

五、將資料匯入MySQL
# 寫入MySQL
print("\n正在連接MySQL服務\n...")
# 創建與測驗資料庫的連接
conn = pymysql.connect(host='localhost',user="root",password="你的密碼",database="score_db")
# 輸出創建的連接物件的資訊
print("連接成功!\n連接物件的基本資訊如下:")
print (conn)
print (type(conn))
cursor = conn.cursor()
print("開始向資料表插入爬取的內容...")
sql1 = ("INSERT INTO score_table_test(學期,課程名,總成績,課程性質,學分) VALUES(%s,%s,%s,%s,%s)")
for i in range(1,subject_num+1):
# param中是實際的表格資料
param = (total_container[i-1][1], total_container[i-1][2], total_container[i-1][6], total_container[i-1][9], total_container[i-1][11])
cursor.execute(sql1, param)
conn.commit()
print("插入成功!")
# 清空表格內容
print("正在清空當前表格內容...")
sql2 = ("truncate table score_table_test")
cursor.execute(sql2)
conn.commit()
print("洗掉成功!")
# 關閉指標物件和連接物件
print("準備斷開資料庫連接....")
cursor.close()
conn.close()
print("已成功斷開連接!")
結果:

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/297584.html
標籤:python
