One Python runtime file. Two accessibility surfaces. Evidence you can inspect and defend.
WCAG 2.2 Site and PDF Scanner examines websites, local HTML, and PDF documents through one interactive application. It combines fast source analysis, optional real-browser testing with axe-core, bounded site crawling, conservative PDF structure inspection, PDF discovery, and accessible reports.
The scanner deliberately avoids claiming that automation proves conformance. Every result describes what was tested, what evidence was observed, and where human review is still required.
Automated testing finds only some accessibility barriers. It does not establish WCAG, Section 508, or PDF/UA conformance. Complete evaluation requires manual review, assistive-technology testing, and judgment about the content and its purpose.
Version 5.0.1 is the current release candidate. Until its GitHub release lists the tested standalone runtime, wheel, normalized source distribution, SPDX SBOM, checksums, release evidence, and provenance, evaluate the source from this repository rather than a similarly named download. See RELEASING.md for the exact artifact and publication gates.
The preview comes from the production report generator using a deliberately flawed, synthetic page. Download and open the interactive HTML fixture, inspect its structured JSON, and review the input page. The reserved .invalid target is never fetched, and no customer or live-scan data is stored in the repository.
This first run analyzes only the included synthetic HTML file. It does not contact a target website and does not require a Chromium download.
git clone https://github.com/fusiontechstrategies/WCAG-2.2-Site-PDF-Scanner.git
cd WCAG-2.2-Site-PDF-Scanner
python -m venv .venv
.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
python WCAG_Site_PDF_Scanner.py web examples\sample-site\index.html `
--output-dir a11y_reports `
--report-formats html,json `
--no-spell-checkOn macOS or Linux, use the shell form:
git clone https://github.com/fusiontechstrategies/WCAG-2.2-Site-PDF-Scanner.git
cd WCAG-2.2-Site-PDF-Scanner
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
python WCAG_Site_PDF_Scanner.py web examples/sample-site/index.html \
--output-dir a11y_reports \
--report-formats html,json \
--no-spell-checkThen open a11y_reports/report.html locally.
| Goal | Start here | Important boundary |
|---|---|---|
| Review one public page | web URL --scope page |
Dynamic checks need Playwright Chromium. |
| Inventory a public site | web URL --scope site --max-urls 500 |
Set a safety cap and use a considerate crawl delay. |
| Inspect local source | web PATH |
Local files receive static analysis; serve them locally for browser behavior. |
| Inspect PDF evidence | pdf PATH_OR_URL |
Results are conservative evidence, not PDF/UA certification. |
| Gate a build | Add --ci-mode |
The command fails on open critical or serious automated findings. |
- One runtime file:
WCAG_Site_PDF_Scanner.py - Interactive menu when launched without arguments
- Automation-friendly
web,pdf,discover-pdfs, anddiagnosticscommands - No licensed or hard-coded website page-count ceiling, with an optional operator safety cap
- WCAG 2.2 A, AA, and AAA targeting for web checks
- Static HTML, CSS, accessible-name, spelling, content, and consistency analysis
- Optional Playwright and integrity-verified axe-core browser analysis
- Site, folder, individual page, local file, and local directory scanning
- Local PDF, PDF directory, remote PDF, and URL-list scanning
- Conservative PDF results with explicit manual-review and analysis-error states
- PDF structure, language, title, figures, headings, tables, links, forms, bookmarks, active content, attachments, and PDF/UA metadata evidence
- Bounded sitemap and same-site PDF discovery without scraping search-engine result pages
- HTML, JSON, and spreadsheet-safe CSV output
- Review-first local HTML and CSS remediation with source diffs, backups, rescanning, and rollback
- Built-in offline diagnostics and self-tests
- Private, loopback, link-local, multicast, reserved, and cloud metadata addresses are blocked by default.
- Redirect destinations are validated.
- Browser subrequests are checked before navigation.
- Browser permissions, service workers, and downloads are disabled for scans.
- HTML, sitemap, URL-list, PDF, and worker-output sizes are bounded.
- Remote PDFs use atomic downloads and must have a valid PDF signature.
- PDF parsing occurs in a child process with a configurable timeout.
- Generated CSV values are neutralized against spreadsheet formula injection.
- The report does not load remote fonts or other presentation assets.
- Remediation refuses templates, links, reparse points, oversized files, out-of-scope paths, and files changed after analysis.
Read SECURITY.md before scanning untrusted or internal content.
- Python 3.10 through 3.14
- Windows, macOS, or Linux
- Chromium installed through Playwright for dynamic web analysis
Create and activate a virtual environment from a cloned repository, then install the pinned runtime dependencies:
python -m venv .venv
.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
python -m playwright install chromiumOn macOS or Linux, activate with source .venv/bin/activate.
The repository is package-ready for local validation, but neither a 5.0.1 GitHub release nor a public PyPI project has been announced. Do not assume that an unrelated package with a similar name is this project.
Install the current checkout into an active virtual environment:
python -m pip install .
wcag-site-pdf-scanner diagnosticsOr install a trusted local checkout into a pipx-managed environment:
pipx install .
wcag-site-pdf-scanner diagnosticsPipx separates Python package environments; it is not a security sandbox. Review and trust the checkout before installing it because installation and scanner commands run with your user account's privileges.
Both installed forms preserve the original WCAG_Site_PDF_Scanner.py module and add the wcag-site-pdf-scanner command. The source-file commands in this README remain valid.
The 5.0.1 release path builds exactly six files twice and requires identical bytes: an exact standalone runtime, normalized pure-Python wheel, normalized source distribution, SPDX 2.3 dependency SBOM, SHA-256 checksum file, and commit-bound release evidence. Generated package metadata, archive fields, order, timestamps, ownership, permissions, and line endings are canonicalized for cross-platform reproducibility. A tag pointing to a verified protected-main commit can create only a draft GitHub release. Publication and any future PyPI setup remain separate maintainer decisions.
Optional language analysis uses NLTK data that is never downloaded automatically. Install it explicitly if needed:
python -m nltk.downloader punkt cmudictpython WCAG_Site_PDF_Scanner.pyThe menu offers website and local HTML scanning, PDF scanning, PDF discovery, and environment diagnostics.
Scan one web page:
python WCAG_Site_PDF_Scanner.py web https://example.com --scope pageScan an entire site with bounded discovery:
python WCAG_Site_PDF_Scanner.py web https://example.com --scope site --max-urls 500Omit --max-urls when you do not want an artificial page-count ceiling. Real capacity still depends on time, memory, storage, the target site's behavior, and crawl exclusions. For unattended or production use, an explicit safety cap is strongly recommended.
Scan a local HTML project:
python WCAG_Site_PDF_Scanner.py web C:\path\to\site --report-formats html,json,csvScan one or more local PDFs:
python WCAG_Site_PDF_Scanner.py pdf C:\documents\one.pdf C:\documents\two.pdfScan every PDF under a directory:
python WCAG_Site_PDF_Scanner.py pdf C:\documents --workers 4Scan remote PDFs or a text file containing one URL per line:
python WCAG_Site_PDF_Scanner.py pdf https://example.com/document.pdf
python WCAG_Site_PDF_Scanner.py pdf --url-file pdf-urls.txtDiscover PDFs from sitemaps and same-site pages:
python WCAG_Site_PDF_Scanner.py discover-pdfs https://example.com --output pdf-urls.txtDiscover and immediately scan them:
python WCAG_Site_PDF_Scanner.py discover-pdfs https://example.com --scan --report-dir accessibility_reportsRun offline diagnostics and self-tests:
python WCAG_Site_PDF_Scanner.py diagnosticsGuided remediation is available for local HTML and linked CSS source:
python WCAG_Site_PDF_Scanner.py web C:\path\to\site --fixThe remediation workflow can currently guide or propose changes for image alternatives, document language, skip links, page titles, form autocomplete, form labels, iframe titles, and suppressed CSS focus outlines. Each source edit is handled as follows:
- The exact local target is validated against the scanned directory.
- Template files, symbolic links, hard links, Windows reparse points, non-UTF-8 content, and oversized files are refused.
- HTML attribute edits preserve the surrounding source instead of reformatting the full document.
- A bounded unified diff is displayed before any write.
- The user approves the transaction explicitly.
- A unique rollback backup is created and the replacement is atomic.
- Changed files are rescanned with the applicable narrow automated engine.
- The user keeps the transaction or restores every backup.
- Retained changes and SHA-256 digests are recorded in the JSON audit trail.
Remote websites are never edited. PDF results provide evidence and remediation guidance, but the tool does not attempt general-purpose automatic PDF retagging. Human review remains required even when a follow-up automated check no longer reports the original finding.
The legacy convenience form remains available. The application determines whether the target is web/HTML or PDF:
python WCAG_Site_PDF_Scanner.py https://example.com
python WCAG_Site_PDF_Scanner.py C:\documents\example.pdfPDF evidence uses these outcomes:
| Status | Meaning |
|---|---|
Fail |
The narrow automated rule found evidence of a failure. |
Pass (narrow automated test) |
The rule ran and found no corresponding failure. This is not full success-criterion conformance. |
Needs manual review |
Automation found relevant evidence but cannot determine the outcome. |
Not applicable |
The tested feature was not detected. |
Not tested |
Required structure or capability was unavailable. |
Analysis error |
The check could not complete. Never interpret this as a pass or as not applicable. |
Web reports likewise treat successful checks as narrow evidence. If a finding contradicts a pass record for the same criterion and location, the pass record is suppressed.
Web scans support:
- Interactive HTML
- JSON
- CSV
- Markdown
- PDF summary
- JUnit XML
PDF scans support:
- Self-contained HTML
- JSON with structured evidence
- Spreadsheet-safe CSV with one row per rule result
Reports may contain page text, element markup, URLs, file paths, and screenshots. Treat them according to the sensitivity of the scanned content.
The implementation is informed by:
- Web Content Accessibility Guidelines 2.2
- W3C guidance for applying WCAG to non-web documents
- W3C guidance on Accessibility Conformance Testing rules
- US Section 508 PDF guidance
- PDF Association Matterhorn Protocol
The scanner is not a certified PDF/UA validator and does not replace a complete accessibility audit.
Scan only systems and documents you own or are authorized to test. Use conservative concurrency and crawl delays on shared systems. Private-network scanning requires the explicit --allow-private-hosts option.
The production runtime remains in one Python module. Focused regression tests, examples, and release checks are kept in separate support files.
See CONTRIBUTING.md, RELEASING.md, SECURITY.md, TESTING.md, and THIRD_PARTY_NOTICES.md.
MIT License. See LICENSE.
This project is independent and is not affiliated with or endorsed by W3C, the US General Services Administration, PDF Association, Deque Systems, Microsoft, or the publishers of referenced accessibility tools.
