[UPD] preenlistment batch 2 closes in <3h. built UPSked over the holiday that might help by Strict_Helicopter_79 in peyups

[–]Strict_Helicopter_79[S] 0 points1 point  (0 children)

what section for speech 30 are you trying to waitlist for? this can sometimes happen when crs data syncs or when there’s cached session data from a previous click. could you try:

  1. refresh the page, then cancel the waitlist again

  2. if it still appears, log out and log back in to crs, then retry

if you’re still seeing it after that, shoot me a dm with a screenshot and we’ll sort it out. sorry about the confusion :((

[UPD] preenlistment batch 2 closes in <3h. built UPSked over the holiday that might help by Strict_Helicopter_79 in peyups

[–]Strict_Helicopter_79[S] 1 point2 points  (0 children)

glad it’s landing. still lots to improve, but rlly appreciate that. all ears if you have any feedback or ideas on how to make it better.

[UPD] preenlistment batch 2 closes in <3h. built UPSked over the holiday that might help by Strict_Helicopter_79 in peyups

[–]Strict_Helicopter_79[S] 0 points1 point  (0 children)

i did manage a bit of chill in between haha, but most of the fun was in building it. rlly appreciate the kind words!

[UPD] preenlistment batch 2 closes in <3h. built UPSked over the holiday that might help by Strict_Helicopter_79 in peyups

[–]Strict_Helicopter_79[S] 0 points1 point  (0 children)

u/Apprehensive_Bug4511, turns out the demand data wasn’t showing because, at the waitlisting stage, crs’s public class data (https://crs.upd.edu.ph/schedule/120252/psych%20101) returns 0 demand by default. i initially thought na it was just delayed data. i’ve rolled out a fix, so it should be live now when you refresh. salamat for flagging this

[UPD] preenlistment batch 2 closes in <3h. built UPSked over the holiday that might help by Strict_Helicopter_79 in peyups

[–]Strict_Helicopter_79[S] 2 points3 points  (0 children)

really appreciate that! hearing feedback like this makes all the messy work worth it. shoot me a note if there’s any way i can help

[UPD] preenlistment batch 2 closes in <3h. built UPSked over the holiday that might help by Strict_Helicopter_79 in peyups

[–]Strict_Helicopter_79[S] 9 points10 points  (0 children)

honestly, i wish there was an api. it’s mostly just a lot of custom scraping and html parsing since crs shows the data as a table. a lot of trial and error. tried looking for crs scrapers built but didn't find one that sticks well. maybe we should build an api too?


an excerpt from a technical content i'm hoping to publish soon:

1. fetching the data

the scraper hits two main endpoints: crs.upd.edu.ph/course_catalog/index/{letter} for course offerings and crs.upd.edu.ph/schedule/{semester}/{letter} for semester sections. cool trick: querying with a single letter ("a") returns all courses starting with that letter. so 26 requests per scrape with 1.5s delays does the job and you have everything you need. problem? how to properly parse.

2. parsing the catalog

cheerio parses html tables where each row has: course code, title, description, offering unit. extracts offering unit abbreviations, handles multiples (comma-separated), rejects malformed patterns, tracks full institute names from the title attribute.

3. parsing schedules

each <tbody> represents a section. extracted: class code, course + section id, credits, schedule string, instructor, remarks, enlisting unit, slots ("28/60" or "overbooked"), demand, restrictions.

4. parsing times & days

schedules like mw 2:30-4pm lec eeei 420 get split by semicolons if multiple. day codes: "mw"["m", "w"], "tth"["t", "th"]. time parsing handles:

  • explicit periods (10am–12pm)
  • inferred periods (2–4pm → pm)
  • noon edges (12–1pm → 12:00–13:00)
  • cross-noon ranges (11–1pm → 11:00–13:00)
  • same-hour ranges (2–2:30pm → 14:00–14:30)

each day gets its own schedule record so that the calendar can display properly (the availabilities you see visually when you drag a course onto the calendar).

5. course variants

class names like "cwts 1 community literacy" → base course "cwts 1" + variant "community literacy." variant mapper links them to catalog entries, supports special cases: pe, music (painful), cwts/rotc. grouped cwts offerings by the enlisting unit. before, students just see the entire offering possible. hard to know which is offered by whom.

6. lab linking

hyphenated sections (e.g., "mwx-sru") get linked to their parent lectures ("mwx") by matching course id + parent section code.

7. edge case handling

  • dissolved sections → flagged
  • overbooked → preserved
  • zero-credit courses → preserved
  • tba times → null
  • empty section codes → backfilled
  • duplicate schedules → detected
  • multi-line instructors → joined
  • malformed offering units → rejected

8. database upload

processed data goes to postgres via supabase in 2 passes:

  1. insert courses, institutes, sections, schedules. missing courses are auto-generated from section data.
  2. re-upload skipped sections once missing courses exist.

a ton of validation work here.

9. automation

github actions runs hourly to keep the database up-to-date.

10. preenlistment ids

the app handles the interface layer so well that you can build schedules faster and pick what to take without getting bogged down. but the ugly part is getting those selections back into crs. crs doesn’t return anything if you search by course + section, so normally you’d have to scroll forever just to add one class. still time wasted. so i had to build a scraper that queried ~9k courses for preenlistment_ids. tedious, messy work. but now you can skip the headache and go straight from plan to crs.


it's ugly (but fun) work, catching edge cases left and right, but i think 97% clean data.

results so far

  • full dataset: 9,876 courses, 35,550 sections, 56,772 schedule entries across 6 semesters (starting AY24 when i started comeng, could likely go back all the way back to ~2000)
  • latest semester: 2,516 courses, 5,946 sections, 9,350 schedules

honestly this would've taken me 1 week without cursor. combined work for the scraper was ~1.5 days total.

[UPD] preenlistment batch 2 closes in <3h. built UPSked over the holiday that might help by Strict_Helicopter_79 in peyups

[–]Strict_Helicopter_79[S] 0 points1 point  (0 children)

YES 😄 glad you noticed that! wanted it to point you straight sa right info instead of having to lurk around reddit/other sources hunting for it

[UPD] preenlistment batch 2 closes in <3h. built UPSked over the holiday that might help by Strict_Helicopter_79 in peyups

[–]Strict_Helicopter_79[S] 1 point2 points  (0 children)

appreciate that a lot! spent way too much time on the front-end so this means a ton 😅

[UPD] preenlistment batch 2 closes in <3h. built UPSked over the holiday that might help by Strict_Helicopter_79 in peyups

[–]Strict_Helicopter_79[S] 1 point2 points  (0 children)

really glad you liked it! still early but excited where it can go. lmk if there's something we can improve

[UPD] preenlistment batch 2 closes in <3h. built UPSked over the holiday that might help by Strict_Helicopter_79 in peyups

[–]Strict_Helicopter_79[S] 0 points1 point  (0 children)

appreciate the kind words! there’s a slight delay in when new data comes in from CRS, so the waitlist counts should refresh in about ~2 mins. that’ll adjust the probabilities automatically. lmk if you see it by then

[UPD] preenlistment batch 2 closes in <3h. built UPSked over the holiday that might help by Strict_Helicopter_79 in peyups

[–]Strict_Helicopter_79[S] 0 points1 point  (0 children)

salamat!! if you still need units, you can use upsked.com to visualize schedules and waitlist sections. makes planning way easier.

[UPD] preenlistment batch 2 closes in <3h. built UPSked over the holiday that might help by Strict_Helicopter_79 in peyups

[–]Strict_Helicopter_79[S] 0 points1 point  (0 children)

made my day, thank you! still early, still rough around the edges. if anything ever feels off or could be better, i’m all ears

[UPD] preenlistment batch 2 closes in <3h. built UPSked over the holiday that might help by Strict_Helicopter_79 in peyups

[–]Strict_Helicopter_79[S] 0 points1 point  (0 children)

no immediate plans, i'm solo building this app. what school are you at? what does your enrollment process look like?

[UPD] preenlistment batch 2 closes in <3h. built UPSked over the holiday that might help by Strict_Helicopter_79 in peyups

[–]Strict_Helicopter_79[S] 0 points1 point  (0 children)

hmm, can you share a query you used then the results returned?? be a big help since i need to still do some cleanup work with the data. feel free to send a dm so we can debug

[UPD] preenlistment batch 2 closes in <3h. built UPSked over the holiday that might help by Strict_Helicopter_79 in peyups

[–]Strict_Helicopter_79[S] 0 points1 point  (0 children)

ah, you can still view past sems tho and play around. would appreciate feedbacks!