cra-scraper 🏛️
CRA exam ratings scraper and analyzer.
Search the FFIEC CRA ratings database programmatically, parse Performance Evaluation PDFs from OCC, FDIC, and Federal Reserve, and identify banks that are prime CDFI partnership opportunities — using free public data from federal regulators.
Why cra-scraper?
The Community Reinvestment Act has been law for nearly 50 years and federal regulators publish exam results for every bank — but there's no programmatic way to access this data. Banks, CDFIs, fair lending researchers, and journalists all rely on manual PDF downloads from three different regulator websites. cra-scraper makes CRA exam data queryable in Python for the first time.
Installation
pip install cra-scraper
# For PE PDF parsing
pip install cra-scraper[pdf]
Quickstart
from crascraper import (
search_ratings, find_partnership_opportunities,
rating_distribution, build_history, find_downgrades,
summary_report,
)
# Search FFIEC ratings. Raises FFIECAccessError on failure (e.g. HTTP 403 —
# see note below); never returns placeholder/sample data.
ratings = search_ratings(bank_name="Federal")
# Compute rating distribution
dist = rating_distribution(ratings)
print(dist)
# Find banks with low ratings — CDFI partnership opportunities
opps = find_partnership_opportunities(ratings, state="IL")
print(opps)
# Track rating history per bank
histories = build_history(ratings)
for bank_id, hist in histories.items():
print(f"{hist.bank_name}: {hist.trend}")
# Identify downgrades
downgrades = find_downgrades(ratings)
print(downgrades)
# Generate a full Markdown summary report
report = summary_report(ratings)
print(report)
A note on cloud/datacenter environments
search_ratings() scrapes www.ffiec.gov, which sits behind Cloudflare.
Requests from cloud/datacenter IP ranges (Google Colab, CI runners, hosted
notebooks, most cloud VMs) are blocked with HTTP 403 at the edge. This is an
IP-reputation block, not something a User-Agent or header change can clear, and it
is not transient. When this happens the call raises FFIECAccessError with an
explanation — it does not return placeholder data. The scrape works from a
residential internet connection; run it from one to obtain the data.
Parse Performance Evaluation PDFs
from crascraper import parse_pe_pdf
pe = parse_pe_pdf("/path/to/performance_eval.pdf")
print(pe.bank_name)
print(pe.overall_rating)
print(pe.lending_test_rating)
print(pe.assessment_areas)
CRA Rating Categories
| Rating | Score | Meaning |
|---|---|---|
| Outstanding | 4 | Strong CRA performance |
| Satisfactory | 3 | Adequate CRA performance |
| Needs to Improve | 2 | Weak CRA performance |
| Substantial Noncompliance | 1 | Inadequate CRA performance |
Federal Regulators Covered
- OCC — Office of the Comptroller of the Currency (national banks)
- FRS — Federal Reserve System (state member banks)
- FDIC — Federal Deposit Insurance Corporation (state non-member banks)
Use Cases
- CDFIs identifying bank partnership opportunities (banks under regulatory pressure to improve community lending)
- Banks benchmarking their CRA performance against peers
- Researchers studying CRA effectiveness and rating trends over time
- Journalists investigating bank performance in low-income communities
- Regulators analyzing exam outcomes across asset sizes and regions
Data Sources
- FFIEC CRA Ratings Database — ffiec.gov/craratings
- OCC CRA Search — occ.gov
- FDIC CRAPES — crapes.fdic.gov
- Federal Reserve CRA — federalreserve.gov
All free public data — no API keys required.
Running Tests
PYTHONPATH=. pytest tests/ -v
28 tests across all modules.
License
MIT 2026 Jaypatel1511
Metadata
Release files for cra-scraper 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| cra_scraper-0.1.1.tar.gz | 18.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| cra_scraper-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 40.7 kB
Release files / cra_scraper-0.1.1.tar.gz
| Download URL | cra_scraper-0.1.1.tar.gz |
|---|---|
| Size | 18.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
30d29fc234b870ee7f73e7b6a356ab95f8d7913e809fa1f3c128fe2deca63f2d
|
|
BLAKE2b-256 checksum How to use checksums |
9dc640d9be64bb9bef2219ac126ab6b8328cd32ef255990712d17dba1b6d81ab
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 24, 2026.
Transparency logRelease files / cra_scraper-0.1.1-py3-none-any.whl
| Download URL | cra_scraper-0.1.1-py3-none-any.whl |
|---|---|
| Size | 22.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9e1ab684980f5a0cbbd2c4f03cd31d651b83eb03286bd7d5912b6fb2306f153f
|
|
BLAKE2b-256 checksum How to use checksums |
94fef17b1b80eeb73fe5ad0b06ad69c22ce59e195479b13136257b34dd32e294
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 24, 2026.
Transparency log