From 929c95568011fe56b6fff48b55b65b51e0d1fccd Mon Sep 17 00:00:00 2001 From: Damian Cooper Date: Sun, 19 Apr 2026 20:20:42 +0100 Subject: [PATCH] fix: Match new Octopus page heading "Last Free Electricity sessions:" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Octopus updated the /free-electricity/ page heading from "Last Session:" to "⚡️Last Free Electricity sessions:⚡️", causing the website scraper's regex to miss all sessions and return 0. Broaden the regex to accept the optional "Free Electricity" phrase and plural "Sessions" for both "Next" and "Last" headings. Also clarify the misleading "Failed to fetch HTML content" log message — it previously fired whenever no sessions were extracted, even on a successful fetch. Now split into a real fetch-failure error and an informational log when the page simply has no sessions listed. Co-Authored-By: Claude Opus 4.7 (1M context) --- octofree/main.py | 4 +++- octofree/scraper_website.py | 7 ++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/octofree/main.py b/octofree/main.py index 6ac5dfb..fd3874c 100644 --- a/octofree/main.py +++ b/octofree/main.py @@ -722,8 +722,10 @@ def main(): save_last_extracted_sessions(current_sessions) logging.debug(f"💾 [STORAGE] Updated last_extracted_sessions.json with {len(current_sessions)} session(s)") - else: + elif html_content is None: logging.error("Failed to fetch HTML content.") + else: + logging.info("ℹ️ No sessions extracted from HTML (page may have no sessions listed yet)") if single_run: break diff --git a/octofree/scraper_website.py b/octofree/scraper_website.py index d2ab5c9..81b469a 100644 --- a/octofree/scraper_website.py +++ b/octofree/scraper_website.py @@ -65,7 +65,8 @@ def extract_sessions(html_content): sessions = [] session_type = None # Try to find "Next Sessions:" first (for multiple) - match = re.search(r'Next\s+Sessions?:', html_content, re.IGNORECASE) + # Octopus pages vary between "Next Sessions:" and "Next Free Electricity sessions:" + match = re.search(r'Next\s+(?:Free\s+Electricity\s+)?Sessions?:', html_content, re.IGNORECASE) if match: session_type = 'next' start_pos = match.end() @@ -86,8 +87,8 @@ def extract_sessions(html_content): found = re.findall(r'\d+(?:am|pm)?-\d+(?:am|pm)?,\s*\w+\s*\d+(?:st|nd|rd|th)?\s*\w+', part, re.IGNORECASE) sessions.extend(found) else: - # Check for "Last Session:" - match = re.search(r'Last\s+Session:', html_content, re.IGNORECASE) + # Check for "Last Session:" or "Last Free Electricity sessions:" + match = re.search(r'Last\s+(?:Free\s+Electricity\s+)?Sessions?:', html_content, re.IGNORECASE) if match: session_type = 'last' start_pos = match.end()