/page-analysis
Analyze web page content, structure, and layout to understand what a page contains and how it is organized. Trigger when the user asks to: analyze a page, understand page structure, inspect a website, summarize page content, examine page layout, review a web page, or describe
$ npx -y skills add billy-enrizky/openbrowser-ai --skill page-analysis --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/page-analysis
Context preview
The summary Claude sees to decide when to auto-load this skill.
Analyze web page content, structure, and layout to understand what a page contains and how it is organized. Trigger when the user asks to: analyze a page, understand page structure, inspect a website, summarize page content, examine page layout, review a web page, or describe
SKILL.md
page-analysis.SKILL.mdname: page-analysis
description: |
Analyze web page content, structure, and layout to understand what a page contains and how it is organized.
Trigger when the user asks to: analyze a page, understand page structure, inspect a website,
summarize page content, examine page layout, review a web page, or describe what is on a page.
allowed-tools: Bash(openbrowser-ai:*) Bash(curl:*) Bash(uv:*) Bash(irm:*) Read Write
Page Analysis
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`.
The CLI daemon also persists cookies and login state in `~/.config/openbrowser/profiles/daemon/storage_state.json`, so authenticated sessions can be reused across later runs.
Setup
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
Workflow
Step 1 -- Navigate and get overview
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)}")
EOFStep 2 -- Extract page metadata
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))
EOFStep 3 -- Detect frameworks and technologies
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}")
EOFStep 4 -- Content summary and statistics
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))
EOFStep 5 -- Analyze heading structure
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}")
EOFStep 6 -- Analyze interactive elements
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")
EOFStep 7 -- Page dimensions and scroll analysis
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")
EOFStep 8 -- Search for specific content patterns
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-ZRead more
name: page-analysis description: | Analyze web page content, structure, and layout to understand what a page contains and how it is organized. Trigger when the user asks to: analyze a page, understand page structure, inspect a website, summarize page content, examine page layout, review a web page, or describe what is on a page. allowed-tools: Bash(openbrowser-ai:*) Bash(curl:*) Bash(uv:*) Bash(irm:*) Read Write
Page Analysis
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`.
The CLI daemon also persists cookies and login state in `~/.config/openbrowser/profiles/daemon/storage_state.json`, so authenticated sessions can be reused across later runs.
Setup
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
Workflow
Step 1 -- Navigate and get overview
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)}")
EOFStep 2 -- Extract page metadata
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))
EOFStep 3 -- Detect frameworks and technologies
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}")
EOFStep 4 -- Content summary and statistics
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))
EOFStep 5 -- Analyze heading structure
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}")
EOFStep 6 -- Analyze interactive elements
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")
EOFStep 7 -- Page dimensions and scroll analysis
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")
EOFStep 8 -- Search for specific content patterns
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-ZOpenBrowser is a framework for intelligent browser automation. It combines direct CDP communication with a CodeAgent architecture, where the LLM writes Python code executed in a persistent namespace, to navigate, interact with, and extract information from web pages autonomously.
Repo: billy-enrizky/openbrowser-ai
Other skills on openbrowser-ai.
- /accessibility-audit
Audit web pages for accessibility issues, WCAG compliance, and screen reader compatibility. Trigger when the user asks to: check accessibility, run an a11y audit, test WCAG compliance, check screen reader support, audit ARIA attributes, verify keyboard navigation, find
Open skill - /deep-research
Conduct deep web research using the openbrowser-ai agent: decompose a query, investigate sub-questions across multiple sources, and produce a cited markdown report plus structured JSON under local_docs/research/. Trigger when the user asks to: research a topic, do a deep dive,
Open skill - /e2e-testing
Test web applications end-to-end by simulating user interactions and verifying expected outcomes. Trigger when the user asks to: test a web app, verify a user flow, run end-to-end tests, QA a feature, check that a page works correctly, validate user journeys, or test a
Open skill - /file-download
Download files from websites, save PDFs, and read downloaded content. Trigger when the user asks to: download a file, save a PDF, export a document, fetch a file from a URL, grab a report, download and read a PDF, or save page content as a file.
Open skill - /form-filling
Fill out web forms, submit data, and handle login or registration flows. Trigger when the user asks to: fill a form, submit data on a website, log in to a site, register an account, complete a checkout, enter information into fields, or automate form submission.
Open skill - /web-scraping
Extract structured data from websites, scrape page content, and collect information across multiple pages. Trigger when the user asks to: extract data from a website, scrape a page, collect information from URLs, pull content from web pages, gather data across multiple pages, or
Open skill

