Malaysia Crawler - Selangor Turf Club
Version 3 · Replace the pending Selangor live-test status with complete 12-race pre/post artifact and handoff evidence.
Malaysia Crawler - Selangor Turf Club
Last reviewed: 2026-08-08 AEST
Identity and scope
- Source ID:
my_selangor_turf_club - Adapter:
formcrawler.sources.my.selangor_turf_club.SelangorTurfClubAdapter - Launcher:
scripts\crawl_selangor_range.bat - Discipline: Thoroughbred (
T) - Jurisdiction/racing code:
MY/MYS - Allowed hosts:
selangorturfclub.comandwww.selangorturfclub.com - FormCrawler preserves raw whole-meeting HTML and parses only the identifiers required for discovery.
Acquisition contract
- Pre-race control:
https://www.selangorturfclub.com/horse-racing/local-racing/race-card/with_sft_club=selangor, the selected year, and compact meeting date. - Post-race target: the same route and date with
result=1&tab=1. - Method: public date-addressable HTML.
- One pre-race control discovers exactly one same-date results target.
- URL validation rejects non-HTTPS, unapproved hosts/paths, fragments, duplicate or unexpected query fields, non-Selangor clubs, and year/date mismatches.
Readiness and safety
- Both phases require the requested meeting date to be the selected source option and require a published Selangor meeting with horses.
- Pre-race validation requires sire, dam, and trainer columns.
- Results validation requires win time, finish time, and dividend columns.
- The shared serialized host limiter, retry ceiling, immutable storage, metadata, queue ledger, and FormParser handoff apply.
Operation
scripts\crawl_selangor_range.bat 2026-07-26 2026-07-26
The optional third argument limits discovered targets per date; omit it for the complete meeting/day. The equivalent generic command is:
python scripts\formcrawler.py capture-date-range --source my_selangor_turf_club --start 2026-07-26 --end 2026-07-26
Breeding and supplementary data
The racecard exposes sire and dam fields. Parent country suffixes, foal year/date, and a stable public horse-detail URL were not fully verified in the inspected source and remain explicitly unconfirmed. The club also publishes an events calendar and general local-racing information.
Validation status
Implemented and fully live-verified.
The focused four-test adapter suite, full 152-test repository suite with ResourceWarning promoted to an error, Python compilation, and git diff --check passed on 2026-08-08.
Complete-day evidence
The unlimited 26 July 2026 run completed on attempt 1 with captured=2, retry_wait=0, and failed=0:
- Pre-race racecard: 805,712 bytes, all 12 race sections, artifact
d35c578784afee9b956728d4159e2880, SHA-256df02afb0d70c9c95073a67dae269bee4fef75a88a08b0fe1e6297709aa93ca7e. - Post-race results: 545,777 bytes, all 12 race sections, artifact
7e14d2db00641645ed11a951839ca4b6, SHA-2569985a1638d271f5be1d15dc7b847a594e996cd413f34d0288e9b5010ae38368e. - Both responses were direct HTTP 200 captures. Recomputed hashes matched the queue ledger and metadata; artifact IDs, content/metadata URIs, and both FormParser handoffs matched.
Module changelog
- 2026-08-08: Completed an unlimited 12-race pre/post day on attempt 1 and verified both hashes, metadata records, and FormParser handoffs.
- 2026-08-08: Re-reviewed the acquisition contract, readiness rules, launcher, source boundaries, and regression coverage before a complete pre/post day test.
- 2026-08-08: Source researched, acquisition contract classified, breeding/profile availability recorded, and implementation/live-validation status published.