? 前幾天聽到朋友說自己選課事情,突發奇想想要搞這樣一個東西,但是由于各種原因只做到以下的完成度,具體的情況也會在解釋的最后留下。這個只適用于曲師大的教務系統,因為用的這個系統來進行的一個調試,對于其他的系統,思路都是一樣的,代碼也只適用于學習,請不要用以其他用途!代碼放在最后。
在金湖等地區,都構建了全面的區域性戰略布局,加強發展的系統性、市場前瞻性、產品創新能力,以專注、極致的服務理念,為客戶提供成都網站設計、成都網站制作 網站設計制作按需定制開發,公司網站建設,企業網站建設,成都品牌網站建設,成都營銷網站建設,成都外貿網站建設,金湖網站建設費用合理。
? 對于想要做到的這個需求呢,我選擇的是python + selenium庫進行一個瀏覽器自動化操作,在寫的過程中因為發現了一個驗證碼的問題所以又用到了一個ddddocr庫,如果想要定時操作的話再加上一個time庫。之后就是理清操作的順序就好了,想到于人工操作一遍的過程。
大的一個方向、思路就是上面這四步,具體的細化之后再談及。
? 這一步就很簡單,直接用selenium庫打開chormedriver就好了
self.driver = webdriver.Chrome()
self.driver.maximize_window() # 最大化
? 這一步就是登錄,要完成的就是把賬號,密碼輸入對應的框,然后輸入驗證碼,點擊登錄。
? 首先把賬號密碼輸入到框里很簡單
self.driver.find_element(By.ID, 'userAccount').send_keys(self.user_account)
self.driver.find_element(By.ID, 'userPassword').send_keys(self.user_password)
? 直接調用selenium庫中的函數就可以進行該操作
? 接下來是這一步驟的一個問題,就是如何過驗證碼,因為該系統的驗證碼圖片并不復雜,我想到的一個解決措施就是把驗證碼截圖,然后識別圖片上的信息,然后重復上述操作就好了。
? 如何截圖,我首先想到的是指定位置然后用某個庫截圖或者是打開圖片的鏈接保存圖片,后來發現每次點開鏈接圖片都是不一樣的(應該是JS的原因),最后發現原來selenium庫自帶一個元素截圖的函數。
ocr = ddddocr.DdddOcr()
img = self.driver.find_element(By.ID, 'SafeCodeImg') # 定位到驗證碼圖片
img.screenshot('code.png') # 給驗證碼元素截圖并保存
with open('code.png', 'rb') as f:
img_bytes = f.read() # 讀取圖片編碼
return ocr.classification(img_bytes) # 返回圖片中的驗證碼
? 這樣的話只需要定位到這個圖片元素,然后保存下來,再讀取編碼信息,使用ddddocr庫來進行一個文字識別,返回圖片的驗證碼模擬登陸就好了
? 最后登錄也就是找到元素然后調用函數模擬點擊就好了
self.driver.find_element(By.XPATH, "http://*[@class='btn btn-primary login_btn']").click()
? 這一部分本來難度不算很高,但是因為JS的原因,有一些地方需要注意。
? 首先就是模擬點擊一些摁扭可以轉到選課界面的地方。因為這個選課系統轉到一個頁面以后會產生一些新的東西(框架),這時候我們要再找上面的元素就要分清楚在哪一個框架上。
self.driver.switch_to.frame("Frame1") # !!
? 通過F12開發者選項可以找到這個元素所在的框架不是初始的框架(frame)而是在JS產生的一個新框架中,那么就需要用這個函數來轉到新的框架Frame1(通過開發者選項找到的frame id)
? 只有這一點需要特別注意!!!
? 首先一點,進入這個界面的時候,瀏覽器的界面是切換了的,因此我們也需要將selenium的定位切換到我們所看到的界面上。
new_window = self.driver.window_handles[-1]
self.driver.switch_to.window(new_window)
? 之后通過點擊又轉產生了一個新的框架,因此在進行一個轉框架的操作。
? 最后就是通過課程id、上課老師名字、上課是星期幾三個來作為鍵確定唯一的課程,進行一個選擇,并重復上述操作直到完成全部選課。
for my_course in self.user_course:
self.driver.find_element(By.ID, 'kcxx').send_keys(my_course[1]) # 通過課程信息查找
self.driver.find_element(By.ID, 'skls').send_keys(my_course[2]) # 通過上課老師查找
self.driver.find_element(By.XPATH, f"http://*[@id='skxq']/option[{my_course[3]+1}]").click()
# 選擇星期(一 - 2, 二 - 3, 三 - 4, 四 - 5, 五 - 6)
self.driver.find_element(By.XPATH, "html/body/div[3]/input[6]").click()
self.driver.find_element(By.ID, 'kcxx').clear() # 清空課程查詢框
self.driver.find_element(By.ID, 'skls').clear() # 清空上課老師框
time.sleep(1)
"""
沒刷新出來加一個等待1秒
"""
course_remain = self.driver.find_element(By.XPATH, "http://*[@class='odd']/td[9]").text # 查看課余量
if int(course_remain) > 0:
self.driver.find_element(By.XPATH, "http://*[@class='odd']/td[11]/div/a").click()
"""
這里缺少了一部分確定的代碼
"""
else:
print(f'{my_course[1]}選課失敗')
time.sleep(3) # 3秒的暫停
? 使用time庫來進行一個定時開始執行
run_time_h = 9 # 定時小時
run_time_m = 0 # 定時分鐘
while True:
current_time = time.localtime(time.time())
print(str(current_time.tm_hour) + '-' + str(current_time.tm_min) + '-' + str(current_time.tm_sec))
if current_time.tm_hour == run_time_h and current_time.tm_min == run_time_m:
break
? 因為我本身不是曲師大的校友所以說我沒有進行一個完全的操作,對系統的認識也不是很充分這樣寫出來的代碼當然也完成度也不能說是很高的,下面我就大概說一下這個代碼可能產生的問題。
import time
import ddddocr
from selenium import webdriver
from selenium.webdriver.common.by import By
class CClassSelect:
def __init__(self, i_account, i_password, i_course):
self.user_account = i_account
self.user_password = i_password
self.user_course = i_course
self.login_url = 'http://202.194.188.38/'
self.account_url = 'http://202.194.188.38/jsxsd/framework/xsMain.jsp'
self.driver = webdriver.Chrome()
self.driver.maximize_window()
def LoginAccount(self):
self.driver.get(self.login_url)
self.driver.find_element(By.ID, 'userAccount').send_keys(self.user_account)
self.driver.find_element(By.ID, 'userPassword').send_keys(self.user_password)
identify_code = self.Ocr()
self.driver.find_element(By.ID, 'RANDOMCODE').send_keys(identify_code)
self.driver.find_element(By.XPATH, "http://*[@class='btn btn-primary login_btn']").click()
def LoginClassSelect(self):
time.sleep(1)
self.driver.find_element(By.XPATH, "http://*[@id='onesidebar']/div/ul/li[3]/span").click()
self.driver.find_element(By.XPATH, "http://*[@class='sidebar-menu']/li[7]/a").click()
time.sleep(1)
self.driver.find_element(By.XPATH, "http://*[@class='treeview-menu menu-open']/li[1]/a").click()
self.driver.switch_to.frame("Frame1") # !!
"""
iframe問題,卡了一段時間這個地方,可以百度到是不在一個frame的原因
定位不到這個‘進入選課’元素,
"""
self.driver.find_element(By.ID, "jrxk").click()
self.driver.find_element(By.XPATH, "http://*[@class='Nsb_pw']/div/center/input[1]").click()
def ClassSelect(self):
new_window = self.driver.window_handles[-1]
self.driver.switch_to.window(new_window)
"""
切換到新的窗口
"""
self.driver.find_element(By.XPATH, "http://*[@id='topmenu']/li[4]/a").click()
self.driver.switch_to.frame("mainFrame") # 換frame
"""
選課代碼 ↓
"""
for my_course in self.user_course:
self.driver.find_element(By.ID, 'kcxx').send_keys(my_course[1]) # 通過課程信息查找
self.driver.find_element(By.ID, 'skls').send_keys(my_course[2]) # 通過上課老師查找
self.driver.find_element(By.XPATH, f"http://*[@id='skxq']/option[{my_course[3]+1}]").click()
# 選擇星期(一 - 2, 二 - 3, 三 - 4, 四 - 5, 五 - 6)
self.driver.find_element(By.XPATH, "html/body/div[3]/input[6]").click()
self.driver.find_element(By.ID, 'kcxx').clear() # 清空課程查詢框
self.driver.find_element(By.ID, 'skls').clear() # 清空上課老師框
time.sleep(1)
"""
沒刷新出來加一個等待1秒
"""
course_remain = self.driver.find_element(By.XPATH, "http://*[@class='odd']/td[9]").text # 查看課余量
if int(course_remain) > 0:
self.driver.find_element(By.XPATH, "http://*[@class='odd']/td[11]/div/a").click()
"""
這里缺少了一部分確定的代碼
"""
else:
print(f'{my_course[1]}選課失敗')
time.sleep(3) # 3秒的暫停
def Ocr(self):
ocr = ddddocr.DdddOcr()
img = self.driver.find_element(By.ID, 'SafeCodeImg') # 定位到驗證碼圖片
img.screenshot('code.png') # 給驗證碼元素截圖并保存
with open('code.png', 'rb') as f:
img_bytes = f.read() # 讀取圖片編碼
return ocr.classification(img_bytes) # 返回圖片中的驗證碼
def Run(self):
self.LoginAccount()
self.LoginClassSelect()
self.ClassSelect()
self.driver.quit()
if __name__ == '__main__':
# 定時運行
run_time_h = 9 # 定時小時
run_time_m = 0 # 定時分鐘
while True:
current_time = time.localtime(time.time())
print(str(current_time.tm_hour) + '-' + str(current_time.tm_min) + '-' + str(current_time.tm_sec))
if current_time.tm_hour == run_time_h and current_time.tm_min == run_time_m:
break
# 主程序
input_account = "" # 用戶賬號
input_password = "abcde" # 用戶密碼
input_course = [['', '張三', 3], ['', '李四', 5]] # 要選的課(ID,上課老師,星期)
app = CClassSelect(input_account, input_password, input_course)
app.Run()
網站名稱:自動化選課(Python + selenium
文章分享:http://m.kartarina.com/article14/dsogide.html
成都網站建設公司_創新互聯,為您提供品牌網站建設、品牌網站制作、標簽優化、服務器托管、建站公司、營銷型網站建設
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯