文章目錄 微信登錄問題Python chrome driver操作導(dǎo)入庫并聲明瀏覽器:完整流程:用js來預(yù)約生成js代碼 主函數(shù)——程序出錯時嘗試:檢測是否成功:logging: 生成每天的日志文件 Windows定時任務(wù)后記:
學(xué)校的圖書館需要網(wǎng)上預(yù)約。復(fù)習(xí)考研的人多、疫情座位少,約上一個好點的座位對于我這種經(jīng)常忘記事情的懶人來說很難。
考慮到老師實驗室有一臺供我們使用的Windows服務(wù)器是不會關(guān)機(jī)的,正好可以幫我在早上7:00預(yù)約系統(tǒng)開啟的時候執(zhí)行程序去預(yù)約一個座位。所以產(chǎn)生了這個想法。
微信登錄問題
想用chromedriver去操作,方便快捷,但我們圖書館的預(yù)約在微信上進(jìn)行的,在微信公眾號上認(rèn)證過帳號以后,會發(fā)送一個鏈接,點進(jìn)去就是自己的登錄信息。經(jīng)過和同學(xué)的驗證,他將他的鏈接發(fā)送給我,我就可以打開他的登錄信息。這讓我感到很神奇,本以為登錄信息僅僅攜帶在網(wǎng)址上,但如果在微信中用瀏覽器打開,再將網(wǎng)址復(fù)制到其它瀏覽器,會登陸失敗。查找一系列百度谷歌想弄清楚這個問題,應(yīng)該與cookies之類的有關(guān),這里希望以后可以填坑。
當(dāng)我沒有找到頭緒的時候,我偶然間發(fā)現(xiàn)學(xué)校圖書館開放了另一個入口可以在網(wǎng)頁上預(yù)約,而這個流程就清晰很多了:
- 進(jìn)入網(wǎng)站
- 輸入賬號和密碼,點擊登錄按鈕
- 找到座位并選擇
Python chrome driver操作

有幾個注意的點:
- 每天早上系統(tǒng)開放的時間有幾分鐘的差別,需要留時間嘗試。
- 剛開放的時候,系統(tǒng)會很卡,所以很可能會出現(xiàn)獲取元素失敗之類的情況。
這就要求我們的程序得有足夠的魯棒性(哈哈蛤) 容錯能力,不會一下崩了就沒用了。
所以我選擇用try...except...
的方法去進(jìn)行,寫了好多個try
, 希望能找到不寫這么多Try的更好的方法。
導(dǎo)入庫并聲明瀏覽器:
from selenium import webdriver
option = webdriver.ChromeOptions()
url='網(wǎng)址'
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") #找到登錄的按鈕,如果沒找到證明還沒到開放時間/系統(tǒng)在崩潰
except:
return 1 #1說明預(yù)約還沒到時候
'''執(zhí)行到這里說明打開啦'''
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代碼來預(yù)約
res=browser.execute_script(js)
return 0
except:
return 2 #2說明打開了網(wǎng)頁,但是遇到了其它問題
用js來預(yù)約
找到座位并選擇,如果用鼠標(biāo)操作的話是很繁瑣的,包括先找到座位圖標(biāo),點擊,下拉選擇開始時間和結(jié)束時間,再點擊預(yù)約,這個過程麻煩不說,主要是容易出錯。
而其實一個座位預(yù)定的本質(zhì)其實是提交一個表單。瀏覽器的前端做了那么多人性化的操作,如可視化座位表、下拉框、溫馨提示等,就是為了人使用時好看而又方便,而我們作為計算機(jī)就可以饒過他,直接提交表單。這里用的是selenium的execute_script()
函數(shù),可以用來執(zhí)行網(wǎng)頁上的js代碼。
生成js代碼
用F12去觀察發(fā)現(xiàn),圖書管的表單提交需要下面幾步:
$("#date").val("2020-12-10");
$("#reserveForm#seat").val("13022"); //座位號
$("#start").val("540"); //用分鐘表示的時間 : 540=9*60 即九點
$("#end").val("1260");
$("#reserveForm").submit();
因此這個函數(shù)用來生成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ù)——程序出錯時嘗試:
返回的狀態(tài)中,如果網(wǎng)頁沒打開,讓他休息10s再嘗試,如果是其它原因,那么休息0.5秒就繼續(xù)嘗試:
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("打開網(wǎng)頁失敗")
time.sleep(10)
elif state==2:
logger.info("其它錯誤")
time.sleep(0.5)
檢測是否成功:
除了上面提到的網(wǎng)頁崩潰導(dǎo)致WebDriver報錯,還有幾種可能導(dǎo)致失敗:
- 座位被人搶了😟
- 已經(jīng)有過預(yù)約了
- 有人約了但不是全部時間段。
這幾種錯誤都不會報錯,會在執(zhí)行代碼后以標(biāo)簽的形式告訴我們,可以用關(guān)鍵字定位這些標(biāo)簽,如果失敗可以選擇預(yù)約PlanB:
比如:
try:
a=browser.find_element_by_xpath("http://*[contains(text(),'盡快')]") #有人約了(非全部時間)
error_reason=a.text
isNoSeat=True
logging: 生成每天的日志文件
寫好小程序以后,幾個兄弟聽說了也想嘗試,每天預(yù)約。
不想每天早上七點起來看,為了防止為止錯誤發(fā)生后還不知道是哪步出錯,采取的辦法是寫日志文件(事后追責(zé)),這里使用的是logging
這個包。
logger的初始化代碼來源 : python的logging模塊
import logging
# 創(chuàng)建一個logger
logger = logging.getLogger('mylogger')
logger.setLevel(logging.DEBUG)
# 創(chuàng)建一個handler,用于寫入日志文件
fh = logging.FileHandler(local_dir+'logfile\\'+logname+'.log')
fh.setLevel(logging.DEBUG)
# 再創(chuàng)建一個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定時任務(wù)
- 此電腦上右鍵管理
- 右側(cè)有創(chuàng)建任務(wù)(下圖)

- 在觸發(fā)器選項卡中新建,并設(shè)定時間
- 在操作選項卡中新建,并選擇程序路徑(下圖)

這樣就程序就會每天早上執(zhí)行,只要有一臺不關(guān)機(jī)的電腦。
后記:
大家開始使用我的代碼,但都是我放在學(xué)校的服務(wù)器上,為了方便他們修改自己想要的預(yù)約時間、位置等信息,我寫了個微信小程序方便同學(xué)修改時間。
思路就是使用微信小程序修改自己的預(yù)約信息,同步到微信的數(shù)據(jù)庫。
早上預(yù)約時,我的程序通過微信云開發(fā)數(shù)據(jù)庫的API獲取到這些預(yù)約信息(時間、座位、學(xué)號、密碼),再去預(yù)約,免去了總要去服務(wù)器上修改程序/參數(shù)的麻煩事。
具體的小程序部分的內(nèi)容這里不展開,以后再寫日記。
這就是上學(xué)期快期末的時候搞的一個小事情,雖然原理非常簡單,但能幫自己和同學(xué)去預(yù)約圖書館還是很快樂的,尤其是每天早上醒來大家都收到企業(yè)微信的“預(yù)約成功”的提示的時候,然而過程中還有一些沒懂的知識和沒填的坑,所以在CSDN寫個小記,怕以后忘了。
到此這篇關(guān)于使用Python webdriver圖書館搶座自動預(yù)約的正確方法的文章就介紹到這了,更多相關(guān)Python webdriver圖書館搶座自動預(yù)約內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
您可能感興趣的文章:- 用python-webdriver實現(xiàn)自動填表的示例代碼
- python+webdriver自動化環(huán)境搭建步驟詳解
- selenium+python自動化測試之使用webdriver操作瀏覽器的方法
- python使用webdriver爬取微信公眾號
- python實現(xiàn)圖書館搶座(自動預(yù)約)功能的示例代碼
- python實現(xiàn)圖書館研習(xí)室自動預(yù)約功能
- Python Requests模擬登錄實現(xiàn)圖書館座位自動預(yù)約