From 7192d6df000adeb3314b39c9e1a07b7a68248f4f Mon Sep 17 00:00:00 2001 From: iwtba4188 Date: Sat, 29 Apr 2023 02:12:52 +0800 Subject: [PATCH] # [Features] Async Method Optimization - Uses an async method to send multiple POST requests to increase the success rate of reservations. --- README.md | 2 +- reservation/main.py | 191 +++++++++++++++++++++++++------------------- 2 files changed, 108 insertions(+), 85 deletions(-) diff --git a/README.md b/README.md index ff3a21d..dc044cd 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # NTHU_alb_reserve ## Getting Start -Download the exe file [here](https://github.com/iwtba4188/reservation_of_nthualb/releases/tag/v2.1). +Download the exe file [here](https://github.com/iwtba4188/reservation_of_nthualb/releases/tag/v3.0). In the setting file, you need to fill the information as below. ```json diff --git a/reservation/main.py b/reservation/main.py index eaa6aba..880e515 100644 --- a/reservation/main.py +++ b/reservation/main.py @@ -2,6 +2,7 @@ import json import datetime import time +import asyncio from colorama import init, Fore, Style @@ -11,98 +12,120 @@ from L_util import crawling_PHPSESSID, log, get_server_time -DEBUG = False +loop = asyncio.get_event_loop() -init(convert=True) # colorama init -TODAY = ( - int(datetime.datetime.now().strftime("%Y")), - int(datetime.datetime.now().strftime("%m")), - int(datetime.datetime.now().strftime("%d"))) +async def post_reservation(url, headers, json): + # response = await requests.post(url=url, headers=headers, json=json) + time.sleep(1) + response = await loop.run_in_executor(None, lambda: requests.post(url=url, headers=headers, json=json)) -RESERVE_TIME = datetime.datetime(year=TODAY[0], month=TODAY[1], day=TODAY[2]) \ - + datetime.timedelta(days=5 if not DEBUG else 4) + html_data = BeautifulSoup(response.text, "html.parser") -TOMORROW_TIME = datetime.datetime(year=TODAY[0], month=TODAY[1], day=TODAY[2])\ - + datetime.timedelta(days=1) - -RESERVE_TIME = str(int(RESERVE_TIME.timestamp())) - -URL = "https://nthualb.url.tw/reservation/api/reserve_field" - - -try: - with open("headers.json") as headers_file: - raw_header = json.load(headers_file) - post_header = raw_header["post_header"] - get_header = raw_header["get_header"] -except FileNotFoundError: - sys.stderr.write("\"header.json\" not found, please add it and try again.\n") -except Exception as err: - sys.stderr.write(f"Unexpected Error. \nErr: {err}\n") - - -try: - with open("settings.json") as setting_file: - setting = json.load(setting_file) -except FileNotFoundError: - sys.stderr.write("\"setting.json\" not found, please add it and try again.\n") -except Exception as err: - sys.stderr.write(f"Unexpected Error. \nErr: {err}\n") - - -try: - ID = setting["id"] + '\t' - PASSWORD = setting["password"] - - PHPSESSID = crawling_PHPSESSID(ID, PASSWORD) - - TIME1 = int(setting["time1"])-1 - FIELD1 = int(setting["field1"])-1 - TIME2 = int(setting["time2"])-1 - FIELD2 = int(setting["field2"])-1 - - post_header["cookie"] = "PHPSESSID=" + str(PHPSESSID) - get_header["cookie"] = "PHPSESSID=" + str(PHPSESSID) -except ValueError as err: - sys.stderr.write(f"setting format is wrong, please check and try again.\nError: {err}\n") -except Exception as err: - sys.stderr.write(f"Unexpected Error. \nErr: {err}\n") - - -log("get server time") -SERVER_TIME = get_server_time(URL=URL, get_header=get_header) -NEED_TO_WAIT = int(TOMORROW_TIME.timestamp()) - int(SERVER_TIME.timestamp()) - -if not DEBUG: - log(f"time of the server is {SERVER_TIME}") - log(f"waiting for next day, sleep {NEED_TO_WAIT}+2 secs") - time.sleep(NEED_TO_WAIT+2) - -for info in [(TIME1, FIELD1), (TIME2, FIELD2)]: - post_header["content-length"] = f"{42+len(str(info[0]))+len(str(info[1]))}" - - data = { - "time": str(info[0]), - "field": str(info[1]), - "date": RESERVE_TIME - } - - log(f"start reserving {data}") - log("sending POST request") - raw_data = requests.post(url=URL, headers=post_header, json=data) - html_data = BeautifulSoup(raw_data.text, "html.parser") - - if raw_data.status_code == 200 and str(html_data) == "ok": - log(f"reserved {data} {Fore.GREEN+Style.BRIGHT}successfully{Fore.RESET+Style.RESET_ALL}," + if response.status_code == 200 and str(html_data) == "ok": + log(f"reserved {json} {Fore.GREEN+Style.BRIGHT}successfully{Fore.RESET+Style.RESET_ALL}," f"see more detail in nthualb website.") elif str(html_data) is None: - log(f"reserved {data} {Fore.RED+Style.BRIGHT}FAIL{Fore.RESET+Style.RESET_ALL}." + log(f"reserved {json} {Fore.RED+Style.BRIGHT}FAIL{Fore.RESET+Style.RESET_ALL}." f"Because {Fore.RED+Style.BRIGHT}the session isn't work " f"(i.e. you didn't login successfully){Fore.RESET+Style.RESET_ALL}.") else: - log(f"reserved {data} {Fore.RED+Style.BRIGHT}FAIL{Fore.RESET+Style.RESET_ALL}." + log(f"reserved {json} {Fore.RED+Style.BRIGHT}FAIL{Fore.RESET+Style.RESET_ALL}." f"Because {Fore.RED+Style.BRIGHT}{html_data}{Fore.RESET+Style.RESET_ALL}.") -log(f"{Style.BRIGHT}FIN{Style.RESET_ALL}") -input("Input any value to exit...") + +def main(): + DEBUG = False + + init(convert=True) # colorama init + + TODAY = ( + int(datetime.datetime.now().strftime("%Y")), + int(datetime.datetime.now().strftime("%m")), + int(datetime.datetime.now().strftime("%d"))) + + RESERVE_TIME = datetime.datetime(year=TODAY[0], month=TODAY[1], day=TODAY[2]) \ + + datetime.timedelta(days=5 if not DEBUG else 4) + + TOMORROW_TIME = datetime.datetime(year=TODAY[0], month=TODAY[1], day=TODAY[2])\ + + datetime.timedelta(days=1) + + RESERVE_TIME = str(int(RESERVE_TIME.timestamp())) + + URL = "https://nthualb.url.tw/reservation/api/reserve_field" + + try: + with open("headers.json") as headers_file: + raw_header = json.load(headers_file) + post_header = raw_header["post_header"] + get_header = raw_header["get_header"] + except FileNotFoundError: + sys.stderr.write( + "\"header.json\" not found, please add it and try again.\n") + except Exception as err: + sys.stderr.write(f"Unexpected Error. \nErr: {err}\n") + + try: + with open("settings.json") as setting_file: + setting = json.load(setting_file) + except FileNotFoundError: + sys.stderr.write( + "\"setting.json\" not found, please add it and try again.\n") + except Exception as err: + sys.stderr.write(f"Unexpected Error. \nErr: {err}\n") + + try: + ID = setting["id"] + '\t' + PASSWORD = setting["password"] + + PHPSESSID = crawling_PHPSESSID(ID, PASSWORD) + # PHPSESSID = "" + + TIME1 = int(setting["time1"])-1 + FIELD1 = int(setting["field1"])-1 + TIME2 = int(setting["time2"])-1 + FIELD2 = int(setting["field2"])-1 + + post_header["cookie"] = "PHPSESSID=" + str(PHPSESSID) + get_header["cookie"] = "PHPSESSID=" + str(PHPSESSID) + except ValueError as err: + sys.stderr.write( + f"setting format is wrong, please check and try again.\nError: {err}\n") + except Exception as err: + sys.stderr.write(f"Unexpected Error. \nErr: {err}\n") + + log("get server time") + SERVER_TIME = get_server_time(URL=URL, get_header=get_header) + NEED_TO_WAIT = int(TOMORROW_TIME.timestamp()) - \ + int(SERVER_TIME.timestamp()) + + tasks = [] + for info in [(TIME1, FIELD1), (TIME2, FIELD2)]: + post_header["content-length"] = f"{42+len(str(info[0]))+len(str(info[1]))}" + + data = { + "time": str(info[0]), + "field": str(info[1]), + "date": RESERVE_TIME + } + + log(f"start reserving {data}") + log("sending POST request") + # raw_data = requests.post(url=URL, headers=post_header, json=data) + for _ in range(5): + tasks.append(loop.create_task( + post_reservation(URL, post_header, data))) + + if not DEBUG: + log(f"time of the server is {SERVER_TIME}") + log(f"waiting for next day, sleep {NEED_TO_WAIT}+1 secs") + time.sleep(NEED_TO_WAIT+1) + + loop.run_until_complete(asyncio.wait(tasks)) + + log(f"{Style.BRIGHT}FIN{Style.RESET_ALL}") + input("Input any value to exit...") + + +if __name__ == "__main__": + main()