香港理工大學實驗室定時預約

香港理工大學實驗室定時預約

文章目錄

  • 香港理工大學實驗室定時預約
  • 簡介
  • 接單價格
  • 軟件界面
  • 網站預約界面
  • 代碼

對爬蟲、逆向感興趣的同學可以查看文章,一對一小班教學(系統理論和實戰教程)、提供接單兼職渠道:https://blog.csdn.net/weixin_35770067/article/details/142514698

簡介

香港理工大學實驗室預約項目,由于平時預約人數較多,因此定制定時預約軟件,學校網頁非常簡單,一個簡單的post請求直接搞定。

接單價格

有第三方抽傭,個人到手660,供大家參考

軟件界面

在這里插入圖片描述

網站預約界面

在這里插入圖片描述

代碼

# -*- coding: utf-8 -*-
'''
@Time    : 2025-06-23 16:24
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple bs4
'''
import time
import warnings
from bs4 import BeautifulSoup
import requests
import tkinter as tk
from tkinter import ttk, messagebox, scrolledtext
import threading
from datetime import datetime, timedelta
import ctypes
import sys
warnings.filterwarnings('ignore')
def hide_console():"""隱藏控制臺窗口"""if sys.platform.startswith('win'):handle = ctypes.windll.kernel32.GetConsoleWindow()ctypes.windll.user32.ShowWindow(handle, 0)hide_console()def create_order(instrument, cookies, auth_token, reservation_details):"""Sends a POST request to create a reservation for the selected instrument."""# Dynamically set the URL and Referer based on the instrument choiceif instrument == "fNIRS1":target_url = "https://urfms.polyu.edu.hk/facilities/ubsn/instruments/NIRSport_2_1/single_reservations"referer_url = "https://urfms.polyu.edu.hk/facilities/ubsn/instruments/NIRSport_2_1/single_reservations/new"else:  # Default to fNIRS2target_url = "https://urfms.polyu.edu.hk/facilities/ubsn/instruments/NIRSport_2_2/single_reservations"referer_url = "https://urfms.polyu.edu.hk/facilities/ubsn/instruments/NIRSport_2_2/single_reservations/new"headers = {'Host': 'urfms.polyu.edu.hk','Cache-Control': 'max-age=0','Origin': 'https://urfms.polyu.edu.hk','Content-Type': 'application/x-www-form-urlencoded','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36','Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7','Sec-Fetch-Site': 'same-origin','Sec-Fetch-Mode': 'navigate','Referer': referer_url,  # Use the dynamic Referer'Cookie': cookies}data = {'authenticity_token': auth_token,'order_account': '2204','send_notification': '1','commit': 'Create',}data.update(reservation_details)try:res = requests.post(target_url, headers=headers, data=data, verify=False, timeout=5)  # Use the dynamic URLres.raise_for_status()return res.textexcept requests.exceptions.RequestException:return ""class ReservationApp:def __init__(self, root):self.root = root# --- Variables ---self.instrument_var = tk.StringVar(value="fNIRS2")  # Default selectionself.start_date_var = tk.StringVar(value="13 Jul 2025")self.start_hour_var = tk.StringVar(value="9")self.start_min_var = tk.StringVar(value="00")self.start_meridian_var = tk.StringVar(value="AM")self.end_date_var = tk.StringVar(value="13 Jul 2025")self.end_hour_var = tk.StringVar(value="10")self.end_min_var = tk.StringVar(value="00")self.end_meridian_var = tk.StringVar(value="AM")self.duration_display_var = tk.StringVar(value="1:00")self.cookie_var = tk.StringVar()self.auth_token_var = tk.StringVar()self.schedule_time_var = tk.StringVar(value=f"{(datetime.now() + timedelta(minutes=1)).strftime('%H:%M:%S')}")self.status_var = tk.StringVar(value="Status: Idle")self._update_title()  # Set initial titleself.root.geometry("850x420")  # Adjusted height for the new frameself.create_widgets()self.create_log_window()def _update_title(self):"""Updates the main window title based on the instrument selection."""selected_instrument = self.instrument_var.get()self.root.title(f"Reservation Scheduler {selected_instrument}")def create_log_window(self):self.log_window = tk.Toplevel(self.root)self.log_window.title("Live HTML Log")self.log_window.geometry("800x600")self.log_text = scrolledtext.ScrolledText(self.log_window, wrap=tk.WORD, state=tk.DISABLED)self.log_text.pack(expand=True, fill='both')self.log_window.protocol("WM_DELETE_WINDOW", self.log_window.withdraw)self.log_window.withdraw()def update_status(self, message):self.status_var.set(message)def log_to_gui(self, message):self.log_text.config(state=tk.NORMAL)self.log_text.insert(tk.END, message)self.log_text.see(tk.END)self.log_text.config(state=tk.DISABLED)def schedule_reservation(self):# Get all required values from GUIinstrument = self.instrument_var.get()cookies = self.cookie_var.get()auth_token = self.auth_token_var.get()schedule_time_str = self.schedule_time_var.get()if not cookies or not auth_token:messagebox.showerror("Invalid Input", "Cookie and Authenticity Token fields cannot be empty.")returntry:target_time = datetime.strptime(schedule_time_str, '%H:%M:%S').time()schedule_dt = datetime.combine(datetime.now().date(), target_time)if schedule_dt < datetime.now(): schedule_dt += timedelta(days=1)start_dt = schedule_dt - timedelta(seconds=5)delay = (start_dt - datetime.now()).total_seconds()if delay < 0:messagebox.showerror("Invalid Time", "Scheduled time is in the past.")returnexcept ValueError:messagebox.showerror("Invalid Format", "Schedule time must be in HH:MM:SS format.")returntry:duration_str = self.duration_display_var.get()h, m = map(int, duration_str.split(':')) if ':' in duration_str else (0, int(duration_str))total_minutes = h * 60 + mexcept ValueError:messagebox.showerror("Invalid Input", "Duration format is incorrect.")returnreservation_details = {'reservation[reserve_start_date]': self.start_date_var.get(),'reservation[reserve_start_hour]': self.start_hour_var.get(),'reservation[reserve_start_min]': self.start_min_var.get(),'reservation[reserve_start_meridian]': self.start_meridian_var.get(),'reservation[reserve_end_date]': self.end_date_var.get(),'reservation[reserve_end_hour]': self.end_hour_var.get(),'reservation[reserve_end_min]': self.end_min_var.get(),'reservation[reserve_end_meridian]': self.end_meridian_var.get(),'reservation[duration_mins]_display': self.duration_display_var.get(),'reservation[duration_mins]': str(total_minutes),}self.schedule_button.config(state=tk.DISABLED)self.update_status(f"Status: Scheduled for {schedule_dt.strftime('%Y-%m-%d %H:%M:%S')}. Waiting...")task_thread = threading.Thread(target=self._execute_task,args=(delay, instrument, cookies, auth_token, reservation_details), daemon=True)task_thread.start()def _execute_task(self, delay, instrument, cookies, auth_token, reservation_details):time.sleep(delay)self.root.after(0, self.update_status, f"Status: Executing for {instrument}... Check log.")self.root.after(0, self.log_window.deiconify)self.root.after(0, lambda: self.log_to_gui(f"--- Starting Reservation Attempts for {instrument} ---\n"))start_time = time.time()success = Falsewhile time.time() - start_time < 60:response_html = create_order(instrument, cookies, auth_token, reservation_details)timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')log_entry = f"\n{'=' * 80}\nATTEMPT TIMESTAMP: {timestamp}\n{'=' * 80}\n"if response_html:soup = BeautifulSoup(response_html, 'html.parser')log_entry += soup.prettify()if not soup.find('div', class_='errorExplanation222222'):self.root.after(0, self.update_status, "Status: Success! Reservation created.")self.root.after(0, lambda: messagebox.showinfo("Success", "Reservation created successfully!"))self.root.after(0, lambda: self.log_to_gui("\n\n--- RESERVATION SUCCESSFUL ---"))success = Trueelse:log_entry += "--- [INFO] No response from server or network error ---"self.root.after(0, self.log_to_gui, log_entry)if success: breaktime.sleep(0.2)if not success:self.root.after(0, self.update_status, "Status: Finished. 60-second window passed.")self.root.after(0, lambda: self.log_to_gui("\n\n--- 60-SECOND EXECUTION WINDOW FINISHED ---"))self.root.after(0, lambda: self.schedule_button.config(state=tk.NORMAL))def create_widgets(self):main_frame = ttk.Frame(self.root, padding="10")main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))# --- Instrument Selection Frame ---inst_frame = ttk.LabelFrame(main_frame, text="Select Instrument", padding=(10, 5))inst_frame.grid(row=0, column=0, columnspan=7, sticky=(tk.W, tk.E), pady=(0, 10))ttk.Radiobutton(inst_frame, text="fNIRS1", variable=self.instrument_var, value="fNIRS1",command=self._update_title).pack(side=tk.LEFT, padx=5)ttk.Radiobutton(inst_frame, text="fNIRS2", variable=self.instrument_var, value="fNIRS2",command=self._update_title).pack(side=tk.LEFT, padx=5)# --- Main content frame ---content_frame = ttk.Frame(main_frame)content_frame.grid(row=1, column=0, columnspan=7)ttk.Label(content_frame, text="Start Time", font=('Helvetica', 10, 'bold')).grid(row=0, column=0, sticky=tk.W,pady=2)ttk.Entry(content_frame, textvariable=self.start_date_var, width=15).grid(row=0, column=1)ttk.Combobox(content_frame, textvariable=self.start_hour_var, values=list(range(1, 13)), width=4).grid(row=0,column=2,padx=5)ttk.Combobox(content_frame, textvariable=self.start_min_var, values=[f"{i:02d}" for i in range(0, 60, 15)],width=4).grid(row=0, column=3)ttk.Combobox(content_frame, textvariable=self.start_meridian_var, values=["AM", "PM"], width=4).grid(row=0,column=4,padx=5)ttk.Label(content_frame, text="End Time", font=('Helvetica', 10, 'bold')).grid(row=1, column=0, sticky=tk.W,pady=2)ttk.Entry(content_frame, textvariable=self.end_date_var, width=15).grid(row=1, column=1)ttk.Combobox(content_frame, textvariable=self.end_hour_var, values=list(range(1, 13)), width=4).grid(row=1,column=2,padx=5)ttk.Combobox(content_frame, textvariable=self.end_min_var, values=[f"{i:02d}" for i in range(0, 60, 15)],width=4).grid(row=1, column=3)ttk.Combobox(content_frame, textvariable=self.end_meridian_var, values=["AM", "PM"], width=4).grid(row=1,column=4,padx=5)ttk.Label(content_frame, text="Duration", font=('Helvetica', 10, 'bold')).grid(row=0, column=5, padx=(20, 0),sticky=tk.S)ttk.Entry(content_frame, textvariable=self.duration_display_var, width=12).grid(row=0, column=6, padx=5,sticky=tk.S)ttk.Label(content_frame, text='Enter "total minutes" or "hours:minutes"').grid(row=1, column=5, columnspan=2,padx=(20, 0), sticky=tk.N,pady=(0, 10))ttk.Label(content_frame, text="Cookie", font=('Helvetica', 10, 'bold')).grid(row=2, column=0, sticky=tk.W,pady=5)ttk.Entry(content_frame, textvariable=self.cookie_var, width=90).grid(row=2, column=1, columnspan=6,sticky=tk.W, padx=5)ttk.Label(content_frame, text="Authenticity Token", font=('Helvetica', 10, 'bold')).grid(row=3, column=0,sticky=tk.W, pady=5)ttk.Entry(content_frame, textvariable=self.auth_token_var, width=90).grid(row=3, column=1, columnspan=6,sticky=tk.W, padx=5)ttk.Label(content_frame, text="Schedule Time (HH:MM:SS)", font=('Helvetica', 10, 'bold')).grid(row=4, column=0,sticky=tk.W,pady=10)ttk.Entry(content_frame, textvariable=self.schedule_time_var, width=15).grid(row=4, column=1, sticky=tk.W)self.schedule_button = ttk.Button(content_frame, text="Schedule Reservation", command=self.schedule_reservation)self.schedule_button.grid(row=5, column=5, columnspan=2, sticky=tk.E, pady=10)status_bar = ttk.Label(self.root, textvariable=self.status_var, relief=tk.SUNKEN, anchor=tk.W)status_bar.grid(row=1, column=0, sticky=(tk.W, tk.E))if __name__ == '__main__':root = tk.Tk()app = ReservationApp(root)root.mainloop()sticky=tk.E, pady=10)status_bar = ttk.Label(self.root, textvariable=self.status_var, relief=tk.SUNKEN, anchor=tk.W)status_bar.grid(row=1, column=0, sticky=(tk.W, tk.E))if __name__ == '__main__':root = tk.Tk()app = ReservationApp(root)root.mainloop()

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/88854.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/88854.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/88854.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Spring AI 項目實戰(十七):Spring Boot + AI + 通義千問星辰航空智能機票預訂系統(附完整源碼)

系列文章 序號文章名稱1Spring AI 項目實戰(一):Spring AI 核心模塊入門2Spring AI 項目實戰(二):Spring Boot + AI + DeepSeek 深度實戰(附完整源碼)3Spring AI 項目實戰(三):Spring Boot + AI + DeepSeek 打造智能客服系統(附完整源碼)4

STM32CubeMX+CLion 使用ARM_CMSIS_DSP

安裝 參考&#xff1a; 【CLion開發stm32】如何使用DSP庫 - 未知的奇跡 - 博客園 實際上這樣配置會出一點小問題&#xff0c;現對其修改 1. 項目根目錄下新建 DSP_LIB文件夾 將目錄STM32CubeMX\Repository\STM32Cube_FW_G4_V1.6.1\Drivers\CMSIS\DSP下的Include文件夾和So…

深入解析C#接口實現的兩種核心技術:派生繼承 vs 顯式實現

—— 如何優雅解決多接口沖突問題 &#x1f50d; 核心概念速覽 派生成員實現 類通過繼承基類方法隱式滿足接口實現需求 interface IIfc1 { void PrintOut(string s); }class MyBaseClass { // 基類實現方法 public void PrintOut(string s) > Console.WriteLine($"Cal…

鴻蒙項目構建配置

鴻蒙項目構建配置 參考文檔 深入鴻蒙開發之后&#xff0c;一般會遇到以下幾個問題。 每次編譯的時候需要手動配置不同的 versionCode 和 versionName&#xff1b;在使用 git 管理代碼的時候&#xff0c;不同的人或者不在同一臺電腦上&#xff0c;dev eco 這個編譯器需要經常…

os.machine()詳解

核心功能返回硬件架構 返回字符串表示系統的硬件架構&#xff0c;常見值包括&#xff1a; x86_64&#xff1a;64 位 x86 架構&#xff08;Intel/AMD&#xff09;armv7l&#xff1a;32 位 ARM 架構&#xff08;如樹莓派 3B&#xff09;aarch64&#xff1a;64 位 ARM 架構&#x…

linux-shell腳本

linux-shell腳本一、什么是shell腳本&#xff1f;二、為什么要學習shell腳本&#xff1f;三、腳本執行的方式3.1 bash test.sh3.2 ./test.sh3.3 source test.sh3.4 . test.sh四、變量的使用4.1 變量定義與使用4.2 避免變量混淆4.3 位置變量for循環和位置變量的結合案例4.4 read…

【嵌入式】51單片機學習筆記-Keil5軟件安裝教程

00. 目錄 文章目錄00. 目錄01. Keil C51概述02. Keil C51下載03. Keil C51安裝04. Keil C51注冊05. 附錄01. Keil C51概述 Keil C51 是德國Keil公司&#xff08;現被ARM收購&#xff09;開發的嵌入式開發工具&#xff0c;專注于8051單片機的C語言和匯編開發。它是μVision IDE…

ai之 ubuntu本地安裝mineru2.1.0

MinerU 目錄 一、更新內容概述寫在前面的話:總體來看,2.0版本升級為全新的 VLM 解析模式,更優于以前的基礎解析方式。二、MinerU 安裝部署下面使用源碼來進行環境安裝。注意:當前狀態說明推薦解決方案如果是下載插件慢可以 指定阿里源三、MinerU 使用1. 在線體驗2. 命令行使…

華為昇騰NPU與NVIDIA CUDA生態兼容層開發實錄:手寫算子自動轉換工具鏈(AST級代碼遷移方案)

點擊 “AladdinEdu&#xff0c;同學們用得起的【H卡】算力平臺”&#xff0c;H卡級別算力&#xff0c;按量計費&#xff0c;靈活彈性&#xff0c;頂級配置&#xff0c;學生專屬優惠。 當國產AI芯片崛起遭遇生態壁壘&#xff0c;如何實現CUDA算子到昇騰平臺的無損遷移成為關鍵挑…

GraphRAG Docker化部署,接入本地Ollama完整技術指南:從零基礎到生產部署的系統性知識體系

相關推薦&#xff1a;Umi-OCR 的 Docker安裝&#xff08;win制作鏡像&#xff0c;Linux&#xff08;Ubuntu Server 22.04&#xff09;離線部署&#xff09; 一、技術背景與發展脈絡 1.1 RAG技術演進歷程分析 檢索增強生成&#xff08;RAG&#xff09;技術的發展經歷了三個重要…

Android 系統默認Launcher3 菜單模式雙層改成單層-3

Android 系統默認自帶Launcher3 菜單都為雙層模式 各手機大廠的Launcher的菜單模式都為單層 如何將launcher3的菜單模式改為單層模式 mOverviewPanel = (ViewGroup) findViewById(R.id.overview_panel); mWidgetsButton = findViewById(R.id.widget_butto…

基于k8s環境下pulsar高可用測試和擴縮容(上)

#作者&#xff1a;任少近 文章目錄Pulsar高可用測試1. 測試目的2.當前集群環境說明3. 模擬故障場景4.功能驗證5.結論Pulsar高可用測試 1. 測試目的 本次測試旨在驗證 Apache Pulsar 在某個 Broker 節點宕機&#xff08;down&#xff09;的情況下&#xff0c;是否仍能正常提供…

JAVA JVM垃圾收集

JVM 垃圾收集是 Java 自動內存管理的核心&#xff0c;本文通過圍繞 “哪些是垃圾、何時回收、怎么回收、用啥回收器、內存咋分配” 等展開一、判斷哪些是垃圾引用計數法&#xff1a;給對象分配引用計數器&#xff0c;有引用時計數加 1&#xff0c;引用失效減 1 &#xff0c;計數…

UniHttp生命周期鉤子與公共參數實戰:打造智能天氣接口客戶端

> 通過靈活的生命周期鉤子,我們讓HTTP請求從機械操作進化為智能對話 在現代應用開發中,高效處理HTTP請求是核心能力。本文將深入探索UniHttp框架中強大的**HttpApiProcessor生命周期鉤子**,并演示如何利用其**公共參數填充機制**優雅地處理第三方接口。我們將以百度天…

C++高級編程,類模版成員函數類外實現

#include <iostream> #include <string>//類模版成員函數類外實現 template<class T1,class T2> class Person {//Person構造函數 public:Person(T1 name,T2 age);// {// this->m_Namename;// this->m_Ageage;// }//Person的成員函數void show…

[Linux入門 ] RAID存儲技術概述

一.數據存儲架構 1??存儲系統 2??主機系統 3??互連部件 4??存儲設備與磁盤陣列 二.數據存儲技術 1??數據冗余技術 2??RAID 0 3??RAID 1 4??RAID 2 5??RAID 3 6??RAID 4 三.基于硬件的RAID磁盤陣列 1??陣列卡(RAID控制器) 2??陣列卡種類 …

AI繪畫生成章邯全身像提示詞

融合了歷史元素和視覺表現力&#xff0c;力求生成符合秦末名將章邯身份的全身像。 核心提示詞結構&#xff1a; [主體描述]&#xff0c;[服裝/盔甲細節]&#xff0c;[姿態/神情]&#xff0c;[武器]&#xff0c;[背景/氛圍]&#xff0c;[風格/質量]&#xff0c;[參數] 選項一&…

iOS高級開發工程師面試——關于優化

iOS高級開發工程師面試——關于優化 一、TableView 有什么好的性能優化方案?二、界面卡頓和檢測你都是怎么處理?三、談談你對離屏渲染的理解?四、如何降低APP包的大小?五、日常如何檢查內存泄露?六、APP啟動時間應從哪些方面優化?一、TableView 有什么好的性能優化方案?…

線性基學習筆記

我們稱一個線性空間 V V V 的一個極大線性無關集為這個線性空間的線性基,簡稱基。 異或線性基 在異或空間下,我們定義如下內容。 異或和 設 S S

ESP-Timer入門(基于ESP-IDF-5.4)

主要參考資料&#xff1a; ESP 定時器&#xff08;高分辨率定時器&#xff09;: https://docs.espressif.com/projects/esp-idf/zh_CN/stable/esp32s3/api-reference/system/esp_timer.html 目錄ESP-Timer與FreeRTOS TimerAPI 使用1.創建定時器2.啟動定時器3.管理定時器4.時間管…