Files
swehockey/testdata/schedule_legacy_playoffs.html
T
Mats Tornberg 6b701819ca Deterministic swehockey.se schedule crawler
One HTTP GET per season, no browser: the page is server-rendered, so every row
arrives in one response and the extraction becomes a pure function of the HTML.

- layouts[] declares one profile per version of the site's table (modern and
  legacy), each identified by its header row, so a new version of the page is a
  new profile plus a fixture instead of a guess.
- The table is located by header signature, not by a CSS path.
- Every cell is shape-checked, and facts the site renders twice (desktop and
  mobile date, time in the tooltip) must agree.
- Cross-field invariants: periods sum to the score, ids are unique, played games
  always have an event link and unplayed ones never do.
- Output is sorted by date, time and id, so it does not inherit the site's row
  order, and it carries no fetch timestamp: same HTML, same bytes.
- Drift is a typed error and exit code 3, with the header it actually found.
- Tests run on committed HTML fixtures and golden JSON; TestLive is opt-in.

Verified over the full SHL archive: 27/27 seasons, 2119 games, 1779 played.
2026-09-27 08:47:25 +00:00

34 lines
5.4 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><title>SHL | stats.swehockey.se</title></head>
<body>
<h1>SHL</h1>
<div id="groupStandingResultContent" class="row"><table class="tblWrapper table table-borderless"><tr><td class="tdWrapper"><table class="tblBorderNoPad"><tr><td class="tdTblBorder"><table class="tblContent"><tr><th colspan="3" class="tdTitle"><h2>Schedule and Results</h2></th><th class="tdTitle d-none d-sm-table-cell" /><th class="tdTitle d-none d-md-table-cell" /><th colspan="2" class="tdTitleRight d-none d-sm-table-cell">
Last update: 2014-04-14 14:19</th><th colspan="2" class="tdTitleRight d-table-cell d-sm-none" /></tr><tr><th class="tdHeader d-none d-sm-table-cell">Round</th><th class="tdHeader">Date</th><th class="tdHeader">Game</th><th class="tdHeader">Result</th><th class="tdHeader d-none d-sm-table-cell" /><th class="tdHeader d-none d-md-table-cell" style="text-align:right">Spectators</th><th class="tdHeader">Venue</th></tr><tr><td class="tdOdd standardPaddingTop d-none d-sm-table-cell">1</td><td class="tdOdd standardPaddingTop d-none d-sm-table-cell" style="white-space: nowrap;"><div class="dateLink"><span href="#" class="lnkTooltip" title="90011001">2014-03-10 19:00</span></div></td><td class="tdOdd standardPaddingTop">HV 71
 - 
Leksands IF<br /><i>Eighth final 1</i></td><td class="tdOdd standardPaddingTop" style="white-space: nowrap;"><a href="&#xD;&#xA; javascript:openonlinewindow('/Game/Events/205038','')&#xD;&#xA; ">4 - 2</a></td><td class="tdOdd standardPaddingTop d-none d-sm-table-cell" style="white-space: nowrap;">
(1-0, 1-1, 2-1)
</td><td class="tdOdd standardPaddingTop d-none d-md-table-cell" style="text-align: right">6923</td><td class="tdOdd standardPaddingTop">Kinnarps Arena</td></tr><tr><td class="tdNormal d-none d-sm-table-cell">
 
</td><td class="tdNormal standardPaddingTop d-none d-sm-table-cell" style="white-space: nowrap;"><div class="dateLink"><span href="#" class="lnkTooltip" title="90011002">2014-03-10 19:00</span></div></td><td class="tdNormal standardPaddingTop">Linköpings HC
 - 
MODO Hockey<br /><i>Eighth final 2</i></td><td class="tdNormal standardPaddingTop" style="white-space: nowrap;"><a href="&#xD;&#xA; javascript:openonlinewindow('/Game/Events/205039','')&#xD;&#xA; ">4 - 0</a></td><td class="tdNormal standardPaddingTop d-none d-sm-table-cell" style="white-space: nowrap;">
(1-0, 3-0, 0-0)
</td><td class="tdNormal standardPaddingTop d-none d-md-table-cell" style="text-align: right">5853</td><td class="tdNormal standardPaddingTop">Cloetta Center</td></tr><tr><td class="tdOdd paddingTop d-none d-sm-table-cell">2</td><td class="tdOdd paddingTop d-none d-sm-table-cell" style="white-space: nowrap;"><div class="dateLink"><span href="#" class="lnkTooltip" title="90011003">2014-03-12 19:00</span></div></td><td class="tdOdd paddingTop">Leksands IF
 - 
HV 71<br /><i>Eighth final 1</i></td><td class="tdOdd paddingTop" style="white-space: nowrap;"><a href="&#xD;&#xA; javascript:openonlinewindow('/Game/Events/205040','')&#xD;&#xA; ">2 - 1</a></td><td class="tdOdd paddingTop d-none d-sm-table-cell" style="white-space: nowrap;">
(0-1, 1-0, 1-0)
</td><td class="tdOdd paddingTop d-none d-md-table-cell" style="text-align: right">6018</td><td class="tdOdd paddingTop">Tegera Arena</td></tr><tr><td class="tdNormal d-none d-sm-table-cell">
 
</td><td class="tdNormal standardPaddingTop d-none d-sm-table-cell" style="white-space: nowrap;"><div class="dateLink"><span href="#" class="lnkTooltip" title="90011004">2014-03-12 19:00</span></div></td><td class="tdNormal standardPaddingTop">MODO Hockey
 - 
Linköpings HC<br /><i>Eighth final 2</i></td><td class="tdNormal standardPaddingTop" style="white-space: nowrap;"><a href="&#xD;&#xA; javascript:openonlinewindow('/Game/Events/205041','')&#xD;&#xA; ">4 - 5</a></td><td class="tdNormal standardPaddingTop d-none d-sm-table-cell" style="white-space: nowrap;">
(2-0, 2-1, 0-3, 0-1)
</td><td class="tdNormal standardPaddingTop d-none d-md-table-cell" style="text-align: right">5526</td><td class="tdNormal standardPaddingTop">Fjällräven Center</td></tr><tr><td class="tdOdd paddingTop d-none d-sm-table-cell">3</td><td class="tdOdd paddingTop d-none d-sm-table-cell" style="white-space: nowrap;"><div class="dateLink"><span href="#" class="lnkTooltip" title="90011005">2014-03-13 19:00</span></div></td><td class="tdOdd paddingTop">Leksands IF
 - 
HV 71<br /><i>Eighth final 1</i></td><td class="tdOdd paddingTop" style="white-space: nowrap;"><a href="&#xD;&#xA; javascript:openonlinewindow('/Game/Events/205042','')&#xD;&#xA; ">2 - 4</a></td><td class="tdOdd paddingTop d-none d-sm-table-cell" style="white-space: nowrap;">
(0-3, 0-0, 2-1)
</td><td class="tdOdd paddingTop d-none d-md-table-cell" style="text-align: right">6462</td><td class="tdOdd paddingTop">Tegera Arena</td></tr></table></td></tr></table></td></tr></table></div>
</body>
</html>