## 1. Obscura āļืāļāļāļ°āđāļĢ?
**Obscura** āļืāļ headless browser engine āļี่āđāļีāļĒāļāļ้āļ§āļĒāļ āļēāļĐāļē **Rust** — āļĄัāļāļืāļ "āđāļāļĢāļēāļ§์āđāļāļāļĢ์āļี่āđāļĄ่āļĄีāļŦāļ้āļē" āļี่āļĢัāļ JavaScript āļ่āļēāļ V8 engine āļูāļāļ āļēāļĐāļē Chrome DevTools Protocol (CDP) āđāļ้ āđāļĨāļ°āļŠāļēāļĄāļēāļĢāļāđāļ้āđāļāļ headless Chrome āļŠāļģāļŦāļĢัāļ Puppeteer āđāļĨāļ° Playwright āđāļ้āđāļāļ **drop-in replacement**
āļูāļāļ่āļēāļĒāđ āļืāļ Obscura āđāļ็āļāđāļāļĢāđāļāļĢāļĄāļี่āđāļิāļāđāļ§็āļ āļ่āļēāļāđāļื้āļāļŦāļē āļĢัāļ JavaScript āļึāļāļ้āļāļĄูāļĨ āđāļĨāļ°āļāļģāļāļēāļāļัāļāđāļāļĄัāļิ āđāļāļĒāļี่āđāļĄ่āļ้āļāļāļĄีāļŦāļ้āļēāļāļ GUI āđāļĨāļĒ āđāļŦāļĄāļēāļ°āļĄāļēāļāļŠāļģāļŦāļĢัāļāļāļēāļ scraping, automation, AI agent browsing
**āļุāļāđāļ่āļāļŠāļģāļัāļ:**
- āđāļ้āļŦāļ่āļ§āļĒāļāļ§āļēāļĄāļāļģāđāļ่ **30 MB** (Chrome Headless āđāļ้ 200+ MB)
- Binary āļāļāļēāļāđāļ่ **70 MB** (Chrome Headless 300+ MB)
- Startup āđāļāļāļāļ°āļัāļāļี
- Anti-detection āđāļāļัāļ§ (stealth mode)
- āļĢāļāļāļĢัāļāļั้āļ CLI, CDP, MCP Protocol
---
## 2. āļāļģāđāļĄāļ้āļāļ Obscura? (āļ้āļāļี)
### ✅ āļ้āļāļี
| āļุāļāļŠāļĄāļัāļิ | āļĢāļēāļĒāļĨāļ°āđāļีāļĒāļ |
|-----------|-----------|
| ð️ **āđāļĢ็āļ§āļĄāļēāļ** | āļŦāļ้āļēāđāļ§็āļāđāļŦāļĨāļāđāļāļĨี่āļĒ ~85 ms āđāļีāļĒāļāļัāļ Chrome ~500 ms |
| ðŠķ **āđāļāļē** | RAM ~30 MB, Binary ~70 MB āđāļĄ่āļ้āļāļāļึ่āļ Chromium 300MB+ |
| ⚡ **Startup āļัāļāļี** | āđāļĄ่āļ้āļāļāļĢāļ 2-3 āļ§ิāđāļŦāļĄืāļāļ launch Chromium |
| ðĄ️ **Stealth āđāļāļัāļ§** | TLS fingerprint, tracker blocking, profile randomization |
| ðĶ **Binary āđāļีāļĒāļ§** | āđāļĄ่āļ้āļāļāļิāļāļั้āļ dependencies āđāļĒāļāļ° |
| ð **āļĢāļāļāļĢัāļ CDP** | āđāļ้ Puppeteer/Playwright āđāļื่āļāļĄāļ่āļāđāļ้āļัāļāļี |
| ðĪ **MCP Protocol** | āđāļŦ้ AI Agent āđāļ้ browser automation āđāļ้āđāļāļĒāļāļĢāļ |
| ðģ **Docker Ready** | Image ~57 MB āļāļ distroless/cc |
| ð§Đ **Rust Library** | āļัāļ engine āđāļāđāļāļĢāđāļāļāļ์ Rust āđāļ้ |
| ð️ **Persist Cookies** | āđāļ็āļ cookies/localStorage āļ้āļēāļĄ session |
| ð **āļ้āļēāļĄāđāļāļĨāļāļāļāļĢ์āļĄ** | Linux, macOS, Windows, Docker |
---
## 3. āļ้āļāļāļģāļัāļāđāļĨāļ°āļ้āļāđāļŠีāļĒ
### ❌ āļ้āļāđāļŠีāļĒ / āļŠิ่āļāļี่āđāļĄ่āļĢāļāļāļĢัāļ
| āļ้āļāļāļģāļัāļ | āļĢāļēāļĒāļĨāļ°āđāļีāļĒāļ |
|----------|-----------|
| ❌ **āđāļĄ่āļĄี Pixel Rendering** | `page.screenshot()`, `page.pdf()` āđāļ้āđāļĄ่āđāļ้ — Obscura āđāļĄ่āļĄี GPU engine |
| ❌ **āđāļĄ่ bypass Cloudflare āđāļāļāļŦāļัāļ** | Web Application Firewall āļี่āļ้āļāļ JS computation challenge (Under Attack mode) āļāļ°āđāļĄ่āļ่āļēāļ |
| ❌ **āđāļĄ่ bypass Datadome / Akamai** | Active bot management challenge |
| ❌ **āđāļĄ่āļĄี CAPTCHA solver** | āļ้āļāļāđāļ้ proxy + stealth āđāļื่āļāđāļĨี่āļĒāļ |
| ðķ **V8 Isolate āđāļāļĢ์āļัāļ** | āļุāļāļŦāļ้āļēāđāļ§็āļāđāļ้ V8 isolate āđāļีāļĒāļ§āļัāļ āļ้āļēāļĄี JS āļŦāļัāļāđ āđāļāļŦāļ้āļēāđāļีāļĒāļ§āļāļ°āļāļģāđāļŦ้āļŦāļ้āļēāļื่āļāļ้āļēāļ |
| ðķ **āđāļĄ่āļĄี Service Workers** | āđāļĄ่āļĢāļāļāļĢัāļ Progressive Web App |
| ðķ **Device Emulation āļāļģāļัāļ** | viewport metadata āđāļ้ āđāļ่āđāļĄ่āļĄี real layout |
| ðķ **GPU āđāļĄ่āļĄี** | āđāļĄ่āļĄี WebGL āļāļĢิāļ (āđāļ่āļĄี GPU renderer string āļāļĨāļāļĄāđāļŦ้ fingerprint āļŠāļĄāļูāļĢāļ์) |
### āđāļāļĢีāļĒāļāđāļีāļĒāļāļัāļ agent-browser / Playwright āļāļĢิāļ
| Scenario | Obscura | Chrome Headless / Playwright |
|----------|---------|------------------------------|
| Scrape āđāļ§็āļāļั่āļ§āđāļ | ✅ āđāļĢ็āļ§āļāļ§่āļē, āđāļāļēāļāļ§่āļē | ✅ āļ้āļēāļāļ§่āļē āđāļ่ reliable |
| āđāļ§็āļ JS-heavy (SPA) | ✅ āđāļ้ | ✅ āđāļ้ |
| āđāļ§็āļāļĄี Cloudflare āļāļēāļāļāļĨāļēāļ | ✅ āļ่āļēāļ (stealth mode) | ✅ āļ่āļēāļ |
| āđāļ§็āļāļĄี Cloudflare āļŦāļัāļ (Under Attack) | ❌ āđāļĄ่āļ่āļēāļ | ✅ āļ่āļēāļ (Chromium āļāļĢิāļ) |
| Screenshot/PDF | ❌ āđāļĄ่āļĄี | ✅ āļĄี |
| āđāļ้āļāļēāļāđāļ Docker | ✅ 57MB Image | ❌ Image āđāļŦāļ่ |
| āđāļ้āļัāļ Puppeteer/Playwright code āđāļิāļĄ | ✅ āļ่āļ CDP āđāļ้ | ✅ |
---
## 4. āđāļีāļĒāļāļัāļ Chrome Headless
| Metric | Obscura | Headless Chrome |
|--------|---------|-----------------|
| ðū **Memory** | ~30 MB | 200+ MB |
| ðĶ **Binary size** | ~70 MB | 300+ MB |
| ð **Startup** | Instant (~0ms) | ~2 āļ§ิāļāļēāļี |
| ⚡ **Page load** | ~85 ms | ~500 ms |
| ðĄ️ **Anti-detect** | ✅ Built-in | ❌ āđāļĄ่āļĄี |
| ð **Puppeteer** | ✅ Yes (CDP) | ✅ Yes |
| ð **Playwright** | ✅ Yes (CDP) | ✅ Yes |
| ðž️ **Screenshot/PDF** | ❌ āđāļĄ่āļĄี | ✅ āļĄี |
| ð **Deploy-friendly** | ✅ Binary āļัāļ§āđāļีāļĒāļ§ | ❌ āļ้āļāļāļĄี Chromium |
---
## 5. āļāļēāļĢāļิāļāļั้āļ
### Linux x86_64
```bash
# āļāļēāļ§āļ์āđāļŦāļĨāļ binary
curl -LO https://github.com/h4ckf0r0day/obscura/releases/latest/download/obscura-x86_64-linux.tar.gz
# āđāļāļāđāļāļĨ์
tar xzf obscura-x86_64-linux.tar.gz
# āļāļāļŠāļāļ
./obscura --version
# (optional) āļĒ้āļēāļĒāđāļ PATH
sudo mv obscura /usr/local/bin/
```
> āļ้āļāļāļāļēāļĢ glibc 2.35+ (Ubuntu 22.04 āļึ้āļāđāļ)
### Linux ARM64
```bash
curl -LO https://github.com/h4ckf0r0day/obscura/releases/latest/download/obscura-aarch64-linux.tar.gz
tar xzf obscura-aarch64-linux.tar.gz
./obscura --version
```
### macOS Apple Silicon
```bash
curl -LO https://github.com/h4ckf0r0day/obscura/releases/latest/download/obscura-aarch64-macos.tar.gz
tar xzf obscura-aarch64-macos.tar.gz
./obscura --version
```
### macOS Intel
```bash
curl -LO https://github.com/h4ckf0r0day/obscura/releases/latest/download/obscura-x86_64-macos.tar.gz
tar xzf obscura-x86_64-macos.tar.gz
./obscura --version
```
### Windows
1. āđāļāļี่ https://github.com/h4ckf0r0day/obscura/releases
2. āļāļēāļ§āļ์āđāļŦāļĨāļ `.zip` āļŠāļģāļŦāļĢัāļ Windows
3. āđāļāļ zip āđāļĨ้āļ§āļĢัāļ `obscura.exe --version`
### Arch Linux (AUR)
```bash
yay -S obscura-browser
```
### Docker
```bash
docker pull h4ckf0r0day/obscura
# āļĢัāļāđāļāļ server
docker run -d \
--name obscura \
--restart unless-stopped \
-p 127.0.0.1:9222:9222 \
-v /srv/obscura/data:/data \
h4ckf0r0day/obscura \
serve --host 0.0.0.0 --storage-dir /data --stealth
```
> Image ~57 MB compressed āļāļ `distroless/cc`
### Build āļāļēāļ Source
**Requirements:**
- Rust 1.75+ (`curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh`)
- C compiler (gcc āļŦāļĢืāļ clang)
- āļื้āļāļี่āļ§่āļēāļ ~5 GB (V8 compile)
```bash
# Clone
git clone https://github.com/h4ckf0r0day/obscura.git
cd obscura
# Build āļāļāļิ (āđāļ้āđāļ§āļĨāļē ~5 āļāļēāļีāļāļĢั้āļāđāļĢāļ)
cargo build --release
# Build āļāļĢ้āļāļĄ stealth (āđāļāļ°āļāļģ)
cargo build --release --features stealth
# āļĢāļ°āļāļ OpenSSL āđāļ่āļē āļāļēāļāļ้āļāļāđāļ้
OPENSSL_NO_VENDOR=1 cargo build --release
# Binary āļāļĒู่āļี่
./target/release/obscura --version
# Install system-wide
cargo install --path crates/obscura-cli
```
**āļŠิ่āļāļี่āļāļĒู่āđāļ archive:**
- `obscura` — CLI āđāļĨāļ° CDP server
- `obscura-worker` — helper āļŠāļģāļŦāļĢัāļāļāļģāļŠั่āļ `scrape` (āļ้āļāļāļāļĒู่ path āđāļีāļĒāļ§āļัāļ)
### Smoke Test āļŦāļĨัāļāļิāļāļั้āļ
```bash
./obscura fetch https://example.com --eval "document.title"
# Expected: "Example Domain"
```
---
## 6. āļāļģāļŠั่āļāļื้āļāļāļēāļ (CLI)
### āļĢูāļāđāļāļāļāļģāļŠั่āļ
```bash
obscura [OPTIONS] <COMMAND> [URLS]
```
### 4 āļāļģāļŠั่āļāļŦāļĨัāļ
| āļāļģāļŠั่āļ | āđāļ้āļāļģāļāļ°āđāļĢ |
|--------|-----------|
| `fetch <URL>` | āđāļŦāļĨāļ URL āđāļีāļĒāļ§, āļĢัāļ JS, āđāļŠāļāļāļāļĨāļĨัāļāļ์ |
| `scrape [URLS]...` | āļĢัāļ JS āļāļĢ้āļāļĄāļัāļāļŦāļĨāļēāļĒ URL |
| `serve` | āļĢัāļ CDP server āđāļŦ้ Puppeteer/Playwright āđāļื่āļāļĄāļ่āļ |
| `mcp` | āļĢัāļāđāļ็āļ MCP server āđāļŦ้ AI Agent āđāļ้āļāļēāļ |
### Global Flags (āđāļ้āđāļ้āļัāļāļุāļāļāļģāļŠั่āļ)
| Flag | āļāļģāļāļิāļāļēāļĒ |
|------|----------|
| `--stealth` | āđāļิāļ stealth mode (TLS fingerprint + tracker blocking) |
| `--proxy <URL>` | āđāļ้ proxy (HTTP/SOCKS5) |
| `--user-agent <UA>` | āđāļāļĨี่āļĒāļ User-Agent |
| `--allow-private-network` | āļāļุāļāļēāļ localhost/192.168.x.x |
| `-v, --verbose` | āđāļŠāļāļ log āđāļĒāļāļ°āļึ้āļ |
| `-q, --quiet` | āļิāļ log |
| `--v8-flags <FLAGS>` | āļั้āļāļ่āļē V8 engine |
| `--storage-dir <DIR>` | āđāļāļĨāđāļāļāļĢ์āđāļ็āļ cookies/localStorage |
---
## 7. āļāļēāļĢāļึāļāļ้āļāļĄูāļĨ (Extract Data)
### --dump āļĢูāļāđāļāļāļ่āļēāļāđ
```bash
# HTML āļŦāļĨัāļāļāļēāļāļĢัāļ JS (āļ่āļēāđāļĢิ่āļĄāļ้āļ)
obscura fetch https://example.com --dump html
# āļ้āļāļāļ§āļēāļĄāļĨ้āļ§āļ (Plain text)
obscura fetch https://example.com --dump text
# Markdown (āđāļāļ°āļāļģāļŠāļģāļŦāļĢัāļ AI/LLM)
obscura fetch https://example.com --dump markdown
# āļĨิāļāļ์āļั้āļāļŦāļĄāļāļāļāļŦāļ้āļē
obscura fetch https://example.com --dump links
# Sub-resources āļั้āļāļŦāļĄāļ (script, img, iframe, fetch/XHR calls)
obscura fetch https://example.com --dump assets
# HTML āļิāļāļ่āļāļāļĢัāļ JS (āđāļŦāļĄืāļāļ server āļŠ่āļāļĄāļē)
obscura fetch https://example.com --dump original
# Cookies āļั้āļāļŦāļĄāļ (āļĢāļ§āļĄ HttpOnly āļี่ document.cookie āļĄāļāļāđāļĄ่āđāļŦ็āļ)
obscura fetch https://example.com --dump cookies
```
### āļāļēāļĢāđāļ้ CSS Selector
```bash
# āđāļāļāļēāļ° content āļŦāļĨัāļ
obscura fetch https://example.com --selector "main" --dump markdown
# āđāļāļāļēāļ° article
obscura fetch https://example.com --selector "article.post" --dump markdown
```
### Markdown Extraction — āđāļŦāļĄāļēāļ°āļัāļ AI Agent āđāļāļĒāđāļāļāļēāļ°
```bash
# āļŠุāļāļĒāļāļāļŠāļģāļŦāļĢัāļ AI — markdown āļŠāļ°āļāļēāļ āđāļĄ่āļĄี noise
obscura fetch https://docs.example.com/page --dump markdown --quiet
# āļัāļāļึāļāđāļ็āļāđāļāļĨ์
obscura fetch https://docs.example.com/page --dump markdown -o page.md
# āļĢāļ SPA āđāļŦāļĨāļāđāļŠāļĢ็āļāļ่āļāļ
obscura fetch https://my-spa.example --wait-until load --dump markdown
```
**āļŠิ่āļāļี่āļูāļāđāļāļĨāļāđāļ็āļ Markdown:**
✅ Headings, paragraphs, bold, italic, code spans
✅ Links (āļāļĢ้āļāļĄ href), Images (āļāļĢ้āļāļĄ src + alt)
✅ List, Block quotes, Code blocks, Tables
**āļŠิ่āļāļี่āļูāļāļัāļāļāļāļ:**
❌ `<script>`, `<style>`, `<noscript>`, inline styles, ARIA attributes, tracking pixels
---
## 8. JavaScript Evaluation
`--eval` āļĢัāļ JavaScript āļāļāļŦāļ้āļēāđāļ§็āļāđāļĨāļ°āļืāļāļ่āļēāđāļ็āļ JSON
### Single Expression
```bash
# āļึāļ title
obscura fetch https://example.com --eval "document.title"
# → "Example Domain"
# āļึāļ structured data
obscura fetch https://news.ycombinator.com --eval \
"Array.from(document.querySelectorAll('.titleline a')).slice(0,5).map(a => a.textContent)"
```
### Multi-statement (IIFE Pattern)
```bash
obscura fetch https://example.com --eval "(function(){
const links = document.querySelectorAll('a');
return Array.from(links).map(a => ({text: a.textContent, href: a.href}));
})()"
```
> ⚠️ **āļ้āļāļāļ§āļĢāļĢāļ°āļ§ัāļ:** āļ้āļēāđāļีāļĒāļ `const` āļŦāļĢืāļ `let` āļี่ top-level āđāļāļĒāļāļĢāļ āļāļ°āļืāļ `null` āđāļāļĢāļēāļ° V8 āđāļŦ้ top-level declaration āļĄี completion value āđāļ็āļ `null`
> ✅ **āļ§ิāļีāđāļ้:** āđāļ้ IIFE `(function(){...})()` āļุāļāļāļĢั้āļāļี่āļĄีāļŦāļĨāļēāļĒ statement
### Wait Options
```bash
# āļĢāļāļุāļāļāļĒ่āļēāļ (āļ่āļēāđāļĢิ่āļĄāļ้āļ āđāļ่āļ้āļēāļี่āļŠุāļ)
--wait-until load
# HTML parsed + scripts āļĢัāļāđāļĨ้āļ§ (āđāļāļ°āļāļģ - āđāļĢ็āļ§āļāļ§่āļē)
--wait-until domcontentloaded
# āļĢāļāđāļŦ้ network connections ≤2 āđāļ็āļāđāļ§āļĨāļē 500ms
--wait-until networkidle2
# āļĢāļāđāļŦ้ network connections =0 āđāļ็āļāđāļ§āļĨāļē 500ms
--wait-until networkidle0
# Extra wait āļŦāļĨัāļ page settle (default 5s)
--wait 3
```
---
## 9. Stealth Mode āđāļĨāļ° Proxy
### Stealth Mode
```bash
# āđāļิāļ stealth
obscura fetch https://example.com --stealth
obscura serve --stealth
```
**Stealth āļāļģāļāļ°āđāļĢāļ้āļēāļ:**
1. āđāļ้ HTTP client āļี่āļĄี TLS fingerprint āļāļĢāļāļัāļ Chrome āļāļĢิāļ (ClientHello, ALPN, cipher order)
2. āđāļŦāļĨāļ tracker blocklist — āļิāļāļั้āļ analytics/fingerprinting endpoints
3. āđāļ้ webpki roots āđāļāļ system certificate store
4. Browser profile — `navigator.platform`, `userAgentData`, GPU renderer āļŠāļāļāļāļĨ้āļāļāļัāļ
**āļŠิ่āļāļี่ Stealth āļัāļāļāļēāļĢāđāļ้:**
- ✅ Basic bot detection (TLS fingerprint, User-Agent)
- ✅ āđāļ§็āļāļี่āļึ่āļāļāļē third-party analytics
**āļŠิ่āļāļี่ Stealth āļัāļāļāļēāļĢāđāļĄ่āđāļ้:**
- ❌ Cloudflare interactive challenges (JS computation challenge)
- ❌ Datadome, Akamai bot manager
- ❌ CAPTCHA
- ❌ IP-based rate limiting (āļ้āļāļāđāļ้ proxy)
### Browser Profile
```bash
# Profile āļāļāļิ (stable, āļัāļ§āđāļีāļĒāļ§)
obscura serve --stealth
# āđāļĨืāļāļ profile index
OBSCURA_PROFILE=2 obscura serve
# āļŦāļĄุāļ profile āļัāļāđāļāļĄัāļิ (random āļุāļ context)
OBSCURA_ROTATE_PROFILE=1 obscura serve
```
**āļ้āļāļāļ§āļĢāļĢāļ°āļ§ัāļ:** āļ้āļēāđāļ้ proxy āļāļĒ่āļēāļŦāļĄุāļ profile āđāļāļĢāļēāļ°āļāļēāļĢāļŦāļĄุāļ identity āđāļ่ IP āđāļิāļĄ = suspicious
### Timezone & Geolocation
```bash
# āļั้āļāđāļ§āļĨāļēzone āđāļŦ้āļāļĢāļāļัāļ proxy region
OBSCURA_TIMEZONE=Asia/Bangkok obscura serve
# āļั้āļāļิāļัāļ GPS
OBSCURA_GEOLOCATION="13.7563,100.5018" obscura serve
```
### Proxy
```bash
# HTTP proxy
obscura fetch https://example.com --proxy http://proxy.example.com:8080
# HTTP proxy āļāļĢ้āļāļĄ auth
obscura fetch https://example.com --proxy http://user:[email protected]:8080
# SOCKS5
obscura fetch https://example.com --proxy socks5://proxy.example.com:1080
# āļĢāļ§āļĄ stealth + proxy + custom UA
obscura serve \
--stealth \
--proxy http://user:[email protected]:8080 \
--user-agent "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ..."
```
---
## 10. āļāļēāļĢāđāļ้āļāļēāļāļัāļ Puppeteer / Playwright
### āđāļĢิ่āļĄ CDP Server
```bash
obscura serve --port 9222
# → obscura listening on ws://127.0.0.1:9222
```
### Puppeteer
```bash
npm install puppeteer-core
```
```javascript
const puppeteer = require('puppeteer-core');
const browser = await puppeteer.connect({
browserWSEndpoint: 'ws://127.0.0.1:9222',
});
const page = await browser.newPage();
await page.goto('https://example.com');
console.log(await page.title()); // "Example Domain"
await browser.disconnect();
```
> ⚠️ āđāļ้ `puppeteer-core` āđāļĄ่āđāļ่ `puppeteer` (puppeteer āđāļāļāđāļ็āļĄāļāļ°āđāļŦāļĨāļ Chromium āļĄāļēāđāļŦ้)
### Playwright
```bash
npm install playwright
```
```javascript
const { chromium } = require('playwright');
const browser = await chromium.connectOverCDP('ws://127.0.0.1:9222');
const context = browser.contexts()[0] || await browser.newContext();
const page = await context.newPage();
await page.goto('https://example.com');
console.log(await page.title());
await browser.close();
```
> ⚠️ āđāļ้ `connectOverCDP` āđāļĄ่āđāļ่ `connect` (connect āđāļ้ protocol āļāļāļ Playwright āđāļāļ)
### āļŠิ่āļāļี่āļĢāļāļāļĢัāļ
| āļีāđāļāļāļĢ์ | āļĢāļāļāļĢัāļ? |
|---------|:-------:|
| `page.goto`, `page.reload`, `page.goBack`, `page.goForward` | ✅ |
| `page.evaluate`, `page.evaluateHandle` | ✅ |
| `page.click`, `page.type`, `page.fill`, `page.focus` | ✅ |
| `page.waitForSelector`, `page.waitForFunction`, `page.waitForNavigation` | ✅ |
| `page.cookies`, `page.setCookie`, `context.cookies` | ✅ |
| `page.setRequestInterception` (block/modify) | ✅ |
| `page.exposeFunction` | ✅ |
| `page.content`, `page.title`, `page.url` | ✅ |
| DOM Agent frameworks (browser-use) | ✅ |
| `page.screenshot()`, `page.pdf()` | ❌ āđāļĄ่āļĄี pixel rendering |
| Service Workers | ❌ |
---
## 11. MCP Server — āđāļŦ้ AI Agent āđāļ้ Browser
Obscura āļĄี MCP (Model Context Protocol) server āđāļāļัāļ§ āļāļģāđāļŦ้ AI Agent āđāļื่āļāļĄāļ่āļāđāļĨāļ°āđāļ้ browser automation āđāļ้āļัāļāļี
### āļĢัāļ MCP Server
```bash
# Stdio mode (default — āļŠāļģāļŦāļĢัāļ Claude Desktop āđāļāļĒāļāļĢāļ)
obscura mcp
# HTTP mode (āļŠāļģāļŦāļĢัāļ remote āļŦāļĢืāļ container)
obscura mcp --http --port 3000
# HTTP + bind all interfaces (āđāļ Docker)
obscura mcp --http --host 0.0.0.0 --port 3000
# āļāļĢ้āļāļĄ stealth + proxy
obscura mcp --stealth --proxy http://proxy.example.com:8080
```
### āļāļēāļĢāđāļื่āļāļĄāļ่āļāļัāļ Claude Desktop
āđāļ้āđāļ `claude_desktop_config.json`:
```json
{
"mcpServers": {
"obscura": {
"command": "/path/to/obscura",
"args": ["mcp", "--stealth"]
}
}
}
```
### āļāļēāļĢāđāļื่āļāļĄāļ่āļāļัāļ Claude Code
```bash
claude mcp add obscura /path/to/obscura mcp
```
### āđāļāļĢื่āļāļāļĄืāļ MCP āļี่ Obscura āđāļŦ้
**Navigation:**
- `browser_navigate`, `browser_back`, `browser_forward`, `browser_reload`, `browser_close`
**Read page:**
- `browser_snapshot` — DOM/accessibility snapshot
- `browser_markdown`, `browser_links`, `browser_extract`
- `browser_interactive_elements`, `browser_detect_forms`
- `browser_get_attribute`, `browser_count`, `browser_search`
**Interactive:**
- `browser_click`, `browser_fill`, `browser_fill_form`
- `browser_type`, `browser_press_key`, `browser_select_option`, `browser_scroll`
**Wait & JS:**
- `browser_wait_for`, `browser_wait_for_text`, `browser_evaluate`
**Cookies & Storage:**
- `browser_get_cookies`, `browser_set_cookie`, `browser_clear_cookies`
- `browser_storage_state`, `browser_set_storage_state`
**Network:**
- `browser_network_requests`, `browser_console_messages`
**Tabs:**
- `browser_tab_new`, `browser_tab_list`, `browser_tab_switch`, `browser_tab_close`
### Security (HTTP transport)
```bash
# āļāļģāļัāļāđāļāļāļēāļ° Origin āļี่āļāļุāļāļēāļ
OBSCURA_MCP_ALLOWED_ORIGINS="https://app.example.com" obscura mcp --http
# Body cap 16 MiB (default — āļ้āļāļāļัāļ large allocation)
```
---
## 12. Production Deployment
### Docker (Production)
```bash
docker run -d \
--name obscura \
--memory=4g --cpus=2 \
--restart unless-stopped \
-p 127.0.0.1:9222:9222 \
-v /srv/obscura/data:/data \
h4ckf0r0day/obscura \
serve --host 0.0.0.0 --storage-dir /data --stealth
```
### Systemd service
```ini
# /etc/systemd/system/obscura.service
[Unit]
Description=Obscura headless browser
After=network.target
[Service]
ExecStart=/usr/local/bin/obscura serve --port 9222 --stealth --storage-dir /var/lib/obscura
Restart=always
RestartSec=5
User=obscura
Group=obscura
LimitNOFILE=65536
MemoryMax=4G
MemoryHigh=3G
[Install]
WantedBy=multi-user.target
```
```bash
sudo systemctl enable --now obscura
sudo journalctl -fu obscura
```
### Workers (Multi-core)
```bash
# 1 worker āļ่āļ 1 CPU core
obscura serve --workers 4
```
### Parallel Scrape
```bash
# Scrape 20 URL āļāļĢ้āļāļĄāļัāļ
obscura scrape \
--concurrency 20 \
--format json \
--timeout 60 \
--stealth \
url1 url2 url3 ...
# āļŦāļĢืāļāļ่āļēāļāļāļēāļ stdin
cat urls.txt | obscura scrape --concurrency 20 --stealth -
```
> ⚠️ āļ้āļāļāļĄี `obscura-worker` āļāļĒู่āļ้āļēāļāđ `obscura` āđāļ PATH
### V8 Heap Management
```bash
# Default: --max-old-space-size=4096 (4GB)
# āļĨāļāļŠāļģāļŦāļĢัāļāđāļāļĢื่āļāļ RAM āļ้āļāļĒ
obscura serve --v8-flags "--max-old-space-size=2048"
```
### Timeouts (āļ้āļāļāļัāļ session āļ้āļēāļ)
```bash
OBSCURA_NAV_TIMEOUT_MS=60000 \
OBSCURA_CDP_COMMAND_TIMEOUT_MS=30000 \
OBSCURA_FETCH_TIMEOUT_MS=20000 \
obscura serve
```
### Persist Cookies & Storage
```bash
# CLI
obscura fetch https://example.com --storage-dir ./obscura-data
# Server
obscura serve --storage-dir ./obscura-data
# āļŦāļĨāļēāļĒ identity āđāļĒāļ directory
obscura serve --port 9222 --storage-dir ./identity-a
obscura serve --port 9223 --storage-dir ./identity-b
```
**āļ āļēāļĒāđāļ `--storage-dir`:**
- `cookies.json` — cookie jar (inspect āļ้āļ§āļĒ `jq`)
- `localStorage/*.json` — 1 file āļ่āļ origin
**āđāļĄื่āļ state āļูāļāđāļีāļĒāļ:**
- āļāļāļ process exit
- āļŦāļĨัāļ navigation āđāļŠāļĢ็āļ
- āļ่āļēāļ CDP `Network.setCookie`
---
## 13. Environment Variables
### Runtime
| Variable | āļ่āļēāđāļĢิ่āļĄāļ้āļ | āļāļģāļāļิāļāļēāļĒ |
|----------|-----------|---------|
| `OBSCURA_ALLOW_PRIVATE_NETWORK` | off | āļāļุāļāļēāļ localhost/192.168.x.x (āļั้āļāđāļ็āļ `1`) |
| `OBSCURA_NAV_TIMEOUT_MS` | 30000 | Timeout navigation (ms) |
| `OBSCURA_CDP_COMMAND_TIMEOUT_MS` | 60000 | Timeout āđāļ่āļĨāļ° CDP command (ms) |
| `OBSCURA_FETCH_TIMEOUT_MS` | 30000 | Timeout fetch/XHR (ms) |
### Stealth & Identity
| Variable | āļ่āļēāđāļĢิ่āļĄāļ้āļ | āļāļģāļāļิāļāļēāļĒ |
|----------|-----------|---------|
| `OBSCURA_TIMEZONE` | Europe/Berlin | Timezone āļŠāļģāļŦāļĢัāļ fingerprint |
| `OBSCURA_GEOLOCATION` | fixed default | āļิāļัāļ GPS (`lat,lon`) |
| `OBSCURA_PROFILE` | 0 (stable) | āđāļĨืāļāļ browser profile index |
| `OBSCURA_ROTATE_PROFILE` | off | āļŦāļĄุāļ profile āļุāļ context |
### MCP Security
| Variable | āļāļģāļāļิāļāļēāļĒ |
|----------|---------|
| `OBSCURA_MCP_ALLOWED_ORIGINS` | comma-separated origin allowlist |
### Logging
```bash
RUST_LOG=obscura=info obscura serve
RUST_LOG=obscura=debug obscura serve
RUST_LOG=obscura_cdp=trace,obscura_browser=debug obscura serve
```
### Build
```bash
OPENSSL_NO_VENDOR=1 cargo build --release
```
---
## 14. āļāļēāļĢāđāļ้āļāļēāļāļŠāļģāļŦāļĢัāļ AI Agent (Hermes)
āļŠāļģāļŦāļĢัāļāļāļēāļĢāđāļ้āļāļēāļ Obscura āđāļ Hermes Agent (āļŦāļĢืāļ AI Agent āļั่āļ§āđāļ) āļĄี 2 āđāļāļ§āļāļēāļ:
### āļ§ิāļีāļี่ 1: CLI Mode (āđāļāļ°āļāļģāļŠāļģāļŦāļĢัāļ Scraping)
āđāļ้āļ่āļēāļ `terminal()` tool āđāļāļĒāļāļĢāļ:
```bash
# Scrape āļŦāļ้āļēāđāļ§็āļ
/home/tong/obscura fetch <URL> --dump markdown --quiet
# āļึāļ structured data
/home/tong/obscura fetch <URL> --quiet --eval "JS code"
# Batch scrape
/home/tong/obscura scrape --quiet --stealth --eval "document.title" URL1 URL2
```
**āļ้āļāļี:** Binary āļัāļ§āđāļีāļĒāļ§, āđāļĢ็āļ§āļĄāļēāļ, āđāļĄ่āļ้āļāļ setup session
**āļ้āļāđāļŠีāļĒ:** āđāļ่āļĨāļ°āļāļĢั้āļāđāļ็āļ session āđāļŦāļĄ่ (cookie āđāļĄ่ persist)
### āļ§ิāļีāļี่ 2: MCP Mode (āđāļāļ°āļāļģāļŠāļģāļŦāļĢัāļ Interactive)
āļĢัāļ `obscura mcp --http` āđāļĨ้āļ§ configure Hermes āđāļŦ้āđāļ้ MCP tools:
```yaml
# āđāļ config.yaml āļāļāļ Hermes
mcp_servers:
obscura:
command: /home/tong/obscura
args: ["mcp", "--stealth", "--http"]
port: 3000
```
**āļ้āļāļี:** āļĄี session āļี่ persist, āļĢāļāļāļĢัāļ interactive (click, fill form)
**āļ้āļāđāļŠีāļĒ:** āļ้āļāļāļĢัāļ background service, āļāļĢัāļāļĒāļēāļāļĢāđāļิ่āļĄ
### Skill āļŠāļģāļŦāļĢัāļ Hermes
āļĄี skill `web/obscura-browser` āļี่āļŠāļēāļĄāļēāļĢāļ load āđāļื่āļāđāļ้āļāļēāļ:
```bash
# terminal āđāļĢีāļĒāļāđāļ้āļāļēāļĄ pattern āđāļ skill
/home/tong/obscura fetch <URL> --dump markdown --quiet --wait-until domcontentloaded
```
### Cron Job Integration
āđāļ cron job prompt āđāļŦ้āđāļ้ Obscura āđāļāļ browser tools:
```bash
# āđāļāļāļี่āļāļ°āđāļ้ browser_navigate → āđāļ้:
/home/tong/obscura fetch <URL> --dump markdown --quiet --stealth
```
---
## 15. FAQ āļัāļāļŦāļēāļี่āļāļāļ่āļāļĒ
### Q: āļิāļāļั้āļāđāļĨ้āļ§āļĢัāļāđāļĄ่āđāļ้ "cannot execute binary file"
**A:** āđāļĨืāļāļ architecture āļิāļ āļāļĢāļ§āļāļŠāļāļāļ้āļ§āļĒ `uname -m` āđāļĨ้āļ§āļāļēāļ§āļ์āđāļŦāļĨāļ binary āļี่āļูāļāļ้āļāļ
### Q: "GLIBC_2.35 not found"
**A:** āļĢāļ°āļāļ Linux āđāļ่āļēāļāļ§่āļē Ubuntu 22.04 āđāļ้ Docker āđāļāļ āļŦāļĢืāļ build āļāļēāļ source
### Q: macOS Gatekeeper āļāļĨ็āļāļ
**A:** `xattr -d com.apple.quarantine ./obscura`
### Q: āđāļ้ `--eval` āđāļĨ้āļ§āđāļ้ `null`
**A:** āđāļ้ IIFE pattern: `(function(){...})()` āđāļāļāļāļēāļĢāđāļีāļĒāļ `const`/`let` āļี่ top-level
### Q: āđāļāļ Cloudflare challenge
**A:** āđāļ้ `--stealth` + `--wait-until networkidle2` + `--wait 10` āļ้āļēāļĒัāļāđāļĄ่āļ่āļēāļ āđāļŠāļāļāļ§่āļēāđāļ็āļ Under Attack mode — āļ้āļāļāđāļ้ Chromium āļāļĢิāļāđāļāļ
### Q: Scrape āļŦāļĨāļēāļĒ URL āđāļĨ้āļ§ error
**A:** āđāļ้ `--concurrency` āļ่āļģāļĨāļ, āđāļิ่āļĄ `--timeout`, āļŦāļĢืāļāđāļ้ `obscura serve` + Puppeteer/Playwright āđāļāļ
### Q: āļ้āļāļāļāļēāļĢ screenshot
**A:** Obscura āđāļĄ่āļĢāļāļāļĢัāļ pixel rendering āđāļ้ headless Chrome + screenshot tool āđāļĒāļ
### Q: Cookies āđāļĄ่ persist āļ้āļēāļĄ session
**A:** āđāļ้ `--storage-dir` āļāļģāļŦāļāļ path āļี่āđāļ็āļ cookies āđāļ§้
---
## 16. āļŠāļĢุāļ
### Obscura āđāļŦāļĄāļēāļ°āļัāļāđāļāļĢ?
| āļāļĨุ่āļĄ | āđāļŦāļĄāļēāļ°? | āđāļŦāļุāļāļĨ |
|------|:------:|--------|
| ð·️ **Web Scraper** | ✅ **āđāļŦāļĄāļēāļ°āļĄāļēāļ** | āđāļĢ็āļ§, āđāļāļē, stealth, markdown output |
| ðĪ **AI Agent** | ✅ **āđāļŦāļĄāļēāļ°āļĄāļēāļ** | MCP native, CLI āđāļ้āļ่āļēāļĒ, resource āļ่āļģ |
| ð§Š **QA / Test Automation** | ⚠️ **āļāļēāļāļŠ่āļ§āļ** | Puppeteer/Playwright CDP āđāļ้ āđāļ่āđāļĄ่āļĄี screenshot |
| ðŽ **Data Scientist** | ✅ **āđāļŦāļĄāļēāļ°** | Extract markdown/link/cookie āđāļ้āđāļĢ็āļ§ |
| ð **Production Scraping** | ✅ **āđāļŦāļĄāļēāļ°** | Docker, systemd, worker scaling, timeouts āļāļĢāļ |
### āļุāļāđāļ่āļāļี่āļŠุāļāļāļāļ Obscura
1. **āđāļĢ็āļ§āđāļĨāļ°āđāļāļē** — 30MB RAM, 70MB binary, startup instant — āļ้āļāļĒāļāļ§่āļē Chrome Headless 10x
2. **Stealth āđāļāļัāļ§** — āđāļĄ่āļ้āļāļāļŦāļē proxy/extension āđāļิ่āļĄ
3. **MCP Protocol** — AI Agent āđāļ้ browser āđāļ้āđāļāļĒāļāļĢāļ
4. **Binary āđāļีāļĒāļ§** — deploy āļ่āļēāļĒāļŠุāļāđ
### āļุāļāļ่āļāļāļี่āļ้āļāļāļĢāļ°āļ§ัāļ
1. **āđāļĄ่āļĄี pixel rendering** — screenshot, PDF āđāļĄ่āđāļ้
2. **āđāļĄ่ bypass Cloudflare āļŦāļัāļ** — āļ้āļāļāļĄี Chromium āļāļĢิāļāļŠāļģāļĢāļāļ
3. **V8 Isolate āđāļāļĢ์āļัāļ** — JS āļŦāļัāļāđ āđāļāļŦāļ้āļēāđāļีāļĒāļ§āļāļĢāļ°āļāļāļŦāļ้āļēāļื่āļ
### āļāļģāđāļāļ°āļāļģāđāļāļāļēāļĢāđāļĨืāļāļāđāļ้
```
āļŦāļ้āļēāđāļ§็āļāļั่āļ§āđāļ → Obscura (āđāļĢ็āļ§, āđāļāļē)
āļŦāļ้āļēāđāļ§็āļāļĄี Cloudflare → Obscura + --stealth
āļŦāļ้āļēāđāļ§็āļāļĄี CF Under Attack → Fallback āđāļ Chromium āļāļĢิāļ
āļ้āļāļāļāļēāļĢ Screenshot → Obscura āđāļĄ่āđāļ้ āđāļ้ tool āļื่āļ
āļ้āļāļāļāļēāļĢ Interactive browser session → Obscura MCP āļŦāļĢืāļ serve
```
---
> ð **āļ้āļēāļĒāļāļāļāļ§āļēāļĄ:** Obscura āđāļ็āļāđāļāļĢื่āļāļāļĄืāļāļี่āđāļāļĨี่āļĒāļāļ§ิāļีāļิāļāđāļĢื่āļāļ headless browser āđāļāđāļĨāļĒ āļāļēāļāļี่āđāļāļĒāļ้āļāļāļึ่āļ Chromium 300MB+ āļāļāļāļี้āđāļĢāļēāļĄี binary 70MB āļี่āļāļģāļāļēāļāđāļ้āđāļĢ็āļ§āļāļ§่āļēāđāļĨāļ°āļิāļāļāļĢัāļāļĒāļēāļāļĢāļ้āļāļĒāļāļ§่āļē āđāļŦāļĄāļēāļ°āļĄāļēāļāļŠāļģāļŦāļĢัāļāļĒุāļāļี่ AI Agent āļ้āļāļāđāļิāļāđāļ§็āļāļ่āļēāļāļ้āļāļĄูāļĨāđāļ็āļāļĢ้āļāļĒāđāļ็āļāļัāļāļāļĢั้āļāļ่āļāļ§ัāļ!
> ð **āļĨิāļāļ์āļี่āđāļี่āļĒāļ§āļ้āļāļ:**
> - Docs: https://docs.obscura.sh/
> - GitHub: https://github.com/h4ckf0r0day/obscura
> - Releases: https://github.com/h4ckf0r0day/obscura/releases
> - Issues: https://github.com/h4ckf0r0day/obscura/issues
No comments:
Post a Comment