From openbrowser
Analyzes web page content, structure, layout, metadata, and detects frameworks like React, Next.js, Vue, Angular, Svelte using browser automation.
npx claudepluginhub billy-enrizky/openbrowser-ai --plugin openbrowserThis skill is limited to using the following tools:
Analyze and understand web page content, structure, and interactive elements using Python code execution. Produces a comprehensive breakdown of what is on the page and how it is organized.
Captures screenshots at multiple viewports, DOM structure, computed styles, and layout properties from live web pages using PinchTab browser automation. Use before frontend or UI changes for baseline analysis.
Reviews entire websites exhaustively for AEO, GEO, SEO, UI/UX psychology, and copywriting. Crawls multiple pages, analyzes visuals/code, produces scored reports with charts and fixes. Use for positioning evaluations.
Extracts structured data from websites using Python browser automation with openbrowser-ai. Handles JS-rendered content, pagination, multi-page scraping, and data processing with pandas.
Share bugs, ideas, or general feedback.
Analyze and understand web page content, structure, and interactive elements using Python code execution. Produces a comprehensive breakdown of what is on the page and how it is organized.
All code runs via openbrowser-ai -c. The daemon starts automatically and persists variables across calls. All browser functions are async -- use await.
Before running, verify openbrowser-ai is installed:
openbrowser-ai --help
If not found, install:
# macOS/Linux
curl -fsSL https://raw.githubusercontent.com/billy-enrizky/openbrowser-ai/main/install.sh | sh
# Windows (PowerShell)
irm https://raw.githubusercontent.com/billy-enrizky/openbrowser-ai/main/install.ps1 | iex
openbrowser-ai -c - <<'EOF'
await navigate("https://example.com")
state = await browser.get_browser_state_summary()
print(f"Title: {state.title}")
print(f"URL: {state.url}")
print(f"Interactive elements: {len(state.dom_state.selector_map)}")
print(f"Tabs: {len(state.tabs)}")
EOF
openbrowser-ai -c - <<'EOF'
meta = await evaluate("""
(function(){
return {
title: document.title,
description: document.querySelector("meta[name='description']")?.content,
canonical: document.querySelector("link[rel='canonical']")?.href,
ogTitle: document.querySelector("meta[property='og:title']")?.content,
ogImage: document.querySelector("meta[property='og:image']")?.content,
lang: document.documentElement.lang,
charset: document.characterSet
};
})()
""")
import json
print(json.dumps(meta, indent=2))
EOF
openbrowser-ai -c - <<'EOF'
tech = await evaluate("""
(function(){
const t = [];
if (window.__NEXT_DATA__) t.push("Next.js");
if (window.__NUXT__) t.push("Nuxt.js");
if (document.querySelector("[data-reactroot]") || document.querySelector("#__next")) t.push("React");
if (document.querySelector("[ng-version]")) t.push("Angular");
if (window.jQuery) t.push("jQuery");
if (window.Vue) t.push("Vue.js");
if (document.querySelector("[data-svelte]")) t.push("Svelte");
return t;
})()
""")
print(f"Technologies detected: {tech}")
EOF
openbrowser-ai -c - <<'EOF'
stats = await evaluate("""
(function(){
return {
headings: document.querySelectorAll("h1,h2,h3,h4,h5,h6").length,
paragraphs: document.querySelectorAll("p").length,
images: document.querySelectorAll("img").length,
links: document.querySelectorAll("a").length,
forms: document.querySelectorAll("form").length,
tables: document.querySelectorAll("table").length,
lists: document.querySelectorAll("ul,ol").length,
buttons: document.querySelectorAll("button,[role='button']").length,
inputs: document.querySelectorAll("input,textarea,select").length,
iframes: document.querySelectorAll("iframe").length,
scripts: document.querySelectorAll("script").length,
stylesheets: document.querySelectorAll("link[rel='stylesheet']").length
};
})()
""")
import json
print("Content statistics:")
print(json.dumps(stats, indent=2))
EOF
openbrowser-ai -c - <<'EOF'
headings = await evaluate("""
(function(){
return Array.from(document.querySelectorAll("h1,h2,h3,h4,h5,h6")).map(h => ({
tag: h.tagName,
text: h.textContent.trim().substring(0, 80)
}));
})()
""")
for h in headings:
htag = h["tag"]
htext = h["text"]
indent = " " * (int(htag[1]) - 1)
print(f"{indent}{htag}: {htext}")
EOF
openbrowser-ai -c - <<'EOF'
state = await browser.get_browser_state_summary()
elements_by_tag = {}
for idx, el in state.dom_state.selector_map.items():
tag = el.tag_name
elements_by_tag.setdefault(tag, []).append({
"index": idx,
"text": el.get_all_children_text(max_depth=1)[:50],
"type": el.attributes.get("type", ""),
"href": el.attributes.get("href", "")[:50] if el.attributes.get("href") else "",
})
for tag, elems in sorted(elements_by_tag.items()):
print(f"\n{tag} ({len(elems)} elements):")
for e in elems[:5]:
eidx = e["index"]
etxt = e["text"]
etype = e["type"]
ehref = e["href"]
print(f" [{eidx}] text=\"{etxt}\" type={etype} href={ehref}")
if len(elems) > 5:
print(f" ... and {len(elems) - 5} more")
EOF
openbrowser-ai -c - <<'EOF'
dims = await evaluate("""
(function(){
return {
viewportWidth: window.innerWidth,
viewportHeight: window.innerHeight,
scrollHeight: document.body.scrollHeight,
scrollWidth: document.body.scrollWidth,
scrollable: document.body.scrollHeight > window.innerHeight
};
})()
""")
import json
print(json.dumps(dims, indent=2))
if dims["scrollable"]:
pages = dims["scrollHeight"] / dims["viewportHeight"]
print(f"Page is approximately {pages:.1f} viewport heights long")
EOF
openbrowser-ai -c - <<'EOF'
import re
# Get page text for Python-side analysis
text_content = await evaluate("document.body.innerText")
# Find emails
emails = re.findall(r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}", text_content)
print(f"Emails found: {emails}")
# Find phone numbers
phones = re.findall(r"\+?\d[\d\s()-]{7,}", text_content)
print(f"Phone numbers found: {phones}")
# Find dates
dates = re.findall(r"\d{4}-\d{2}-\d{2}|\w+ \d{1,2},? \d{4}", text_content)
print(f"Dates found: {dates}")
EOF
-c - <<'EOF'), so all Python syntax works without shell escaping issues.evaluate() for metadata and DOM statistics -- gives a fast structured overview.browser.get_browser_state_summary() for interactive element analysis.await scroll(down=True) and re-extract to analyze below-fold content.-c calls while the daemon is running, so you can build a comprehensive analysis incrementally.