clippercard: The Guerilla API for Public Transit

How a fragile web scraper survived for over a decade to provide the developer access that a major transit agency refused to build.

6 min read • View on GitHub • More from anthonywu

A subway turnstile constructed entirely out of tangled, messy wire and duct tape. A pristine, glowing transit card slides smoothly through the reader slot, representing the messy reality of web scraping providing a clean interface.
A clean interface built on top of a chaotic foundation.

I encourage the staff of MTA reading this project to see this effort as a nudge for a public and official API. The moment they put up an API that obsoletes this project, I will happily direct followers to the official solution.

Anthony Wu, Creator · anthonywu/clippercard
Key Takeaways

The API That Shouldn't Exist

Most open-source projects exist to solve a technical problem. clippercard exists to solve a political one. It is a "web-scraper-as-an-API" built to bridge the gap between the Metropolitan Transportation Commission’s (MTC) closed ecosystem and the needs of San Francisco Bay Area developers. The goal is not just utility, but leverage.

Hedcut portrait of Anthony Wu.

This explicit design philosophy—building a tool with the sole intention of rendering it obsolete—frames the repository as a form of digital activism. It provides the programmatic access to transit balances and history that users demand, while daring the transit authority to shut it down.

Simulating the Browser

Beneath the surface, clippercard is an exercise in rigorous state management. Because the source website lacks a semantic structure, the Python script must perfectly mimic a human browsing session. In clippercard/client.py, the ClipperCardWebSession inherits from requests.Session to maintain authentication cookies.

The true complexity lies in bypassing basic security measures without triggering alarms. The script fetches the login page, extracts a dynamically generated CSRF token from a hidden input field, and posts the credentials. It then caches the resulting HTML "soup" to prevent redundant network calls, minimizing the load on the MTC servers and reducing the risk of rate-limiting.

The stateful scraping pipeline transforms messy, non-semantic HTML into structured data objects.

The Art of the Immortal Scraper

Web scrapers are notoriously fragile; they break the moment a target website changes a class name or nested div. Yet, clippercard has survived for over a decade. The secret to its longevity is its testing strategy.

The repository relies heavily on a tests/data/ directory packed with static HTML snapshots of the Clipper website. These offline fixtures allow the parser to be continuously regression-tested against known layouts without hitting live servers or requiring real user credentials. It is a fossil record of web design, preserving the exact state needed to ensure the extraction engine remains functional.

A scientist in a lab coat carefully brushing dust off a perfectly preserved, fossilized computer monitor embedded in a slab of rock. The monitor displays a crude website layout.
Static HTML fixtures act as a fossil record, freezing the website's state for offline regression testing.

Scraping the Web vs. Reading the Chip

The approach taken by clippercard stands in stark contrast to hardware-level integrations. For example, the popular Flipper Zero firmware includes an NFC parser written in C that interacts directly with the Mifare DESFire chip inside the physical transit card.

Featureclippercard (Python)Flipper Zero (C Firmware)
Access MethodWeb Scraping via HTTPDirect NFC Hardware Read
Data SourceGlobal Account DatabaseLocal Chip Memory
StateHistorical & Global BalanceInstant Read-Only Local State
Longevity RiskHigh (Requires website stability)Low (Standardized NFC protocols)

While the hardware approach provides instant, localized data without an internet connection, it cannot access broader account history or manage multiple cards. clippercard brute-forces the web layer to provide a comprehensive, global view of the user's transit data—proving that sometimes, the messy software hack is the only way to get the full picture.