使用Python webdriver圖書館搶座自動預約的正確方法
文章目錄 微信登錄問題Python chrome driver操作導入庫並聲明瀏覽器:完整流程:用js來預約生成js代碼 主函數——程序出錯時嘗試:檢測是否成功:logging: 生成每天的日志文件 Windows定時任務後記:
學校的圖書館需要網上預約。復習考研的人多、疫情座位少,約上一個好點的座位對於我這種經常忘記事情的懶人來說很難。
考慮到老師實驗室有一臺供我們使用的Windows服務器是不會關機的,正好可以幫我在早上7:00預約系統開啟的時候執行程序去預約一個座位。所以產生瞭這個想法。
微信登錄問題
想用chromedriver去操作,方便快捷,但我們圖書館的預約在微信上進行的,在微信公眾號上認證過帳號以後,會發送一個鏈接,點進去就是自己的登錄信息。經過和同學的驗證,他將他的鏈接發送給我,我就可以打開他的登錄信息。這讓我感到很神奇,本以為登錄信息僅僅攜帶在網址上,但如果在微信中用瀏覽器打開,再將網址復制到其它瀏覽器,會登陸失敗。查找一系列百度谷歌想弄清楚這個問題,應該與cookies之類的有關,這裡希望以後可以填坑。
當我沒有找到頭緒的時候,我偶然間發現學校圖書館開放瞭另一個入口可以在網頁上預約,而這個流程就清晰很多瞭:
- 進入網站
- 輸入賬號和密碼,點擊登錄按鈕
- 找到座位並選擇
Python chrome driver操作
有幾個註意的點:
- 每天早上系統開放的時間有幾分鐘的差別,需要留時間嘗試。
- 剛開放的時候,系統會很卡,所以很可能會出現獲取元素失敗之類的情況。
這就要求我們的程序得有足夠的魯棒性(哈哈蛤) 容錯能力,不會一下崩瞭就沒用瞭。
所以我選擇用try...except...
的方法去進行,寫瞭好多個try
, 希望能找到不寫這麼多Try的更好的方法。
導入庫並聲明瀏覽器:
from selenium import webdriver option = webdriver.ChromeOptions() url='網址' local_dir = 'C:\\Users\\Administrator\\Desktop\\librarytest\\' #webdiriver 位置 browser = webdriver.Chrome(local_dir+"chromedriver.exe",options=option)
完整流程:
使用selenium操作非常簡單,就是find_element_by_id()
和find_element_by_xpath()
,主要是看F12去找他們的xpath或者id。
def wholeProcess(browser): browser.get(url) try: btn=browser.find_element_by_xpath("/html/body/div[4]/div[2]/div[2]/dl/input") #找到登錄的按鈕,如果沒找到證明還沒到開放時間/系統在崩潰 except: return 1 #1說明預約還沒到時候 '''執行到這裡說明打開啦''' try: btn.click() username=browser.find_element_by_id("un") password=browser.find_element_by_id("pd")#找到賬號密碼 username.send_keys(studentNumber) password.send_keys(loginPassword) btn=browser.find_element_by_xpath('//*[@id="index_login_btn"]/input')#找到登錄按鍵 btn.click() js=generateJsCode(startTime,endTime)#使用js代碼來預約 res=browser.execute_script(js) return 0 except: return 2 #2說明打開瞭網頁,但是遇到瞭其它問題
用js來預約
找到座位並選擇,如果用鼠標操作的話是很繁瑣的,包括先找到座位圖標,點擊,下拉選擇開始時間和結束時間,再點擊預約,這個過程麻煩不說,主要是容易出錯。
而其實一個座位預定的本質其實是提交一個表單。瀏覽器的前端做瞭那麼多人性化的操作,如可視化座位表、下拉框、溫馨提示等,就是為瞭人使用時好看而又方便,而我們作為計算機就可以饒過他,直接提交表單。這裡用的是selenium的execute_script()
函數,可以用來執行網頁上的js代碼。
生成js代碼
用F12去觀察發現,圖書管的表單提交需要下面幾步:
$("#date").val("2020-12-10"); $("#reserveForm#seat").val("13022"); //座位號 $("#start").val("540"); //用分鐘表示的時間 : 540=9*60 即九點 $("#end").val("1260"); $("#reserveForm").submit();
因此這個函數用來生成js代碼:
def generateJsCode(startTime_ori,endTime_ori): seatnumber_str = seatId startTime_str = str(startTime_ori * 60) endTime_str = str(endTime_ori * 60) tomorrowTime = (datetime.datetime.now() + datetime.timedelta(days=1)).strftime('%Y-%m-%d') # 明天 js = '$("#date").val("' + tomorrowTime + '");$("#reserveForm #seat").val("' + seatnumber_str + '");$("#start").val("' + startTime_str + '");$("#end").val("' + endTime_str + '");$("#reserveForm").submit();' return js
主函數——程序出錯時嘗試:
返回的狀態中,如果網頁沒打開,讓他休息10s再嘗試,如果是其它原因,那麼休息0.5秒就繼續嘗試:
if __name__=='__main__': browser = webdriver.Chrome(local_dir+"chromedriver.exe",options=option)#聲明瀏覽器 while True: state=wholeProcess(browser) if state==0: #沒出錯 break: elif state==1: logger.info("打開網頁失敗") time.sleep(10) elif state==2: logger.info("其它錯誤") time.sleep(0.5)
檢測是否成功:
除瞭上面提到的網頁崩潰導致WebDriver報錯,還有幾種可能導致失敗:
- 座位被人搶瞭😟
- 已經有過預約瞭
- 有人約瞭但不是全部時間段。
這幾種錯誤都不會報錯,會在執行代碼後以標簽的形式告訴我們,可以用關鍵字定位這些標簽,如果失敗可以選擇預約PlanB:
比如:
try: a=browser.find_element_by_xpath("//*[contains(text(),'盡快')]") #有人約瞭(非全部時間) error_reason=a.text isNoSeat=True
logging: 生成每天的日志文件
寫好小程序以後,幾個兄弟聽說瞭也想嘗試,每天預約。
不想每天早上七點起來看,為瞭防止為止錯誤發生後還不知道是哪步出錯,采取的辦法是寫日志文件(事後追責),這裡使用的是logging
這個包。
logger的初始化代碼來源 : python的logging模塊
import logging # 創建一個logger logger = logging.getLogger('mylogger') logger.setLevel(logging.DEBUG) # 創建一個handler,用於寫入日志文件 fh = logging.FileHandler(local_dir+'logfile\\'+logname+'.log') fh.setLevel(logging.DEBUG) # 再創建一個handler,用於輸出到控制臺 ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) # 定義handler的輸出格式 formatter = logging.Formatter('[%(asctime)s][%(thread)d][%(filename)s][line: %(lineno)d][%(levelname)s] ## %(message)s') fh.setFormatter(formatter) ch.setFormatter(formatter) # 給logger添加handler logger.addHandler(fh) logger.addHandler(ch) # 記錄一條日志
記錄時隻要使用 logger.info("xxxxx")
就可以,非常方便,寫在瞭上面。
Windows定時任務
- 此電腦上右鍵管理
- 右側有創建任務(下圖)
- 在觸發器選項卡中新建,並設定時間
- 在操作選項卡中新建,並選擇程序路徑(下圖)
這樣就程序就會每天早上執行,隻要有一臺不關機的電腦。
後記:
大傢開始使用我的代碼,但都是我放在學校的服務器上,為瞭方便他們修改自己想要的預約時間、位置等信息,我寫瞭個微信小程序方便同學修改時間。
思路就是使用微信小程序修改自己的預約信息,同步到微信的數據庫。
早上預約時,我的程序通過微信雲開發數據庫的API獲取到這些預約信息(時間、座位、學號、密碼),再去預約,免去瞭總要去服務器上修改程序/參數的麻煩事。
具體的小程序部分的內容這裡不展開,以後再寫日記。
這就是上學期快期末的時候搞的一個小事情,雖然原理非常簡單,但能幫自己和同學去預約圖書館還是很快樂的,尤其是每天早上醒來大傢都收到企業微信的“預約成功”的提示的時候,然而過程中還有一些沒懂的知識和沒填的坑,所以在CSDN寫個小記,怕以後忘瞭。
到此這篇關於使用Python webdriver圖書館搶座自動預約的正確方法的文章就介紹到這瞭,更多相關Python webdriver圖書館搶座自動預約內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- python+selenium小米商城紅米K40手機自動搶購的示例代碼
- Python趣味實戰之手把手教你實現舉牌小人生成器
- 利用Python實現網站自動簽到
- selenium動態數據獲取的方法實現
- Python logging簡介詳解