這篇文章主要為大家詳細介紹了python實現圖書館研習室自動預約功能,具有一定的參考價值,感興趣的小夥伴們可以參考一下
本文為大家分享了python實現圖書館研習室自動預約的具體代碼,供大家參考,具體內容如下
簡介
現在好多學校為學生提供了非常良好的學習環境,通常體現在自習教室的設施裝置上。對此不得不提一句的就是我們學校的圖書館,隨著新圖書館的修建,館內也設定了多個功能區,每層分為A、B、C、D四個地區,由南北連廊相連,中間由旋轉樓梯貫通一至五層。A區為自修區;B區和C區為藏閱一體的社會科學和自然科學書庫;D區為專項功能區,包含影視廳、數位媒體創客體驗中心、智慧培訓教室、CloudDesktop電子閱覽室等;B、C區東西連廊設有大小十二間研習室;南北連廊設有休閑閱讀區。
上面那段我是從圖書館官網上抄的,不過真的得為學校的圖書館點個贊。迴歸本篇文章正題,學校免費為廣大師生提供了舒適優良裝置齊全的研習室。但是這些研習室是需要進行網上預約才能夠進入使用,每天的00:00開啟下一天的預約,因此要想約到一個時間段(3小時)的研習室,可謂得“挑燈夜戰”。當然,在這個過程中手速快將有巨大的優勢。如果晚上休息的早,手速又不快,基本上就別想預約到研習室了。剛剛好最近學了一點python爬蟲,就打算用爬蟲幫我完成這個艱巨的任務了。哈哈哈哈!(ps:防止惡意訪問,所有連結就不放了哈)
python實現思路
想想思路還是挺簡單的,無非就是登入帳號、尋找房間、提交預約。那就讓我們試試看:
登入帳號
首先開啟我們研習室預約的登入介面,連結為:U2FsdGVkX19NdfJkghN54Msvy1zl7AucRur/ct0nz4orPI7uLkSDsvuFMgr0fGcO
rn9Z/f8h3bds9w==
好吧,這第一步登入帳號就非常考驗我這個新手了,不過不能慫。通過參考其他一些大佬使用的方法,就是開啟firefox的firebug(ctrl+shift+e)查看網路情況,在這個情況下進行一次正常的登入。
可以看到我們這裡有個post,到時便可以使用python中requests.post方法。
為了能夠成功的登入,要隱藏自己是個爬蟲的身份,在訊息頭中,可以看到我們的要求標頭,只要將參數都複製過來,組成自己的headers = {…}來欺騙伺服器。
看一下參數這一頁,這裡的表單資料只有三個,分別對應著驗證碼、帳號和密碼。將這裡的參數複製過來,就可以組成我們的data = {…}。其中需要我們的注意的就是這個驗證碼,無論是人工“自”能識別,還是機器自動識別,都需要將驗證碼儲存為本地檔案。如此一來,就有了一個問題,每訪問一次伺服器,驗證碼就會變換。現在讓我們好好捋捋思路,首先我們得獲得驗證碼並將其儲存在本地,這就需要訪問一次伺服器,最後我們要提交我們的參數進行登入,這又再一次訪問了伺服器,這次的驗證碼和我們擷取的驗證碼已經不是同一個驗證碼了。在剛剛開始的嘗試中我無論如何無法登入伺服器,就是兩次的驗證碼不匹配。如何?第一次擷取的驗證碼和提交時的驗證碼相一致呢?
這裡就需要同一個cookie在上面的幾個圖中,我們都能看到有個cookie值。要保證同步,這裡就需要做到,我們擷取驗證碼時的cookie值和提交帳號密碼時的cookie值一致。因此,在我的程式中,我先做的一個步驟時先擷取一個cookie值,然後將這個cookie值作為headers中的一個參數。登入的思路就是這樣了,補充一句,這裡的驗證碼我是自己手動識別的>﹏<。
尋找房間
這個步驟其實是一個無用的步驟,為什麼有這個步驟,按照人為預約習慣,我們會產生怎麼一個步驟,但是如果使用爬蟲,只要成功登入之後就可以直接提交預約的表單。當然,如果要使得自動預約程式更加智能,便可以添加這個步驟,可以查看那些房間是還可以預約的,在這裡自訂的補充一些規則。我就略過了。。。
提交預約
同登入一樣,我們也手動的提交一次,去查看網路情況,便可以用python類比這一個過程。在這裡我就不在貼圖進行解釋,這裡提交也是用requests.post的方法。不過一點要注意的是,這裡的headers和登入時的headers是不一樣的,所以在此提醒各位,如果在其他類似的預約程式中可以注意看看不同內容post時的headers是否一致。我在這裡就被坑了一會。
#!/usr/bin/env python # _*_ coding:utf-8 _*_ # # @Version : 1.0 # @Time : 2018/4/10 # @Author : 圈圈烴# @File : reservation_4.py import requestsimport reimport jsonimport datetimeimport timedef get_cookies(): """獲得cookies""" url = 'http://**************' s = requests.session() s.get(url) ck_dict = requests.utils.dict_from_cookiejar(s.cookies) # 將jar格式轉化為dict ck = 'JSESSIONID=' + ck_dict['JSESSIONID'] # 重組cookies """獲得二維碼""" path = './code.png' get_cookies_headers = { 'user-anget': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0', 'Cookie': ck} get_cookies_url = 'http://**************' code_image = requests.get(get_cookies_url, headers=get_cookies_headers) with open(path, 'wb') as fn: fn.write(code_image.content) fn.close() print('驗證碼儲存成功') return ckdef login(cookies, hour, minute): login_headers = { 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive', 'Content-Length': '45', 'Content-Type': 'application/x-www-form-urlencoded', 'Cookie': cookies, 'Host': '**************', 'Pragma': 'no-cache', 'Referer': 'http://**************', 'Upgrade-Insecure-Requests': '1', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0' } login_url = 'http://**************' login_data = { 'codeImage': input('請輸入驗證碼:'), 'uname': '**************', 'upass': '**************' } requests.post(login_url, data=login_data, headers=login_headers) res = requests.get('http://**************', headers=login_headers) reg_h = r'<option value=(.*?)>\d{4}-\d{2}-\d{2}' # 匹配可提供預約的hash value_h = re.findall(reg_h, res.text) """定時""" counter = 0 while (True): now = datetime.datetime.now() # 擷取當前系統時間 if now.hour == hour and now.minute == minute: break time.sleep(0.5) # print(now) counter = counter + 1 if counter == 240: res = requests.get('http://**************', headers=login_headers) reg_h = r'<option value=(.*?)>\d{4}-\d{2}-\d{2}' # 匹配可提供預約的hash reg_t = r'(\d{4}-\d{2}-\d{2})' # 匹配可提供預約的日期 value_h = re.findall(reg_h, res.text) value_t = re.findall(reg_t, res.text) with open('./con_log.txt', 'a') as fjs: fjs.write(eval(value_h[-1])+' '+value_t[-1]+' '+str(now)+' \n') fjs.close() print('儲存成功') counter = 0 return str(eval(value_h[-1]))def reservation(day_hash, cookies, stime, etime): reservation_data = { '_etime': etime, # 結束時間11點,其值為11*60=660 '_roomid': '1285b3ca77594b3095c7b89d4922553c', # 房間Id '_seatno': '', '_stime': stime, # 開始時間8點,其值為8*60=480 '_subject': '學習', # 研討主題 '_summary': '學習', # 研討大綱 'ruleId': day_hash, 'usercount': 3, # 預約人數 'users': '**************', # 學號 'UUID': '**************' } reservation_headers = { 'Accept': 'application/json, text/javascript, */*; q=0.01', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive', 'Content-Length': '239', 'Content-Type': 'application/json', 'Cookie': cookies, 'Host': '**************', 'Pragma': 'no-cache', 'Referer': 'http://**************', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0' } reservation_js = json.dumps(reservation_data) reservation_url = 'http://**************' status = requests.post(reservation_url, data=reservation_js, headers=reservation_headers) # print(stime, etime) # print(status) print(status.text)def main(): """預約策略一:11:20-20.40""" full_stime = ['1060', '870', '680'] full_etime = ['1240', '1050', '860'] """預約策略二:10:00-13:00;13:50-16:50;17:40-20:40""" stime = ['1060', '830', '600'] etime = ['1240', '1010', '780'] cookies = get_cookies() day_hash = login(cookies, 0, 0) # 設定定時時間 for i in range(0, 3): reservation(day_hash, cookies, stime[i], etime[i])if __name__ == '__main__': main()
實現效果
自從學了python,媽媽再也不用擔心我搶不到研習室了。在程式中加幾行定時的程式之後,便可以在00:00自動幫我預約研習室了。通過測試發現,預約時很大程度上是能夠約到房間的,例如在4-12號,約好三個時間段是用了7秒,但是在4-13號居然花了21秒,而且使得一個時間段被其他同學約走了。當然這個程式還需要進一步改進,實現完勝“手速”。
補在最後
還有不足,歡迎交流。