香港理工大学实验室定时预约

文章目录

  • 香港理工大学实验室定时预约
  • 简介
  • 接单价格
  • 软件界面
  • 网站预约界面
  • 代码

对爬虫、逆向感兴趣的同学可以查看文章,一对一小班教学(系统理论和实战教程)、提供接单兼职渠道: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.时间管…