Always test a scraper with
test=True before running it for real. Test mode runs your discover_files() method and shows you what files it found, without downloading anything.The SimpleScraper interface
Every scraper extendsSimpleScraper and implements one method: discover_files(). It returns a list of dicts, each with four required keys:
Dates must be in one of these ISO formats:
YYYY, YYYY-MM, YYYY-MM-DD, or YYYY-QN (for example, "2024-Q1"). Non-ISO dates are rejected at discovery time.
{ScraperName}Scraper — for example, KaufmanHallScraper.
Capability tiers
Choose the simplest approach that works for your source. Simpler scrapers are faster, cheaper, and more reliable.Direct HTTP
Use
get_html() or get_json() to fetch pages directly. Works for most public data portals where files are linked in standard HTML.AI browser automation
Use
self.browser_task() to describe what you want to find. An AI agent navigates the site and returns structured data. Good for dynamic or JS-heavy sites without writing selectors.Playwright browser
Set
needs_browser = True to get self.page, a Playwright sync Page. Use when you need precise, deterministic browser control — clicking tabs, filling forms, waiting for elements.Tier 1: Direct HTTP
The default — no extra configuration needed.get_html() returns a BeautifulSoup object; get_json() fetches and parses JSON.
Tier 2: AI browser automation
Callself.browser_task() with a plain-language description of what to find. Pass an output_schema to get back structured JSON. This works in any scraper — you don’t need needs_browser = True.
Tier 3: Playwright browser
Setneeds_browser = True to get self.page — a Playwright sync Page that starts on self.url with bot protection already cleared. Use this when you need to click through tabs, wait for dynamic content, or interact with forms.
Available in the scraper namespace
These are available without importing anything:
You can also define
SCRAPER_HEADERS on your class to add or override request headers for every request this scraper makes (merged with DEFAULT_HEADERS):
polars (use instead of pandas — pandas is not installed), requests, lxml, beautifulsoup4, pdfplumber, html5lib, xmltodict, tenacity, curl_cffi, openpyxl, xlrd, chardet, python-dateutil, and all Python standard library modules.
Testing and running a scraper
Always test before running for real.1
Create a workspace
2
Test your scraper code
Test mode runs The output shows how many files were found and previews the first five with their filenames, dates, and URLs.
discover_files() and shows you the files found — no downloads happen.3
Save the scraper code
Once the test output looks correct, save the code:
4
Run the scraper to download files
Render HTML pages as PDF
Some data sources only publish HTML tables with no downloadable files. Setrender_as_pdf = True on your scraper and all discovered URLs will be rendered to PDF by a headless browser and fed into the extraction pipeline.