Created
February 14, 2026 18:09
-
-
Save zellux/cba602c7fa6a8b26e23bb0f9b299a8e5 to your computer and use it in GitHub Desktop.
Fetch San Mateo County Library preschooler events
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python3 | |
| """ | |
| Fetch San Mateo County Library events for preschoolers from the next 3 days. | |
| Scrapes https://smcl.bibliocommons.com/v2/events with audience filter | |
| for "Preschoolers (0-5 years old)" and a 3-day date window starting today. | |
| """ | |
| import requests | |
| from bs4 import BeautifulSoup | |
| from datetime import datetime, timedelta | |
| BASE_URL = "https://smcl.bibliocommons.com/v2/events" | |
| PRESCHOOLER_AUDIENCE_ID = "564274cf4d0090f742000011" | |
| HEADERS = { | |
| "User-Agent": ( | |
| "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) " | |
| "AppleWebKit/537.36 (KHTML, like Gecko) " | |
| "Chrome/120.0.0.0 Safari/537.36" | |
| ) | |
| } | |
| def fetch_events(days=3): | |
| today = datetime.now() | |
| end = today + timedelta(days=days - 1) | |
| params = { | |
| "audiences": PRESCHOOLER_AUDIENCE_ID, | |
| "startDate": today.strftime("%Y-%m-%d"), | |
| "endDate": end.strftime("%Y-%m-%d"), | |
| } | |
| resp = requests.get(BASE_URL, params=params, headers=HEADERS, timeout=30) | |
| resp.raise_for_status() | |
| soup = BeautifulSoup(resp.text, "html.parser") | |
| items = soup.find_all(class_="cp-events-search-item") | |
| events = [] | |
| for item in items: | |
| # Title | |
| title_tag = item.find(class_="cp-event-title") | |
| title = title_tag.get_text(strip=True) if title_tag else "N/A" | |
| # Link | |
| link_tag = item.find("a", attrs={"data-key": "event-link"}) | |
| link = link_tag["href"] if link_tag else "" | |
| # Date & time — use the screen-reader spans within cp-event-date-time | |
| date_time_span = item.find(class_="cp-event-date-time") | |
| if date_time_span: | |
| sr_spans = date_time_span.find_all(class_="cp-screen-reader-message") | |
| date_str = sr_spans[0].get_text(strip=True) if len(sr_spans) > 0 else "" | |
| time_str = sr_spans[1].get_text(strip=True) if len(sr_spans) > 1 else "" | |
| date_time = f"{date_str}, {time_str}" if date_str and time_str else date_str or time_str | |
| else: | |
| date_time = "" | |
| # Location — use the screen-reader span to get clean (non-duplicated) text | |
| location_tag = item.find(class_="cp-event-location-name") | |
| if location_tag: | |
| loc_sr = location_tag.find(class_="cp-screen-reader-message") | |
| if loc_sr: | |
| location = loc_sr.get_text(strip=True).replace("Event location: ", "") | |
| else: | |
| location = location_tag.get_text(strip=True) | |
| else: | |
| location = "N/A" | |
| # Description | |
| desc_tag = item.find(class_="cp-event-description") | |
| description = desc_tag.get_text(strip=True) if desc_tag else "" | |
| events.append({ | |
| "title": title, | |
| "date_time": date_time, | |
| "location": location, | |
| "description": description, | |
| "link": link, | |
| }) | |
| return events, today, end | |
| def main(): | |
| events, start, end = fetch_events() | |
| print(f"San Mateo County Library — Preschooler Events") | |
| print(f"{start.strftime('%A, %B %d')} through {end.strftime('%A, %B %d, %Y')}") | |
| print(f"{'=' * 70}") | |
| if not events: | |
| print("No events found for this date range.") | |
| return | |
| for i, evt in enumerate(events, 1): | |
| print(f"\n{i}. {evt['title']}") | |
| print(f" When: {evt['date_time']}") | |
| print(f" Where: {evt['location']}") | |
| if evt["description"]: | |
| # Wrap long descriptions | |
| desc = evt["description"] | |
| if len(desc) > 120: | |
| desc = desc[:117] + "..." | |
| print(f" About: {desc}") | |
| print(f" Link: {evt['link']}") | |
| print(f"\n{'=' * 70}") | |
| print(f"Total: {len(events)} events") | |
| if __name__ == "__main__": | |
| main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment