python實(shí)現(xiàn)圖書(shū)館研習(xí)室自動(dòng)預(yù)約功能
本文為大家分享了python實(shí)現(xiàn)圖書(shū)館研習(xí)室自動(dòng)預(yù)約的具體代碼,供大家參考,具體內(nèi)容如下
簡(jiǎn)介
現(xiàn)在好多學(xué)校為學(xué)生提供了非常良好的學(xué)習(xí)環(huán)境,通常體現(xiàn)在自習(xí)教室的設(shè)施設(shè)備上。對(duì)此不得不提一句的就是我們學(xué)校的圖書(shū)館,隨著新圖書(shū)館的修建,館內(nèi)也設(shè)置了多個(gè)功能區(qū),每層分為A、B、C、D四個(gè)區(qū)域,由南北連廊相連,中間由旋轉(zhuǎn)樓梯貫通一至五層。A區(qū)為自修區(qū);B區(qū)和C區(qū)為藏閱一體的社會(huì)科學(xué)和自然科學(xué)書(shū)庫(kù);D區(qū)為專(zhuān)項(xiàng)功能區(qū),包含影視廳、數(shù)字媒體創(chuàng)客體驗(yàn)中心、智慧培訓(xùn)教室、云桌面電子閱覽室等;B、C區(qū)東西連廊設(shè)有大小十二間研習(xí)室;南北連廊設(shè)有休閑閱讀區(qū)。
上面那段我是從圖書(shū)館官網(wǎng)上抄的,不過(guò)真的得為學(xué)校的圖書(shū)館點(diǎn)個(gè)贊。回歸本篇文章正題,學(xué)校免費(fèi)為廣大師生提供了舒適優(yōu)良設(shè)備齊全的研習(xí)室。但是這些研習(xí)室是需要進(jìn)行網(wǎng)上預(yù)約才能夠進(jìn)入使用,每天的00:00開(kāi)啟下一天的預(yù)約,因此要想約到一個(gè)時(shí)間段(3小時(shí))的研習(xí)室,可謂得“挑燈夜戰(zhàn)”。當(dāng)然,在這個(gè)過(guò)程中手速快將有巨大的優(yōu)勢(shì)。如果晚上休息的早,手速又不快,基本上就別想預(yù)約到研習(xí)室了。剛剛好最近學(xué)了一點(diǎn)python爬蟲(chóng),就打算用爬蟲(chóng)幫我完成這個(gè)艱巨的任務(wù)了。哈哈哈哈?。╬s:防止惡意訪問(wèn),所有鏈接就不放了哈)
python實(shí)現(xiàn)思路
想想思路還是挺簡(jiǎn)單的,無(wú)非就是登錄賬號(hào)、查找房間、提交預(yù)約。那就讓我們?cè)囋嚳矗?/p>
登錄賬號(hào)
首先打開(kāi)我們研習(xí)室預(yù)約的登錄界面,鏈接為:U2FsdGVkX19NdfJkghN54Msvy1zl7AucRur/ct0nz4orPI7uLkSDsvuFMgr0fGcO
rn9Z/f8h3bds9w==

好吧,這第一步登錄賬號(hào)就非常考驗(yàn)我這個(gè)新手了,不過(guò)不能慫。通過(guò)參考其他一些大佬使用的方法,就是打開(kāi)firefox的firebug(ctrl+shift+e)查看網(wǎng)絡(luò)情況,在這個(gè)情況下進(jìn)行一次正常的登錄。

可以看到我們這里有個(gè)post,到時(shí)便可以使用python中requests.post方法。

為了能夠成功的登錄,要隱藏自己是個(gè)爬蟲(chóng)的身份,在消息頭中,可以看到我們的請(qǐng)求頭,只要將參數(shù)都復(fù)制過(guò)來(lái),組成自己的headers = {…}來(lái)欺騙服務(wù)器。

看一下參數(shù)這一頁(yè),這里的表單數(shù)據(jù)只有三個(gè),分別對(duì)應(yīng)著驗(yàn)證碼、賬號(hào)和密碼。將這里的參數(shù)復(fù)制過(guò)來(lái),就可以組成我們的data = {…}。其中需要我們的注意的就是這個(gè)驗(yàn)證碼,無(wú)論是人工“自”能識(shí)別,還是機(jī)器自動(dòng)識(shí)別,都需要將驗(yàn)證碼保存為本地文件。如此一來(lái),就有了一個(gè)問(wèn)題,每訪問(wèn)一次服務(wù)器,驗(yàn)證碼就會(huì)變換?,F(xiàn)在讓我們好好捋捋思路,首先我們得獲得驗(yàn)證碼并將其保存在本地,這就需要訪問(wèn)一次服務(wù)器,最后我們要提交我們的參數(shù)進(jìn)行登錄,這又再一次訪問(wèn)了服務(wù)器,這次的驗(yàn)證碼和我們獲取的驗(yàn)證碼已經(jīng)不是同一個(gè)驗(yàn)證碼了。在剛剛開(kāi)始的嘗試中我無(wú)論如何無(wú)法登錄服務(wù)器,就是兩次的驗(yàn)證碼不匹配。如何實(shí)現(xiàn)第一次獲取的驗(yàn)證碼和提交時(shí)的驗(yàn)證碼相一致呢?
這里就需要同一個(gè)cookie在上面的幾個(gè)圖中,我們都能看到有個(gè)cookie值。要保證同步,這里就需要做到,我們獲取驗(yàn)證碼時(shí)的cookie值和提交賬號(hào)密碼時(shí)的cookie值一致。因此,在我的程序中,我先做的一個(gè)步驟時(shí)先獲取一個(gè)cookie值,然后將這個(gè)cookie值作為headers中的一個(gè)參數(shù)。登錄的思路就是這樣了,補(bǔ)充一句,這里的驗(yàn)證碼我是自己手動(dòng)識(shí)別的>﹏<。
查找房間
這個(gè)步驟其實(shí)是一個(gè)無(wú)用的步驟,為什么有這個(gè)步驟,按照人為預(yù)約習(xí)慣,我們會(huì)產(chǎn)生怎么一個(gè)步驟,但是如果使用爬蟲(chóng),只要成功登錄之后就可以直接提交預(yù)約的表單。當(dāng)然,如果要使得自動(dòng)預(yù)約程序更加智能,便可以添加這個(gè)步驟,可以查看那些房間是還可以預(yù)約的,在這里自定義的補(bǔ)充一些規(guī)則。我就略過(guò)了。。。
提交預(yù)約
同登錄一樣,我們也手動(dòng)的提交一次,去查看網(wǎng)絡(luò)情況,便可以用python模擬這一個(gè)過(guò)程。在這里我就不在貼圖進(jìn)行解釋?zhuān)@里提交也是用requests.post的方法。不過(guò)一點(diǎn)要注意的是,這里的headers和登錄時(shí)的headers是不一樣的,所以在此提醒各位,如果在其他類(lèi)似的預(yù)約程序中可以注意看看不同內(nèi)容post時(shí)的headers是否一致。我在這里就被坑了一會(huì)。
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
#
# @Version : 1.0
# @Time : 2018/4/10
# @Author : 圈圈烴
# @File : reservation_4.py
import requests
import re
import json
import datetime
import time
def get_cookies():
"""獲得cookies"""
url = 'http://**************'
s = requests.session()
s.get(url)
ck_dict = requests.utils.dict_from_cookiejar(s.cookies) # 將jar格式轉(zhuǎn)化為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('驗(yàn)證碼保存成功')
return ck
def 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('請(qǐng)輸入驗(yàn)證碼:'),
'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}' # 匹配可提供預(yù)約的hash
value_h = re.findall(reg_h, res.text)
"""定時(shí)"""
counter = 0
while (True):
now = datetime.datetime.now() # 獲取當(dāng)前系統(tǒng)時(shí)間
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}' # 匹配可提供預(yù)約的hash
reg_t = r'(\d{4}-\d{2}-\d{2})' # 匹配可提供預(yù)約的日期
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, # 結(jié)束時(shí)間11點(diǎn),其值為11*60=660
'_roomid': '1285b3ca77594b3095c7b89d4922553c', # 房間Id
'_seatno': '',
'_stime': stime, # 開(kāi)始時(shí)間8點(diǎn),其值為8*60=480
'_subject': '學(xué)習(xí)', # 研討主題
'_summary': '學(xué)習(xí)', # 研討大綱
'ruleId': day_hash,
'usercount': 3, # 預(yù)約人數(shù)
'users': '**************', # 學(xué)號(hào)
'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():
"""預(yù)約策略一:11:20-20.40"""
full_stime = ['1060', '870', '680']
full_etime = ['1240', '1050', '860']
"""預(yù)約策略二: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) # 設(shè)定定時(shí)時(shí)間
for i in range(0, 3):
reservation(day_hash, cookies, stime[i], etime[i])
if __name__ == '__main__':
main()
實(shí)現(xiàn)效果
自從學(xué)了python,媽媽再也不用擔(dān)心我搶不到研習(xí)室了。在程序中加幾行定時(shí)的程序之后,便可以在00:00自動(dòng)幫我預(yù)約研習(xí)室了。通過(guò)測(cè)試發(fā)現(xiàn),預(yù)約時(shí)很大程度上是能夠約到房間的,例如在4-12號(hào),約好三個(gè)時(shí)間段是用了7秒,但是在4-13號(hào)居然花了21秒,而且使得一個(gè)時(shí)間段被其他同學(xué)約走了。當(dāng)然這個(gè)程序還需要進(jìn)一步改進(jìn),實(shí)現(xiàn)完勝“手速”。

補(bǔ)在最后
還有不足,歡迎交流。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 用python-webdriver實(shí)現(xiàn)自動(dòng)填表的示例代碼
- python+webdriver自動(dòng)化環(huán)境搭建步驟詳解
- selenium+python自動(dòng)化測(cè)試之使用webdriver操作瀏覽器的方法
- python使用webdriver爬取微信公眾號(hào)
- python實(shí)現(xiàn)圖書(shū)館搶座(自動(dòng)預(yù)約)功能的示例代碼
- Python Requests模擬登錄實(shí)現(xiàn)圖書(shū)館座位自動(dòng)預(yù)約
- 使用Python webdriver圖書(shū)館搶座自動(dòng)預(yù)約的正確方法
相關(guān)文章
python實(shí)現(xiàn)MongoDB的雙活示例
本文主要介紹了python實(shí)現(xiàn)MongoDB的雙活示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02
python數(shù)據(jù)分析之如何刪除value=0的行
這篇文章主要給大家介紹了關(guān)于python數(shù)據(jù)分析之如何刪除value=0的行的相關(guān)資料,文中通過(guò)實(shí)例代碼以及圖文介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Python具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2022-12-12
Python實(shí)現(xiàn)異常檢測(cè)LOF算法的示例代碼
這篇文章主要為大家介紹一個(gè)經(jīng)典的異常檢測(cè)算法:局部離群因子(Local Outlier Factor),簡(jiǎn)稱(chēng)LOF算法。感興趣的小伙伴可以跟隨小編一起了解一下2022-03-03
python使用布隆過(guò)濾器的實(shí)現(xiàn)示例
這篇文章主要介紹了python使用布隆過(guò)濾器的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08
python讀取一個(gè)目錄下所有txt里面的內(nèi)容方法
今天小編就為大家分享一篇python讀取一個(gè)目錄下所有txt里面的內(nèi)容方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-06-06
python實(shí)現(xiàn) 獲取b站主播直播間 粉絲牌信息的方法
這篇文章主要介紹了python實(shí)現(xiàn) 獲取b站主播直播間粉絲牌信息 ,用于實(shí)現(xiàn)通過(guò)牌子逆向查主播信息這個(gè)功能,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-02-02
淺談Python描述數(shù)據(jù)結(jié)構(gòu)之KMP篇
這篇文章主要介紹了Python描述數(shù)據(jù)結(jié)構(gòu)之KMP篇,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09
python實(shí)現(xiàn)windows倒計(jì)時(shí)鎖屏功能
這篇文章主要介紹了python實(shí)現(xiàn)windows倒計(jì)時(shí)鎖屏功能,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-07-07

