h4ckf0r0day/obscura
h4ckf0r0day/obscuraThe headless browser for AI agents and web scraping
From the README
Obscura
The open-source headless browser for AI agents and web scraping. Lightweight, stealthy, and built in Rust.
Obscura is a headless browser engine written in Rust, built for web scraping and AI agent automation. It runs real JavaScript via V8, supports the Chrome DevTools Protocol, and acts as a drop-in replacement for headless Chrome with Puppeteer and Playwright.
Why Obscura over headless Chrome?
Designed for automation at scale, not desktop browsing.
| Metric | Obscura | Headless Chrome | |--------------|--------------|------------------| | Memory | 30 MB | 200+ MB | | Binary size | 70 MB | 300+ MB | | Anti-detect | Built-in | None | | Page load | 85 ms | ~500 ms | | Startup | Instant | ~2s | | Puppeteer | Yes | Yes | | Playwright | Yes | Yes |
Install
Download
Grab the latest binary from Releases:
# Linux x86_64
curl -LO
tar xzf obscura-x86_64-linux.tar.gz
./obscura fetch --eval "document.title"
# macOS Apple Silicon
curl -LO
tar xzf obscura-aarch64-macos.tar.gz
# macOS Intel
curl -LO
tar xzf obscura-x86_64-macos.tar.gz
# Windows
Download the `.zip` from the releases page and extract it manually.
Single binary. No Chrome, no Node.js, no dependencies.
Build from source
git clone
cd obscura
cargo build --release
# With stealth mode (anti-detection + tracker blocking)
cargo build --release --features stealth
Requires Rust 1.75+ (rustup.rs). First build takes ~5 min (V8 compiles from source, cached after).
Quick Start
Fetch a page
# Get the page title
obscura fetch --eval "document.title"
# Extract all links
obscura fetch --dump links
# Render JavaScript and dump HTML
obscura fetch --dump html
# Wait for dynamic content
obscura fetch --wait-until networkidle0
Start the CDP server
obscura serve --port 9222
# With stealth mode (anti-detection + tracker blocking)
obscura serve --port 9222 --stealth
Scrape in parallel
obscura scrape url1 url2 url3 ... \
--concurrency 25 \
--eval "document.querySelector('h1').textContent" \
--format json
Puppeteer / Playwright
Puppeteer
npm install puppeteer-core
import puppeteer from 'puppeteer-core';
const browser = await puppeteer.connect({
browserWSEndpoint: 'ws://127.0.0.1:9222/devtools/browser',
});
const page = await browser.newPage();
await page.goto(');
const stories = await page.evaluate(() =>
Array.from(document.querySelectorAll('.titleline > a'))
.map(a => ({ title: a.textContent, url: a.href }))
);
console.log(stories);
await browser.disconnect();
Playwright
npm install playwright-core
import { chromium } from 'playwright-core';
const browser = await chromium.connectOverCDP({
endpointURL: 'ws://127.0.0.1:9222',
});
co