Auto_courseGrabber: automating the Zhengfang course selection page
正方教务系统自动抢课脚本(多省市高校实测):并发选课、课程名/课号检索、时间/教师筛选、换课、定时开抢与可视化控制台。JavaScript helper for Zhengfang course enrollment.
At a glance
- What is it?
- Auto_courseGrabber is a JavaScript helper injected into the course selection page of the Zhengfang academic administration system used by many Chinese universities. It watches for free teaching classes, applies time and teacher filters, can schedule a start time, and can trade one enrolled course for another, all inside the browser tab you are already logged into.
- Who is it for?
- Auto_courseGrabber is a practical tool for students on a Zhengfang system who can prepare their course list in advance, filter by teaching class, and accept that the script only sees what the page has already loaded. It is the wrong tool if your target course sits behind the load more control, if the school's enrolment rules forbid automation, or if you need any guarantee that a seat is still there when the request lands.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 87 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A script you paste into your own logged-in page
The delivery mechanism is old fashioned and worth understanding before anything else. You log into your university's academic system, open the self-service course selection page, use the page's own search to load the courses you want into the list, and then paste the contents of courseGrabber.js into the browser developer console. The script attaches a control panel to the top right of the page, and if you close it you can bring it back by typing showGrabberUI() in the console.
There is a second installation route, a bookmarklet. The documentation shows the shape of it, a short JavaScript snippet that creates a script element pointing at a URL you supply and appends it to the document, so that clicking the bookmark on the selection page loads the script. That approach works but it needs the script hosted somewhere, and it means the code arrives from a remote URL rather than from the file you reviewed.
The script itself lives in one file at the root of the repository, and the project also ships a tests directory, a docs directory with coverage and usage notes, a web structure folder and a compatibility report template under the issue templates. The primary language is JavaScript, the licence is MIT, the default branch is master, and the recent release line is v2.3.0, v2.3.1 and v2.3.2, all published in January 2026, with the last push on 2026-07-28.
There is also a tutorial video on Bilibili and one on Douyin, which tells you the intended audience is students rather than developers.
The hard limit: only what the page has already loaded
This is the constraint that decides whether the tool works for you, and the documentation is unusually clear about it. The script can only recognise and operate courses that are already present in the current page DOM. If the course you want is still hidden behind the load more control at the bottom of the page, or only appears after another query or another page of results, the script cannot find it from the course number alone.
The recommended workflow follows directly. Use the page's own search first, and an exact course number is the recommended search, then confirm the course is visible in the list before starting the script.
The script depends on a specific page structure. It looks for the course card structure in the Zhengfang page, for example the panel heading class and the hidden input carrying the teaching class identifier:
.panel-heading.kc_head
input[name="kch_id"]If a school's page is customised and that structure is different, the script will not find teaching classes, and the project's answer is to submit a sanitised compatibility report rather than to start sending requests harder. That is a sensible rule, and it is also an admission that this is a script tied to one vendor's markup, not a general automation tool.
The documentation draws a distinction that is easy to miss, between expanding course information and loading more courses. Expanding course information reveals the teaching class details of a course that is already on the page. Loading more courses brings additional courses onto the page, and the script cannot do that.
Expanding the cards, and why it costs you milliseconds
The filters only work when the course information card is expanded, because that is where the times and the teachers are shown. The Zhengfang system rebuilds the DOM tree when it refreshes the list with jQuery, which collapses the cards that were open, so the script proactively triggers a click to expand the target course cards after a refresh.
That expansion has a performance cost, and the cost lands exactly where it hurts, in the latency of the enrolment requests. The script therefore disables the behaviour automatically in two cases, controlled by the CLICK2EXPEND_ENABLED flag. The first is when the page holds only one course and that course is the target, because the system expands the first course in the list by itself after a refresh. The second is when neither a time filter nor a teacher filter is enabled, since the expansion would end immediately anyway but might still introduce a small delay that affects how fast requests are sent.
That is a good example of the script being honest about its own behaviour. An automatic helper that silently slows itself down would be worse than one that tells you why it is skipping a step.
The other part of the model is per-course status tracking. Each course is tracked independently, and the panel shows the run state, the number of attempts and the number of successes, with a log area that reports events in colour. The state vocabulary is specific: a teaching class with spare capacity was found, a teaching class was skipped because it failed a filter, there was a time conflict with an already selected course, the selection succeeded, or the request failed.
Filters for weekdays, periods, weeks and teachers
The filter system is the part of the tool with lasting value, because it encodes a preference you could not otherwise express to the enrolment page.
A time filter takes keywords for the weekday, for example Monday or Wednesday, for the class periods, for example periods 1 to 2 or periods 11 to 12, and for the week range, for example weeks 1 to 8 or odd weeks. A teacher filter takes a name, or a professional title such as lecturer or professor. Multiple keywords are allowed and the rule is that any one matching is enough.
Filters can be global, applying to every course, or set per course, and the two can be combined. The interface lets you add a course by code, give it a priority, optionally attach a time filter and a teacher filter, and edit the filters later through a button on the course row. The priority number is smaller-is-higher, and the concurrency mode uses it to decide which course is attempted first.
There is also a scripted route, through the API surface exposed on the grab object:
grab.addCourse('23286514', 1)
grab.removeCourse('23286514')
grab.status()
grab.debug()The console API is the better route if you want a repeatable setup, since the array of course codes, priorities and filters can be written down once and pasted in, rather than retyped into a form for every course. A time filter is written as a list of weekday, period and week keywords, and a teacher filter as a list of names or titles, so a filter that accepts Monday and Wednesday alongside periods 1 to 2 is a single array in the course definition.
Swapping a course means giving up a seat first
The swap feature is the most interesting and the most dangerous part of the tool, and the documentation is direct about the risk.
The scenario is described as riding two horses at once. You hold course B, but course A is the one you want, so the idea is to drop B and grab A when A has a free place. The implementation is a field labelled replace course, and when you fill it in, the script listens for the moment and performs the sequence automatically.
The warning that follows is the important sentence. Because grabbing course A requires dropping course B first, there is a risk that after B is dropped, A has no free place. The documentation attributes that risk to the other students using the same script, which is a neat summary of the problem: the tool wins seats by being faster, and being faster shifts the odds for everyone else in the queue.
This is the point where a reader should decide for themselves whether to use it at all. The mechanics are a sequence of state changes against a system with a seat limit, and there is no undo. Everything else in the tool is a convenience on top of a request you could have made yourself, but this one changes what you already hold in exchange for something you might not get.
The project does at least document the trade honestly, and it asks users to respect the rules of their own institution and to avoid setting an excessively short check interval, which is the polite version of do not hammer the server.
Timing, tunables and the batch controls
The scheduling feature is straightforward. You pick a start time, set it, and a countdown is displayed until it elapses, at which point the script starts on its own. You can cancel a scheduled start, and the same thing is available from the console:
grab.start()
grab.schedule('2025-12-19 14:00:00')
grab.cancelSchedule()
grab.stop()The tunables live at the top of the script, and they are the numbers to think about before a real enrolment round. The check interval is the polling period in milliseconds, the maximum attempts caps how many tries are made, the maximum consecutive failures is the point at which the script gives up on a course, and the concurrency flag switches between trying all courses at once and working through them by priority. The documentation describes the concurrent mode as more efficient and better suited to several courses, and the sequential mode as more stable and better suited to an unstable network.
The concurrent and sequential split is a real trade-off rather than a preference. Concurrent mode puts every course in flight at the same time, which minimises the time to seat but multiplies the number of simultaneous requests. Sequential mode makes one request path at a time, which is gentler on a flaky connection and on the server, at the cost of taking longer to work through the priority list.
The panel can be minimised, dragged to any position on the screen, and shows its logs in real time.
Compatibility is graded by evidence, not asserted
The documentation is unusually careful about a question that similar projects usually answer loosely, which is which universities are supported.
Three levels of evidence are distinguished. A university whose official recent material states it uses the Zhengfang teaching or course selection platform is confirmed as being on the platform. A university shown as a customer on the vendor's own site is a vendor customer, which the documentation is careful to say does not mean the course selection page of that university is compatible with the script. The only third level, community tested, means a report was submitted with the university, the system version or page features, the script version, the date and the result, and only that level can honestly be called tested.
The practical advice is to check the selection page for course cards and teaching class information before running anything, and to consult the coverage document in the repository for the per-university list, which is a separate file from the README for good reason. The documentation also answers the question of what to do when a university is neither confirmed nor tested, which is to check the page features and to prefer the community tested records.
The maintenance picture is short and healthy. The repository is not archived, the last push was on 2026-07-28, and the release line moved through v2.3.0, v2.3.1 and v2.3.2 in January 2026. The licence is MIT, so the code can be read, modified and redistributed, and the compatibility report template in the issue templates gives a concrete way to help the next person whose university is not on the list yet.
Editorial conclusion
Auto_courseGrabber is a practical tool for students on a Zhengfang system who can prepare their course list in advance, filter by teaching class, and accept that the script only sees what the page has already loaded. It is the wrong tool if your target course sits behind the load more control, if the school's enrolment rules forbid automation, or if you need any guarantee that a seat is still there when the request lands. Before you use it, read the usage notes, check the page for the course card structure the script depends on, and set a check interval the server can absorb rather than the fastest one you can.
Frequently asked questions
How do I load Auto_courseGrabber on the course selection page?
Log into your academic system, open the self-service course selection page, use the page search to load the target courses, and paste the contents of courseGrabber.js into the browser developer console. The control panel appears in the top right, and showGrabberUI() in the console brings it back if you close it.
Why can the script not find my course?
It can only see courses that are already loaded into the current page DOM. If the course is still behind the load more control at the bottom, or only appears after a further query, the script cannot find it from the course number. Search by exact course number first and confirm the course is visible in the list.
Can the script filter by teacher and class time?
Yes. A time filter takes weekday, class period and week range keywords, and a teacher filter takes a name or a title such as lecturer or professor. Filters can be global or set per course, and multiple keywords are allowed, with any one match being enough.
Is using a course selection script allowed at my university?
The project asks users to comply with their own institution's rules, to avoid setting too short a check interval, and to test the script before the real enrolment round. Different universities have different rules about opening times, enrolment conditions and request frequency, so the answer comes from your own school rather than from the tool.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/ceilf6-auto-coursegrabber)Was this useful?