使用Python webdriver圖書館搶座自動(dòng)預(yù)約的正確方法
文章目錄 微信登錄問(wèn)題Python chrome driver操作導(dǎo)入庫(kù)并聲明瀏覽器:完整流程:用js來(lái)預(yù)約生成js代碼 主函數(shù)——程序出錯(cuò)時(shí)嘗試:檢測(cè)是否成功:logging: 生成每天的日志文件 Windows定時(shí)任務(wù)后記:學(xué)校的圖書館需要網(wǎng)上預(yù)約。復(fù)習(xí)考研的人多、疫情座位少,約上一個(gè)好點(diǎn)的座位對(duì)于我這種經(jīng)常忘記事情的懶人來(lái)說(shuō)很難。
考慮到老師實(shí)驗(yàn)室有一臺(tái)供我們使用的Windows服務(wù)器是不會(huì)關(guān)機(jī)的,正好可以幫我在早上7:00預(yù)約系統(tǒng)開啟的時(shí)候執(zhí)行程序去預(yù)約一個(gè)座位。所以產(chǎn)生了這個(gè)想法。
微信登錄問(wèn)題想用chromedriver去操作,方便快捷,但我們圖書館的預(yù)約在微信上進(jìn)行的,在微信公眾號(hào)上認(rèn)證過(guò)帳號(hào)以后,會(huì)發(fā)送一個(gè)鏈接,點(diǎn)進(jìn)去就是自己的登錄信息。經(jīng)過(guò)和同學(xué)的驗(yàn)證,他將他的鏈接發(fā)送給我,我就可以打開他的登錄信息。這讓我感到很神奇,本以為登錄信息僅僅攜帶在網(wǎng)址上,但如果在微信中用瀏覽器打開,再將網(wǎng)址復(fù)制到其它瀏覽器,會(huì)登陸失敗。查找一系列百度谷歌想弄清楚這個(gè)問(wèn)題,應(yīng)該與cookies之類的有關(guān),這里希望以后可以填坑。
當(dāng)我沒(méi)有找到頭緒的時(shí)候,我偶然間發(fā)現(xiàn)學(xué)校圖書館開放了另一個(gè)入口可以在網(wǎng)頁(yè)上預(yù)約,而這個(gè)流程就清晰很多了:
進(jìn)入網(wǎng)站 輸入賬號(hào)和密碼,點(diǎn)擊登錄按鈕 找到座位并選擇Python chrome driver操作有幾個(gè)注意的點(diǎn):
每天早上系統(tǒng)開放的時(shí)間有幾分鐘的差別,需要留時(shí)間嘗試。 剛開放的時(shí)候,系統(tǒng)會(huì)很卡,所以很可能會(huì)出現(xiàn)獲取元素失敗之類的情況。這就要求我們的程序得有足夠的魯棒性(哈哈蛤) 容錯(cuò)能力,不會(huì)一下崩了就沒(méi)用了。所以我選擇用try...except...的方法去進(jìn)行,寫了好多個(gè)try, 希望能找到不寫這么多Try的更好的方法。
導(dǎo)入庫(kù)并聲明瀏覽器:
from selenium import webdriveroption = webdriver.ChromeOptions()url=’網(wǎng)址’local_dir = ’C:UsersAdministratorDesktoplibrarytest’ #webdiriver 位置browser = webdriver.Chrome(local_dir+'chromedriver.exe',options=option)完整流程:
使用selenium操作非常簡(jiǎn)單,就是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') #找到登錄的按鈕,如果沒(méi)找到證明還沒(méi)到開放時(shí)間/系統(tǒng)在崩潰 except: return 1 #1說(shuō)明預(yù)約還沒(méi)到時(shí)候 ’’’執(zhí)行到這里說(shuō)明打開啦’’’ try: btn.click() username=browser.find_element_by_id('un') password=browser.find_element_by_id('pd')#找到賬號(hào)密碼 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代碼來(lái)預(yù)約 res=browser.execute_script(js) return 0 except: return 2 #2說(shuō)明打開了網(wǎng)頁(yè),但是遇到了其它問(wèn)題用js來(lái)預(yù)約
找到座位并選擇,如果用鼠標(biāo)操作的話是很繁瑣的,包括先找到座位圖標(biāo),點(diǎn)擊,下拉選擇開始時(shí)間和結(jié)束時(shí)間,再點(diǎn)擊預(yù)約,這個(gè)過(guò)程麻煩不說(shuō),主要是容易出錯(cuò)。而其實(shí)一個(gè)座位預(yù)定的本質(zhì)其實(shí)是提交一個(gè)表單。瀏覽器的前端做了那么多人性化的操作,如可視化座位表、下拉框、溫馨提示等,就是為了人使用時(shí)好看而又方便,而我們作為計(jì)算機(jī)就可以饒過(guò)他,直接提交表單。這里用的是selenium的execute_script()函數(shù),可以用來(lái)執(zhí)行網(wǎng)頁(yè)上的js代碼。
生成js代碼用F12去觀察發(fā)現(xiàn),圖書管的表單提交需要下面幾步:
$('#date').val('2020-12-10'); $('#reserveForm#seat').val('13022'); //座位號(hào)$('#start').val('540'); //用分鐘表示的時(shí)間 : 540=9*60 即九點(diǎn)$('#end').val('1260');$('#reserveForm').submit();
因此這個(gè)函數(shù)用來(lái)生成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主函數(shù)——程序出錯(cuò)時(shí)嘗試:
返回的狀態(tài)中,如果網(wǎng)頁(yè)沒(méi)打開,讓他休息10s再嘗試,如果是其它原因,那么休息0.5秒就繼續(xù)嘗試:
if __name__==’__main__’: browser = webdriver.Chrome(local_dir+'chromedriver.exe',options=option)#聲明瀏覽器 while True: state=wholeProcess(browser) if state==0: #沒(méi)出錯(cuò) break: elif state==1: logger.info('打開網(wǎng)頁(yè)失敗') time.sleep(10) elif state==2: logger.info('其它錯(cuò)誤') time.sleep(0.5)
檢測(cè)是否成功:
除了上面提到的網(wǎng)頁(yè)崩潰導(dǎo)致WebDriver報(bào)錯(cuò),還有幾種可能導(dǎo)致失敗:
座位被人搶了😟 已經(jīng)有過(guò)預(yù)約了 有人約了但不是全部時(shí)間段。這幾種錯(cuò)誤都不會(huì)報(bào)錯(cuò),會(huì)在執(zhí)行代碼后以標(biāo)簽的形式告訴我們,可以用關(guān)鍵字定位這些標(biāo)簽,如果失敗可以選擇預(yù)約PlanB:比如:
try: a=browser.find_element_by_xpath('//*[contains(text(),’盡快’)]') #有人約了(非全部時(shí)間) error_reason=a.text isNoSeat=True
logging: 生成每天的日志文件
寫好小程序以后,幾個(gè)兄弟聽說(shuō)了也想嘗試,每天預(yù)約。不想每天早上七點(diǎn)起來(lái)看,為了防止為止錯(cuò)誤發(fā)生后還不知道是哪步出錯(cuò),采取的辦法是寫日志文件(事后追責(zé)),這里使用的是logging這個(gè)包。logger的初始化代碼來(lái)源 : python的logging模塊
import logging# 創(chuàng)建一個(gè)loggerlogger = logging.getLogger(’mylogger’)logger.setLevel(logging.DEBUG)# 創(chuàng)建一個(gè)handler,用于寫入日志文件fh = logging.FileHandler(local_dir+’logfile’+logname+’.log’)fh.setLevel(logging.DEBUG)# 再創(chuàng)建一個(gè)handler,用于輸出到控制臺(tái)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添加handlerlogger.addHandler(fh)logger.addHandler(ch)# 記錄一條日志
記錄時(shí)只要使用 logger.info('xxxxx')就可以,非常方便,寫在了上面。
Windows定時(shí)任務(wù) 此電腦上右鍵管理 右側(cè)有創(chuàng)建任務(wù)(下圖)這樣就程序就會(huì)每天早上執(zhí)行,只要有一臺(tái)不關(guān)機(jī)的電腦。
后記:大家開始使用我的代碼,但都是我放在學(xué)校的服務(wù)器上,為了方便他們修改自己想要的預(yù)約時(shí)間、位置等信息,我寫了個(gè)微信小程序方便同學(xué)修改時(shí)間。
思路就是使用微信小程序修改自己的預(yù)約信息,同步到微信的數(shù)據(jù)庫(kù)。早上預(yù)約時(shí),我的程序通過(guò)微信云開發(fā)數(shù)據(jù)庫(kù)的API獲取到這些預(yù)約信息(時(shí)間、座位、學(xué)號(hào)、密碼),再去預(yù)約,免去了總要去服務(wù)器上修改程序/參數(shù)的麻煩事。具體的小程序部分的內(nèi)容這里不展開,以后再寫日記。
這就是上學(xué)期快期末的時(shí)候搞的一個(gè)小事情,雖然原理非常簡(jiǎn)單,但能幫自己和同學(xué)去預(yù)約圖書館還是很快樂(lè)的,尤其是每天早上醒來(lái)大家都收到企業(yè)微信的“預(yù)約成功”的提示的時(shí)候,然而過(guò)程中還有一些沒(méi)懂的知識(shí)和沒(méi)填的坑,所以在CSDN寫個(gè)小記,怕以后忘了。
到此這篇關(guān)于使用Python webdriver圖書館搶座自動(dòng)預(yù)約的正確方法的文章就介紹到這了,更多相關(guān)Python webdriver圖書館搶座自動(dòng)預(yù)約內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!
相關(guān)文章:
1. Python中Anaconda3 安裝gdal庫(kù)的方法2. PHP AOP教程案例3. python用zip壓縮與解壓縮4. python公司內(nèi)項(xiàng)目對(duì)接釘釘審批流程的實(shí)現(xiàn)5. Notepad++如何配置python?配置python操作流程詳解6. Python 簡(jiǎn)介7. Python操作Excel工作簿的示例代碼(*.xlsx)8. JAVA如何轉(zhuǎn)換樹結(jié)構(gòu)數(shù)據(jù)代碼實(shí)例9. Python importlib模塊重載使用方法詳解10. Python自動(dòng)化之定位方法大殺器xpath
