自動化選課(Python + selenium

? 前幾天聽到朋友說自己選課事情,突發奇想想要搞這樣一個東西,但是由于各種原因只做到以下的完成度,具體的情況也會在解釋的最后留下。這個只適用于曲師大的教務系統,因為用的這個系統來進行的一個調試,對于其他的系統,思路都是一樣的,代碼也只適用于學習,請不要用以其他用途!代碼放在最后。

在金湖等地區,都構建了全面的區域性戰略布局,加強發展的系統性、市場前瞻性、產品創新能力,以專注、極致的服務理念,為客戶提供成都網站設計、成都網站制作 網站設計制作按需定制開發,公司網站建設,企業網站建設,成都品牌網站建設,成都營銷網站建設,成都外貿網站建設,金湖網站建設費用合理。

工具

  • Python3
  • selenium庫(瀏覽器自動化操作)
  • ddddocr庫(OCR圖片文字識別)
  • time庫(定時操作)

思路

? 對于想要做到的這個需求呢,我選擇的是python + selenium庫進行一個瀏覽器自動化操作,在寫的過程中因為發現了一個驗證碼的問題所以又用到了一個ddddocr庫,如果想要定時操作的話再加上一個time庫。之后就是理清操作的順序就好了,想到于人工操作一遍的過程。

  1. 進入系統登錄界面
  2. 進入用戶界面
  3. 進入選課界面
  4. 開始選課

大的一個方向、思路就是上面這四步,具體的細化之后再談及。

過程

進入系統登錄界面

? 這一步就很簡單,直接用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

一些操作的解釋

  1. selenium庫的使用可以查一下其他博主的介紹
  2. 關于元素的定位,一般我習慣于使用通過ID和XPATH來定位(XPATH 就是 "http://*[@xx='abc']/li[1]/")這個也可以看看如何去使用。
  3. ddddocr庫是看圖片的編碼來轉換成文本

此代碼可能出現的問題(完成度不是很高):

? 因為我本身不是曲師大的校友所以說我沒有進行一個完全的操作,對系統的認識也不是很充分這樣寫出來的代碼當然也完成度也不能說是很高的,下面我就大概說一下這個代碼可能產生的問題。

  1. 如果系統崩潰(加載不出頁面……),程序應該是不能執行命令。
  2. 最后的選課部分只進行了一個點擊,并沒有確認,因此實際上這段代碼是無法完成選課的!
  3. 可能圖片識別有一定的誤差,導致不能登陸成功(ddddocr庫可能出的問題)
  4. 操作過快以至于元素沒有加載出來,這一點我通過time.sleep()函數來進行了一個優化,每次選課間隙也添加一個3秒的一個等待。
  5. 可能通過ID、上課老師、上課星期幾三個限制無法確定唯一的課程
    ……
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。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

h5響應式網站建設
主站蜘蛛池模板: 国产免费无码AV片在线观看不卡 | 亚洲精品无码激情AV| 人妻夜夜添夜夜无码AV| 精品久久久久久中文字幕无码 | 最新亚洲人成无码网站| 精品一区二区三区无码免费直播| 日韩va中文字幕无码电影| 人妻丰满熟妇岳AV无码区HD| 免费无码不卡视频在线观看| 日日摸日日碰夜夜爽无码| 免费一区二区无码视频在线播放 | 无码专区天天躁天天躁在线| 激情无码亚洲一区二区三区| 久久久久久AV无码免费网站下载| 无码精品不卡一区二区三区| 无码乱人伦一区二区亚洲| 潮喷大喷水系列无码久久精品| 97久久精品无码一区二区天美| 东京无码熟妇人妻AV在线网址| 无码高潮爽到爆的喷水视频app| 亚洲AV无码专区国产乱码电影| 亚洲AV无码成人精品区大在线| 亚洲a∨无码一区二区| 精品人无码一区二区三区| 亚洲精品人成无码中文毛片 | 国产日韩精品中文字无码| 日韩人妻无码精品专区| 国产精品无码翘臀在线观看| 亚洲日韩精品A∨片无码加勒比 | 亚洲精品无码MV在线观看| 免费无码又爽又高潮视频 | 久久国产精品无码网站| 日韩加勒比一本无码精品| 无码一区二区三区AV免费| 人妻少妇精品无码专区动漫| 无码狠狠躁久久久久久久| 精品无码成人片一区二区| 精品无人区无码乱码大片国产| 国产成人无码A区在线观看导航| 一本大道无码av天堂| 亚洲AV无码AV男人的天堂不卡|