Innovation Port Sports Facilities Automatic Reservation.
This is an automatically translated post by LLM. The original post is in Chinese. If you find any translation errors, please leave a comment to help me improve the translation. Thanks!
Project Background
The Innovation Port badminton venue has a high demand for reservations every day. The online reservation system opens around 8:40 am every morning, and the opening time is not fixed. These factors have caused a lot of trouble for manual venue reservations, so it is considered to automate the venue reservation process with a script.
Project Concept
The sports venue reservation system needs to confirm the identity through the SJTU authentication system. Consider carrying the identity information after logging in to access the sports venue reservation system. The identity authentication here refers to the library seat reservation script by Guoguo:
XJTU Library Seat Reservation Script - Requests Library | Guoguo's Blog (gwyxjtu.github.io)
In addition, the sports venue reservation system is open from 8:40 to 21:40, not all day. Therefore, connectivity detection is required for reservation control.
The project process architecture is shown below:
- Check connectivity to confirm whether the sports venue reservation system is open.
- Use the sports venue query API to obtain all venue information.
- Set certain conditions to filter out the venues that need to be reserved.
- Obtain identity information through SJTU authentication.
- Send a reservation POST request to the venue reservation system to make a reservation.
Project Implementation
1. Connectivity Detection
Use the urlopen
library in the requests
library to perform connectivity detection:
1 | def check_net(testserver): |
The waiting code for the detection in the main function is as follows:
1 | while True: |
2. Query Venue Information
First, create a session
to perform subsequent access.
Access through session
ensures continuity of access.
1 | import requests |
Next is to query the venue information. Taking the Innovation Port table tennis venue as an example (because there are many unreserved venues, which is convenient for testing ^_^).
By observing the link and conducting tests, it can be inferred that
each venue is identified by an id
, which is used for
subsequent venue information queries and reservation applications.
By checking the page request, you can find that sending a
GET
request to /findtime.html
can query the
required information.
However, the information returned by this request is incomplete, and
an event id
is not returned. This event id
is
needed for subsequent reservations. After multiple searches, the
following api
was finally found on the tennis court
reservation page:
From this api
, three key pieces of information can be
found:
- id: the identifier of each time slot for each venue
- status: venue status, 1 for available, 2 for reserved
- stockid: identifier of each venue
Therefore, you can use this api
to query the venue
information for each venue. The implementation is as follows:
1 | def get_avaliable_seats(court_id,date): |
3. Filter the Required Venues
This step is relatively easy, just filter the sessions obtained in the previous step.
1 | def get_suitable_seats(seat_list,time): |
4. Obtain Identity Information through SJTU Authentication
Here, Guoguo's library seat reservation script is referenced XJTU
Library Seat Reservation Script - Requests Library | Guoguo's Blog
(gwyxjtu.github.io). The only difference is that the application to
which it jumps after logging in to the authentication system is
different. In the browser, jump from the sports venue reservation system
to the authentication page to query the page cookie to obtain the
corresponding appid
.
Fill in the corresponding appid
in the appropriate
location to perform login and jump. The login part of the code is as
follows:
1 | def encrypt_pwd(raw_pwd, publicKey='0725@pwdorgopenp'): |
5. Reserve the Venue
The last step is to reserve the venue. The manual reservation process is as follows:
- Select the venue.
- Click the confirm venue button.
- Jump to a new page to confirm the venue information.
- Click the continue reservation button to display the verification code.
- Enter the verification code and confirm.
- Return the reservation status information (success or failure).
By examining and analyzing the page requests in these processes, it
is found that only two processes are related to successful reservations:
① obtaining and recognizing the verification code, and ② submitting a
reservation post
with the verification code.
Taking the table tennis venue reservation page as an example, the verification code generation method is as follows:
That is, access the address http://202.117.17.144/login/yzm.html?+(any float random number) to obtain the verification code image.
The post
request can be located step by step through
nested functions:
It can be seen that the final submitted post
request
address is /order/book
, with two parameters, one is the
string converted from the reservation information, and the other is the
verification code. Below are the methods to obtain these two
parameters.
There are many parameters in the reservation information, but many
parameters are null
and do not need to be considered. The
parameters that need to be constructed are as follows:
1 | param={"activityPrice":0, //Price information, keep it unchanged |
The verification code part can be verified online through some online
recognition api
, and the verification code is relatively
simple and has a high success rate. The api
address used in
this project is: https://aicode.my-youth.cn
At this point, the venue can be successfully reserved. The reservation code is as follows:
1 | def order(seat_info): |
Project Summary
During the development process, I also took some detours. For example, in the implementation of the reservation stage, I studied the logic of page jumping for a long time. But in fact, only the last request sent by the last page is effective. When writing the script, pay attention to the result-oriented rather than the process-oriented. This avoids many unnecessary developments.