A tool for extracting JavaScript and HTML from a HAR file, preserving the original URL folder structure, fetching source maps, and beautifying/unminifying the output.
- Parses a HAR export (captured from DevTools → Network → Save all as HAR with content)
- Extracts every
scriptanddocumentresponse, deduplicating by URL - Saves files mirroring the original URL structure (
domain/path/file.js) - Fetches source maps using a three-stage strategy:
sourcemapper -jsurl <url>(auto-detect.mapfrom the JS file itself)sourcemapper -url <url>.mapsourcemapper -url <url>.map.js- Falls back to parsing
//# sourceMappingURL=comments in the JS and downloading the map directly (including inlinedata:URIs)
- Beautifies JS via
deobfuscator.js(preferred) orjs-beautify - Extracts inline scripts from HTML pages via
htmlq
Requirements: Python 3.10+, no third-party Python packages needed.
Optional tools (used when available):
| Tool | Purpose |
|---|---|
sourcemapper |
Reconstruct source files from .map files |
js-beautify |
Prettify minified JS |
deobfuscator.js |
Deobfuscate JS |
htmlq |
Extract inline <script> tags from HTML |
# sourcemapper
go install github.com/denandz/sourcemapper@latest
# js-beautify
npm install -g js-beautify
# htmlq
brew install htmlq # macOS
cargo install htmlq # or via cargoOpen DevTools → Network tab → reload the page → right-click the request list → Save all as HAR with content.
⚠️ Make sure to use "Save all as HAR with content", not plain HAR! otherwise response bodies won't be included.
git clone https://github.com/Spix0r/unhar
cd unharpython3 unhar.py site.har# custom output directory
python3 unhar.py site.har --output folder
# skip source map fetching
python3 unhar.py site.har --no-srcmap
# skip beautify / deobfuscation
python3 unhar.py site.har --no-beautify
# extract only, no post-processing
python3 unhar.py site.har --no-srcmap --no-beautifyunhar_output/
├── src/ ← reconstructed source files (from source maps)
│ └── src/
│ ├── components/
│ │ └── App.jsx
│ └── utils/
│ └── helpers.ts
├── quote.joinroot.com/
│ ├── main.27b66d7c.bundle.js
│ └── runtime.abc123.bundle.js
├── js.adsrvr.org/
│ └── universal_pixel.js
└── siteintercept.qualtrics.com/
└── dxjsmodule/
└── FeedbackButtonModule.js%3FQ_CLIENTVERSION=2.55.0...
| Flag | Default | Description |
|---|---|---|
har_file |
(required) | Path to the .har file |
--output |
unhar_output |
Output directory |
--no-srcmap |
off | Skip source map fetching |
--no-beautify |
off | Skip JS beautification |
For each JS file, the tool tries in order:
1. sourcemapper -jsurl <url> # reads X-SourceMap / SourceMap header
↓ fail
2. sourcemapper -url <url>.map # common convention
↓ fail
3. sourcemapper -url <url>.map.js # alternate convention
↓ fail
4. parse //# sourceMappingURL= comment from JS content
├── data: URI → decode base64 inline, write .map file
└── http URL → fetch directly, then run sourcemapper on it
- Duplicate URLs (same JS file requested multiple times in the HAR) are processed only once.
- Files with query strings are saved with the query encoded in the filename (e.g.
file.js%3Fv=1.2.3). - If a path segment conflicts with an existing directory, the file is saved as
index.htmlinside it. - All external tools (
sourcemapper,js-beautify, etc.) are optional. The tool checks for their presence withshutil.whichand silently skips the step if they're not installed.