Complete guide for both GUI and command-line interfaces with advanced SEO analysis features
Windows:
# Download and install the EXE installer
# Visit: https://download.blackseoanalyzer.com/26.9.16/BlackSEOAnalyzerSetup.exe
# Double-click to install
# Or via PowerShell:
Invoke-WebRequest -Uri https://download.blackseoanalyzer.com/26.9.16/BlackSEOAnalyzerSetup.exe -OutFile BlackSEOAnalyzerSetup.exe
.\BlackSEOAnalyzerSetup.exe
macOS:
# Download the DMG installer (Universal Binary for Intel and Apple Silicon)
curl -L -o Black-SEO-Analyzer.dmg https://download.blackseoanalyzer.com/26.9.16/Black-SEO-Analyzer.dmg
# Open the DMG and drag to Applications folder
open Black-SEO-Analyzer.dmg
Launch GUI:
After installation, launch "bseoa" from your Applications folder (macOS) or Start Menu (Windows).
Windows CLI:
# Download x86-64 binary
Invoke-WebRequest -Uri https://download.blackseoanalyzer.com/26.9.16/x86_64-win/black-seo-analyzer.exe -OutFile black-seo-analyzer.exe
# Verify installation
.\black-seo-analyzer.exe --version
macOS CLI (Apple Silicon):
# Download ARM64 binary
curl -L -o black-seo-analyzer https://download.blackseoanalyzer.com/26.9.16/aarch64-macos/black-seo-analyzer
# Make executable
chmod +x black-seo-analyzer
# Verify installation
./black-seo-analyzer --version
Linux CLI:
# Download x86-64 binary
curl -L -o black-seo-analyzer https://download.blackseoanalyzer.com/26.9.16/x86_64-linux/black-seo-analyzer
# Make executable
chmod +x black-seo-analyzer
# Verify installation
./black-seo-analyzer --version
Note: CLI binaries can be moved to your PATH for system-wide access (e.g., /usr/local/bin on Unix systems).
After purchasing, you'll receive a license key via email.
GUI Activation:
Use the license command in the GUI:
> license YOUR_LICENSE_KEY
CLI Activation:
./black-seo-analyzer --license-key YOUR_LICENSE_KEY
The license is stored locally in ~/.black-seo-analyzer/license.key and works for both GUI and CLI.
Note: A license key is required to run any crawl. Sign up for a free 14-day full-feature trial at blackseoanalyzer.com/free-trial — every analyzer, no page limit, no credit card required.
The GUI features smart autocomplete and visual file selection. Common commands:
# Set the URL to crawl
> set url https://example.com
# Set output directory
> set output-dir ./reports
# Start the crawl (output format is chosen later, at export time)
> crawl
# View crawl history
> list crawls
# Export a previous crawl (using session ID from list crawls)
> export crawl_1762367280_8991c20b html-folder
# Load saved configuration
> load client-config.json
# Save current configuration
> save my-config.json
Tip: Start typing any command and press Tab to autocomplete. Use arrow keys to navigate command history.
The CLI follows this pattern for automation and scripting:
./black-seo-analyzer [OPTIONS]
Examples:
# Basic crawl with default settings
./black-seo-analyzer --url-to-begin-crawl https://example.com
# Crawl with specific output format
./black-seo-analyzer --url-to-begin-crawl https://example.com --output-type json
# Generate output from existing crawl session
./black-seo-analyzer --generate-output --output-type html-folder --output-file ./reports
# Core Options
--url-to-begin-crawl # URL of the website to analyze (required for crawling)
--output-type # Output format: json, jsonl, xml, csv, csv-flat, html-folder, json-files
--output-file # Output directory or file path
--log-file # Path to log file
# Crawling Controls
--max-pages # Maximum number of pages to crawl
--concurrent-requests # Number of concurrent requests [default: 20]
--rate-limit # Rate limit in milliseconds [default: 50]
--user-agent # User-Agent string [default: "black-seo-analyzer v26.9.14"]
# Special Modes
--spa # Enable Single-Page Application (SPA) rendering mode
--is-sitemap # Treat the URL as a sitemap.xml file
--disable-external-links # Disable external link checking
--locale # Locale for internationalization [default: en]
# Session Management
--generate-output # Generate output from database instead of crawling
--session-id # Crawl session ID to generate output from (uses latest if not specified)
--db-path # Path to SQLite database file [default: crawl.db]
Full site audit with HTML report:
./black-seo-analyzer --url-to-begin-crawl https://example.com --output-type html-folder --output-file ./audit-report
Quick technical check (first 50 pages):
./black-seo-analyzer --url-to-begin-crawl https://example.com --max-pages 50 --output-type json
JavaScript SPA analysis:
./black-seo-analyzer --url-to-begin-crawl https://spa-site.com --spa
Analyze a sitemap:
./black-seo-analyzer --url-to-begin-crawl https://example.com/sitemap.xml --is-sitemap
Competitive analysis with AI insights:
./black-seo-analyzer --url-to-begin-crawl https://competitor.com --use-openai-analyzer --openai-api-key $OPENAI_API_KEY
Quick reference comparing command-line interface (CLI) and graphical user interface (GUI) commands. Both versions provide identical functionality with different syntax.
| Task | CLI Syntax | GUI Syntax |
|---|---|---|
| Basic Crawl | ./black-seo-analyzer --url-to-begin-crawl https://example.com |
set url https://example.comcrawl |
| Set Output Directory | --output-file ./reports |
set output-dir(opens folder browser) |
| Set Output Type | --output-type html-folder |
export <session> html-folder(chosen at export time, not via set) |
| Concurrent Requests | --concurrent-requests 20 |
set concurrent-requests 20 |
| Rate Limiting | --rate-limit 100 |
set rate-limit 100 |
| Max Pages | --max-pages 100 |
set max-pages 100 |
| SPA Mode | --spa |
set spa true |
| Sitemap Analysis | --is-sitemap |
set is-sitemap true |
| User Agent | --user-agent "MyBot/1.0" |
set user-agent MyBot/1.0 |
| License Key | --license-key YOUR_KEY |
license YOUR_KEY |
| OpenAI Analyzer | --use-openai-analyzer --openai-api-key KEY |
set use-openai trueset openai-key YOUR_KEY |
| Anthropic Claude | --use-anthropic-analyzer --anthropic-api-key KEY |
set use-anthropic trueset anthropic-key YOUR_KEY |
| Save Configuration | Not available | save config.json |
| Load Configuration | Not available | load config.json |
| List Past Crawls | Not available | list crawls |
| Export Crawl | --session-id abc123 --generate-output --output-type html-folder |
export abc123 html-folder |
| Show Config | Not available | show config |
| View Version | --version |
version |
| View Help | --help |
help |
Need more GUI examples? Check out the GUI Documentation for step-by-step workflows, real-world examples, and advanced features.
Set API keys and sensitive data via environment variables:
# AI Provider Keys (can be used instead of command-line flags)
export OPENAI_API_KEY="sk-..."
export ANTHROPIC_API_KEY="sk-ant-..."
export DEEPSEEK_API_KEY="..."
export GEMINI_API_KEY="..."
The HTML reports are rendered from Tera templates compiled into the binary. To change one, copy it into a directory of your own, edit it, and point --html-templates-dir at that directory:
my-templates/
├── index_file.html # index.html, the crawl summary
├── page_file.html # wrapper document for each file in pages/
├── page.html # the per-page report body
├── sitemap_graph.html # --output-type sitemap
└── topic_cluster_graph.html # --output-type topic-cluster
Use with:
./black-seo-analyzer --url-to-begin-crawl https://example.com --output-type html-folder --html-templates-dir ./my-templates
The same flag works when regenerating output from an already-crawled session, so you can re-render against a changed template without crawling again:
./black-seo-analyzer --generate-output --session-id abc123 --output-type html-folder --html-templates-dir ./my-templates
A few rules worth knowing:
sitemap_graph.html and topic_cluster_graph.html are not Tera templates — they are copied verbatim except for the literal {json_data}, which is replaced with the graph data as JSON.The templates are Tera 2, which follows Jinja2 closely but not exactly: filter arguments are keyword arguments ({{ score | round(precision=1) }}), and slicing is written {% for k in keyword_analysis[:50] %} rather than with a slice filter. The full list of variables each template receives is in the template README.
| Provider | Default Model | Best For |
|---|---|---|
| OpenAI | gpt-4o | General analysis, content optimization |
| Anthropic | claude-3-haiku-20240307 | Deep technical analysis, code review |
| DeepSeek | deepseek-chat | Cost-effective bulk analysis |
| Google Gemini | gemini-1.5-flash-latest | Multimodal analysis with screenshots |
OpenAI Configuration:
# Use OpenAI for SEO analysis
./black-seo-analyzer --url-to-begin-crawl https://example.com \
--use-openai-analyzer \
--openai-api-key $OPENAI_API_KEY \
--openai-model gpt-4o \
--openai-prompt-file ./prompts/seo-analysis.txt
Anthropic Claude Configuration:
# Use Anthropic Claude for analysis
./black-seo-analyzer --url-to-begin-crawl https://example.com \
--use-anthropic-analyzer \
--anthropic-api-key $ANTHROPIC_API_KEY \
--anthropic-model claude-3-haiku-20240307 \
--anthropic-prompt-file ./prompts/technical-review.txt
DeepSeek Configuration:
# Use DeepSeek for cost-effective analysis
./black-seo-analyzer --url-to-begin-crawl https://example.com \
--use-deepseek-analyzer \
--deepseek-api-key $DEEPSEEK_API_KEY \
--deepseek-model deepseek-chat
Google Gemini Configuration:
# Use Google Gemini for analysis
./black-seo-analyzer --url-to-begin-crawl https://example.com \
--use-gemini-analyzer \
--gemini-api-key $GEMINI_API_KEY \
--gemini-model gemini-1.5-flash-latest \
--gemini-prompt-file ./prompts/content-analysis.txt
Create custom prompt files for specific analysis needs. Save your prompt as a text file:
# seo-analysis-prompt.txt
Analyze this page content for:
1. Keyword density and semantic relevance
2. Content structure and readability
3. Missing topics based on search intent
4. Internal linking opportunities
5. Schema.org markup recommendations
Provide specific, actionable recommendations for improvement.
Use custom prompts with any AI provider:
./black-seo-analyzer --url-to-begin-crawl https://example.com \
--use-openai-analyzer \
--openai-prompt-file ./seo-analysis-prompt.txt
Semantic analysis runs on-device (bundled all-MiniLM-L12-v2 model, no external API call) and is enabled with a single flag. It powers duplicate-content and topical-relevance detection automatically during a crawl:
# Enable semantic analysis during a crawl
./black-seo-analyzer --url-to-begin-crawl https://example.com \
--enable-semantic-analysis
Find pages similar to a phrase or topic:
# Search a completed crawl for semantically similar pages
./black-seo-analyzer \
--enable-semantic-analysis \
--semantic-query "return policy and refunds" \
--query-limit 20
Similarity thresholds (0.95 for duplicates, 0.7 for topical relevance) are fixed internally rather than configurable via CLI flags.
Performance (Core Web Vitals, load timing) and structured-data (Schema.org) checks are built-in analyzers that run automatically as part of every crawl — there's no separate flag to turn them on. What you control is how much runs, via --audit-profile:
# Run every analyzer, including performance and structured data (default)
./black-seo-analyzer --url-to-begin-crawl https://example.com --audit-profile full
# Run only Tier 1 critical technical/indexing checks
./black-seo-analyzer --url-to-begin-crawl https://example.com --audit-profile critical
# Tier 1 + Tier 2: critical issues plus core on-page & duplicate content
./black-seo-analyzer --url-to-begin-crawl https://example.com --audit-profile core
# Tier 1-3: everything except the most advanced checks
./black-seo-analyzer --url-to-begin-crawl https://example.com --audit-profile standard
# Fast pass covering the most common issues only
./black-seo-analyzer --url-to-begin-crawl https://example.com --audit-profile quick
There's no CLI option to set custom Core Web Vitals thresholds or to selectively enable only compression/caching/CDN checks — those results are included whenever the Performance and Resources analyzers run under the chosen profile.
| Format | Use Case | Example |
|---|---|---|
json |
API integration, programmatic processing | --output-type json --output-file report.json |
jsonl |
Streaming, large datasets | --output-type jsonl --output-file report.jsonl |
jsonl-summary |
One-line-per-issue summaries for large crawls | --output-type jsonl-summary --output-file summary.jsonl |
xml |
Enterprise systems, feed ingestion | --output-type xml --output-file report.xml |
csv |
Spreadsheet analysis, data science | --output-type csv --output-file report.csv |
csv-flat |
Simplified metrics, dashboards | --output-type csv-flat --output-file report-flat.csv |
html-folder |
Visual reports, client deliverables | --output-type html-folder --output-file ./report |
json-files |
Distributed processing, archival | --output-type json-files --output-file ./report |
sitemap |
Regenerating an XML sitemap from crawl results | --output-type sitemap --output-file sitemap.xml |
topic-cluster |
Grouping pages by semantic similarity | --output-type topic-cluster --output-file clusters.json |
broken-links |
Isolated report of 4xx/5xx links only | --output-type broken-links --output-file broken.csv |
The CLI always writes its report to a file (or folder) rather than to standard output, so pipe-based workflows read the resulting file after the crawl finishes:
Extract critical issues with jq:
./black-seo-analyzer --url-to-begin-crawl https://example.com \
--output-type json --output-file report.json
jq '.issues[] | select(.severity == "critical") | {url: .url, issue: .type}' report.json
Generate a broken-links-only report directly:
./black-seo-analyzer --url-to-begin-crawl https://example.com \
--output-type broken-links --output-file broken-pages.csv
Use the compact per-issue summary for large sites:
./black-seo-analyzer --url-to-begin-crawl https://large-site.com \
--max-pages 10000 --output-type jsonl-summary --output-file summary.jsonl
name: SEO Audit
on:
push:
branches: [main]
schedule:
- cron: '0 0 * * 0' # Weekly
jobs:
seo-audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Download bseoa
run: |
curl -L https://github.com/sethblack/black-seo-analyzer/releases/latest/download/black-seo-analyzer-linux-x64.tar.gz | tar xz
chmod +x black-seo-analyzer
- name: Run SEO Audit
env:
LICENSE_KEY: ${{ secrets.BLACK_SEO_LICENSE }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
run: |
./black-seo-analyzer --store-license $LICENSE_KEY
./black-seo-analyzer \
--url-to-begin-crawl https://staging.example.com \
--max-pages 100 \
--use-openai-analyzer --openai-api-key $OPENAI_API_KEY \
--output-type json --output-file audit.json
- name: Check for Critical Issues
run: |
CRITICAL_COUNT=$(jq '[.issues[] | select(.severity == "critical")] | length' audit.json)
if [ $CRITICAL_COUNT -gt 0 ]; then
echo "Found $CRITICAL_COUNT critical SEO issues!"
exit 1
fi
- name: Upload Report
uses: actions/upload-artifact@v3
with:
name: seo-audit-report
path: audit.json
Create a monitoring script for regular checks:
#!/bin/bash
# seo-monitor.sh
SITES=(
"https://example.com"
"https://blog.example.com"
"https://shop.example.com"
)
WEBHOOK_URL="https://hooks.slack.com/services/YOUR/WEBHOOK/URL"
for site in "${SITES[@]}"; do
echo "Auditing $site..."
OUTFILE="audit-$(date +%Y%m%d)-${site//https:\/\//}.json"
./black-seo-analyzer \
--url-to-begin-crawl "$site" \
--max-pages 50 \
--output-type json --output-file "$OUTFILE"
# Check for issues
CRITICAL=$(jq '[.issues[] | select(.severity == "critical")] | length' "$OUTFILE")
HIGH=$(jq '[.issues[] | select(.severity == "high")] | length' "$OUTFILE")
if [ $CRITICAL -gt 0 ] || [ $HIGH -gt 5 ]; then
curl -X POST $WEBHOOK_URL \
-H 'Content-Type: application/json' \
-d "{\"text\":\"⚠️ SEO Alert for $site: $CRITICAL critical, $HIGH high priority issues found\"}"
fi
done
Run bseoa in a container:
# Dockerfile
FROM debian:bullseye-slim
RUN apt-get update && apt-get install -y \
curl \
jq \
chromium \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
RUN curl -L https://github.com/sethblack/black-seo-analyzer/releases/latest/download/black-seo-analyzer-linux-x64.tar.gz | tar xz
ENV CHROME_PATH=/usr/bin/chromium
ENTRYPOINT ["./black-seo-analyzer"]
Build and run:
# Build image
docker build -t black-seo-analyzer .
# Run analysis
docker run --rm \
-v $(pwd)/reports:/app/reports \
-e LICENSE_KEY=$BLACK_SEO_LICENSE \
black-seo-analyzer \
--url-to-begin-crawl https://example.com \
--output-type html-folder --output-file /app/reports
Site relies on JavaScript rendering and pages look empty in the report:
# Enable the headless-browser crawler for single-page apps
./black-seo-analyzer --url-to-begin-crawl https://example.com --spa
Without --spa, pages are fetched with a plain HTTP request and no JavaScript executes — that's the right default for static/server-rendered sites, and the one to flip on for SPAs.
Getting rate-limited or blocked:
# Slow down and reduce concurrency (rate-limit is milliseconds between requests)
./black-seo-analyzer --url-to-begin-crawl https://example.com \
--rate-limit 1000 --concurrent-requests 2
Memory issues on large sites:
# Cap total pages crawled and use the compact per-issue summary format
./black-seo-analyzer --url-to-begin-crawl https://large-site.com \
--max-pages 10000 --output-type jsonl-summary --output-file summary.jsonl
Logging is always on (info level) and goes to standard output by default. Send it to a file instead with --log-file:
./black-seo-analyzer --url-to-begin-crawl https://example.com --log-file crawl.log
There isn't a separate verbose/debug flag or per-component debug switches today — the log level and detail are fixed.
Optimize for speed (skip the headless browser and raise concurrency — be respectful of the target site):
./black-seo-analyzer --url-to-begin-crawl https://example.com \
--concurrent-requests 50 --rate-limit 20
Optimize for accuracy on JavaScript-heavy sites (render with the headless browser, at lower concurrency):
./black-seo-analyzer --url-to-begin-crawl https://example.com \
--spa --concurrent-requests 5
There's no flag to selectively skip specific resource types or to force full-page screenshots on every page — those aren't configurable today.
Choose your interface: GUI for visual workflows or CLI for automation. Both included with every license.
Expand your knowledge and connect with the community