{"id":"05f565bb-91b4-480c-a578-a4691e51e876","entityType":"agent","slug":"clawhub-fasjdas-browser-automation-puppeteer","name":"Browser Automation","canonicalUrl":"https://www.xpersona.co/agent/clawhub-fasjdas-browser-automation-puppeteer","canonicalPath":"/agent/clawhub-fasjdas-browser-automation-puppeteer","generatedAt":"2026-10-10T07:20:57.748Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"editorial-content","verified":true,"confidence":"high","updatedAt":"2026-10-09T23:02:47.355Z","emptyReason":null},"description":"Web scraping and browser automation using Puppeteer. Use when the user wants to extract data from websites, crawl pages, scrape dynamic content rendered by J... Skill: Browser Automation Owner: fasjdas Summary: Web scraping and browser automation using Puppeteer. Use when the user wants to extract data from websites, crawl pages, scrape dynamic content rendered by J... Tags: latest:1.0.0 Version history: v1.0.0 | 2026-05-18T14:57:47.390Z | user - Initial release of browser-automation skill powered by Puppeteer. - Enables web scraping, crawling, form automation, and screensho","descriptionLabel":"Technical summary","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1.9K downloads reported by the source. Last updated 10/9/2026.","installCommand":"clawhub skill install s17dayn2j0y3gje2rqg2bww9s584xgrp:browser-automation-puppeteer","sourceUrl":"https://clawhub.ai/fasjdas/browser-automation-puppeteer","homepage":"https://clawhub.ai/fasjdas/skills/browser-automation-puppeteer","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/fasjdas/browser-automation-puppeteer","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/fasjdas/skills/browser-automation-puppeteer","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":66,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"Web scraping and browser automation using Puppeteer. Use when the user wants to extract data from websites, crawl pages, scrape dynamic content rendered by J..."},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-09T23:02:47.355Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-09T23:02:47.355Z","emptyReason":null},"stars":null,"forks":null,"downloads":1914,"packageName":null,"latestVersion":"1.0.0","tractionLabel":"1.9K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-09T23:02:47.355Z","emptyReason":null},"lastUpdatedAt":"2026-10-09T23:02:47.355Z","lastCrawledAt":"2026-10-09T23:02:47.355Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-10T23:02:47.355Z","lastVerifiedAt":null,"highlights":[{"version":"1.0.0","createdAt":"2026-05-18T14:57:47.390Z","changelog":"- Initial release of browser-automation skill powered by Puppeteer. - Enables web scraping, crawling, form automation, and screenshots for JavaScript-rendered and dynamic content. - Includes usage guidelines, common code patterns, and ready-to-use scripts for scraping, screenshots, and crawling. - Provides selector reference and tips for effective, responsible browser automation.","fileCount":9,"zipByteSize":10854}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s17dayn2j0y3gje2rqg2bww9s584xgrp:browser-automation-puppeteer","setupComplexity":"low","setupSteps":["Setup complexity is LOW. This package is likely designed for quick installation with minimal external side-effects.","Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-fasjdas-browser-automation-puppeteer/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-fasjdas-browser-automation-puppeteer/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-fasjdas-browser-automation-puppeteer/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-fasjdas-browser-automation-puppeteer/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-fasjdas-browser-automation-puppeteer/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-fasjdas-browser-automation-puppeteer/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-10T07:20:57.748Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-fasjdas-browser-automation-puppeteer/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-fasjdas-browser-automation-puppeteer/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-fasjdas-browser-automation-puppeteer/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-fasjdas-browser-automation-puppeteer/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"high","updatedAt":"2026-10-09T23:02:47.355Z","emptyReason":null},"readme":"Skill: Browser Automation\n\nOwner: fasjdas\n\nSummary: Web scraping and browser automation using Puppeteer. Use when the user wants to extract data from websites, crawl pages, scrape dynamic content rendered by J...\n\nTags: latest:1.0.0\n\nVersion history:\n\nv1.0.0 | 2026-05-18T14:57:47.390Z | user\n\n- Initial release of browser-automation skill powered by Puppeteer.\n- Enables web scraping, crawling, form automation, and screenshots for JavaScript-rendered and dynamic content.\n- Includes usage guidelines, common code patterns, and ready-to-use scripts for scraping, screenshots, and crawling.\n- Provides selector reference and tips for effective, responsible browser automation.\n\nArchive index:\n\nArchive v1.0.0: 9 files, 10854 bytes\n\nFiles: LICENSE.txt (1055b), README.md (2679b), references/puppeteer-api.md (4231b), scripts/crawl.js (2419b), scripts/scrape.js (1807b), scripts/screenshot.js (1418b), skill-card.md (2382b), SKILL.md (6673b), _meta.json (147b)\n\nFile v1.0.0:SKILL.md\n\n---\nname: browser-automation\ndescription: Web scraping and browser automation using Puppeteer. Use when the user wants to extract data from websites, crawl pages, scrape dynamic content rendered by JavaScript, take screenshots, fill forms, or automate browser workflows. Triggers include \"scrape\", \"crawl\", \"extract data from\", \"web harvest\", \"take screenshot of\", or any request involving Puppeteer or headless browser automation.\n---\n\n# Browser Automation\n\nWeb scraping and browser automation powered by Puppeteer.\n\n## When to Use\n\n✅ **USE this skill when:**\n\n- \"Scrape data from [URL]\"\n- \"Extract all [products/listings/items] from [website]\"\n- \"Take a screenshot of [page]\"\n- \"Crawl [website] and collect [info]\"\n- \"Fill and submit [form]\"\n- Any JavaScript-rendered content that won't load without a browser\n\n❌ **DON'T use this skill when:**\n\n- Simple static pages → use `web_fetch` instead\n- APIs available → fetch API directly\n- Rate-limited sites → respect robots.txt\n\n## Quick Start\n\n```bash\n# Install Puppeteer\nnpm install puppeteer\n\n# Basic scraping\nnode scripts/scrape.js https://example.com\n```\n\n## Core Patterns\n\n### Launch Browser\n\n```javascript\nconst puppeteer = require('puppeteer');\n\nasync function scrape(url) {\n  const browser = await puppeteer.launch({\n    headless: 'new',\n    args: ['--no-sandbox', '--disable-setuid-sandbox']\n  });\n  \n  const page = await browser.newPage();\n  await page.goto(url, { waitUntil: 'networkidle2' });\n  \n  // ... extract data ...\n  \n  await browser.close();\n}\n```\n\n### Extract Text Content\n\n```javascript\n// Get all text from a selector\nconst titles = await page.$$eval('h2', els => els.map(el => el.textContent.trim()));\n\n// Get text from single element\nconst price = await page.$eval('.price', el => el.textContent.trim());\n```\n\n### Extract HTML\n\n```javascript\nconst html = await page.$eval('.product-list', el => el.innerHTML);\n```\n\n### Extract Attributes\n\n```javascript\nconst links = await page.$$eval('a', els => els.map(el => ({\n  text: el.textContent.trim(),\n  href: el.getAttribute('href')\n})));\n```\n\n### Wait for Content\n\n```javascript\n// Wait for selector\nawait page.waitForSelector('.results', { timeout: 10000 });\n\n// Wait for network idle\nawait page.goto(url, { waitUntil: 'networkidle2' });\n\n// Wait for function\nawait page.waitForFunction(() => document.querySelectorAll('.item').length > 10);\n```\n\n### Pagination\n\n```javascript\nasync function scrapeWithPagination(baseUrl, maxPages = 5) {\n  const browser = await puppeteer.launch({ headless: 'new' });\n  const page = await browser.newPage();\n  \n  let results = [];\n  \n  for (let i = 1; i <= maxPages; i++) {\n    const url = `${baseUrl}?page=${i}`;\n    await page.goto(url, { waitUntil: 'networkidle2' });\n    \n    const items = await page.$$eval('.item', els => \n      els.map(el => el.textContent.trim())\n    );\n    \n    if (items.length === 0) break;\n    results.push(...items);\n  }\n  \n  await browser.close();\n  return results;\n}\n```\n\n### Screenshots\n\n```javascript\n// Full page screenshot\nawait page.screenshot({ path: 'screenshot.png', fullPage: true });\n\n// Element screenshot\nconst element = await page.$('.chart');\nawait element.screenshot({ path: 'chart.png' });\n```\n\n### Block Resources (Speed Up)\n\n```javascript\nawait page.setRequestInterception(true);\npage.on('request', req => {\n  if (['image', 'stylesheet', 'font'].includes(req.resourceType())) {\n    req.abort();\n  } else {\n    req.continue();\n  }\n});\n```\n\n## Scripts\n\n### scrape.js — Basic Scraping\n\n```javascript\n// Usage: node scripts/scrape.js <url> [selector]\nconst puppeteer = require('puppeteer');\n\nconst url = process.argv[2];\nconst selector = process.argv[3] || 'body';\n\nif (!url) {\n  console.error('Usage: node scrape.js <url> [selector]');\n  process.exit(1);\n}\n\n(async () => {\n  const browser = await puppeteer.launch({ headless: 'new' });\n  const page = await browser.newPage();\n  \n  await page.goto(url, { waitUntil: 'networkidle2' });\n  \n  const content = await page.$$eval(selector, els => \n    els.map(el => el.textContent.trim())\n  );\n  \n  console.log(JSON.stringify(content, null, 2));\n  \n  await browser.close();\n})();\n```\n\n### screenshot.js — Page Screenshots\n\n```javascript\n// Usage: node scripts/screenshot.js <url> [output.png]\nconst puppeteer = require('puppeteer');\n\nconst url = process.argv[2];\nconst output = process.argv[3] || 'screenshot.png';\n\nif (!url) {\n  console.error('Usage: node screenshot.js <url> [output.png]');\n  process.exit(1);\n}\n\n(async () => {\n  const browser = await puppeteer.launch({ headless: 'new' });\n  const page = await browser.newPage();\n  \n  await page.goto(url, { waitUntil: 'networkidle2' });\n  await page.screenshot({ path: output, fullPage: true });\n  \n  console.log(`Screenshot saved to ${output}`);\n  await browser.close();\n})();\n```\n\n### crawl.js — Multi-Page Crawler\n\n```javascript\n// Usage: node crawl.js <url> <selector> [maxPages]\nconst puppeteer = require('puppeteer');\n\nconst url = process.argv[2];\nconst selector = process.argv[3];\nconst maxPages = parseInt(process.argv[4]) || 10;\n\nif (!url || !selector) {\n  console.error('Usage: node crawl.js <url> <selector> [maxPages]');\n  process.exit(1);\n}\n\n(async () => {\n  const browser = await puppeteer.launch({ headless: 'new' });\n  const page = await browser.newPage();\n  \n  let allData = [];\n  \n  for (let i = 1; i <= maxPages; i++) {\n    const pageUrl = url.includes('?') ? `${url}&page=${i}` : `${url}?page=${i}`;\n    console.error(`Crawling: ${pageUrl}`);\n    \n    await page.goto(pageUrl, { waitUntil: 'networkidle2' });\n    \n    const data = await page.$$eval(selector, els => \n      els.map(el => el.textContent.trim())\n    );\n    \n    if (data.length === 0) break;\n    allData.push(...data);\n  }\n  \n  console.log(JSON.stringify(allData, null, 2));\n  await browser.close();\n})();\n```\n\n## Common Selectors\n\n| Target | Selector |\n|--------|----------|\n| All links | `a` |\n| All images | `img` |\n| Headings | `h1`, `h2`, `h3` |\n| Lists | `ul li`, `ol li` |\n| Tables | `table tr` |\n| Cards/Items | `.item`, `.card`, `.product` |\n| Prices | `.price`, `[class*=\"price\"]` |\n| Descriptions | `.description`, `.summary` |\n\n## Tips\n\n- **Check robots.txt** before scraping: `curl example.com/robots.txt`\n- **Add delays** between requests to avoid bans: `await new Promise(r => setTimeout(r, 2000))`\n- **Use `networkidle2`** for SPAs (Single Page Apps)\n- **Debug with screenshots** when selectors fail\n- **Set user agent** for sites that block bots:\n  ```javascript\n  await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36');\n  ```\n\n## Reference\n\nFor detailed Puppeteer API, see [puppeteer/docs/api.md](references/puppeteer-api.md).\n\nFile v1.0.0:README.md\n\n# Browser Automation\n\nWeb scraping and browser automation skill using Puppeteer for AI assistants.\n\n## Install\n\n```bash\nnpm install puppeteer\n```\n\n## Scripts\n\n### scrape.js — Extract text from a web page\n\n```bash\nnode scripts/scrape.js <url> [selector]\n```\n\n**Examples:**\n\n```bash\n# Scrape all headings\nnode scripts/scrape.js https://news.ycombinator.com h2\n\n# Scrape with default selector (body)\nnode scripts/scrape.js https://example.com\n\n# Scrape specific elements\nnode scripts/scrape.js https://shop.example.com .product-item\n```\n\n**Output:** JSON array of extracted content\n\n---\n\n### screenshot.js — Capture screenshots\n\n```bash\nnode scripts/screenshot.js <url> [output.png] [--full]\n```\n\n**Examples:**\n\n```bash\n# Basic screenshot (viewport only)\nnode scripts/screenshot.js https://example.com\n\n# Full page screenshot\nnode scripts/screenshot.js https://example.com full.png --full\n\n# Custom output path\nnode scripts/screenshot.js https://example.com ./screenshots/page.png\n```\n\n**Options:**\n\n- `output.png` — Output file path (default: screenshot.png)\n- `--full` — Capture entire scrollable page\n\n---\n\n### crawl.js — Multi-page crawler\n\n```bash\nnode scripts/crawl.js <url> <selector> [maxPages]\n```\n\n**Examples:**\n\n```bash\n# Crawl 5 pages of products\nnode scripts/crawl.js https://shop.example.com/products .product-item 5\n\n# Crawl Hacker News\nnode scripts/crawl.js https://news.ycombinator.com .athing 3\n\n# Default max pages is 10\nnode scripts/crawl.js https://example.com/blog .post-title\n```\n\n**Output:** JSON array of all extracted items across pages\n\n---\n\n## Node.js API\n\nUse the skill's patterns directly in your own scripts:\n\n```javascript\nconst puppeteer = require('puppeteer');\n\nasync function scrape(url, selector) {\n  const browser = await puppeteer.launch({\n    headless: 'new',\n    args: ['--no-sandbox', '--disable-setuid-sandbox']\n  });\n  \n  const page = await browser.newPage();\n  await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36');\n  \n  await page.goto(url, { waitUntil: 'networkidle2' });\n  \n  const results = await page.$$eval(selector, els => \n    els.map(el => el.textContent.trim())\n  );\n  \n  await browser.close();\n  return results;\n}\n\nscrape('https://example.com', 'h1').then(console.log);\n```\n\n---\n\n## Tips\n\n- **Check robots.txt** before scraping: `curl example.com/robots.txt`\n- **Add delays** between requests to avoid getting blocked\n- **Use screenshots** to debug when selectors don't match\n- **Set viewport** before taking screenshots: `await page.setViewport({ width: 1280, height: 800 })`\n\n## Requirements\n\n- Node.js 18+\n- npm\n- Puppeteer (installed via `npm install puppeteer`)\n\n## License\n\nMIT\n\nFile v1.0.0:_meta.json\n\n{\n  \"ownerId\": \"kn7av1vf358r12x3h9g4w71r89831x43\",\n  \"slug\": \"browser-automation-puppeteer\",\n  \"version\": \"1.0.0\",\n  \"publishedAt\": 1779116267390\n}\n\nFile v1.0.0:references/puppeteer-api.md\n\n# Puppeteer API Reference\n\nComplete reference for Puppeteer used in this skill.\n\n## Browser Launch\n\n```javascript\nconst browser = await puppeteer.launch({\n  headless: 'new',           // 'new' = faster headless\n  args: [\n    '--no-sandbox',          // Required for Linux\n    '--disable-setuid-sandbox',\n    '--disable-dev-shm-usage',\n    '--disable-accelerated-2d-canvas',\n    '--no-first-run',\n    '--no-zygote',\n    '--disable-gpu'\n  ]\n});\n```\n\n## Page Navigation\n\n```javascript\nawait page.goto(url, {\n  waitUntil: 'networkidle2',  // Wait until network is idle\n  timeout: 30000               // 30s timeout\n});\n\n// Alternative wait strategies:\n// 'load' - default\n// 'domcontentloaded' - faster\n// 'networkidle0' - stricter\n// 'networkidle' - strictest\n```\n\n## Content Extraction\n\n### $$eval (Multiple Elements)\n\n```javascript\nconst data = await page.$$eval('selector', elements => {\n  return elements.map(el => ({\n    text: el.textContent.trim(),\n    href: el.href,\n    src: el.src\n  }));\n});\n```\n\n### $eval (Single Element)\n\n```javascript\nconst text = await page.$eval('.title', el => el.textContent.trim());\n```\n\n### Inner HTML/Text\n\n```javascript\nconst html = await page.$eval('.container', el => el.innerHTML);\nconst text = await page.$eval('.container', el => el.innerText);\n```\n\n## Waiting\n\n### Wait for Selector\n\n```javascript\nawait page.waitForSelector('.loaded-content', { timeout: 10000 });\n```\n\n### Wait for Function\n\n```javascript\nawait page.waitForFunction(() => {\n  return document.querySelectorAll('.item').length >= 10;\n});\n```\n\n### Wait for Navigation\n\n```javascript\nawait Promise.all([\n  page.waitForNavigation(),\n  page.click('.submit-btn')\n]);\n```\n\n## Click & Type\n\n```javascript\nawait page.click('#submit-button');\nawait page.type('#search-input', 'search term');\nawait page.focus('#input');\nawait page.keyboard.press('Enter');\n```\n\n## Evaluate (Raw JS in Page Context)\n\n```javascript\nconst result = await page.evaluate(() => {\n  const items = document.querySelectorAll('.item');\n  return Array.from(items).map(item => ({\n    title: item.querySelector('h3')?.textContent,\n    price: item.querySelector('.price')?.textContent\n  }));\n});\n```\n\n## Screenshots\n\n```javascript\n// Full page\nawait page.screenshot({ path: 'full.png', fullPage: true });\n\n// Specific area\nawait page.screenshot({ path: 'header.png', clip: { x: 0, y: 0, width: 800, height: 200 } });\n\n// Element\nconst el = await page.$('.chart');\nawait el.screenshot({ path: 'chart.png' });\n```\n\n## PDF Generation\n\n```javascript\nawait page.pdf({\n  path: 'page.pdf',\n  format: 'A4',\n  printBackground: true\n});\n```\n\n## Handle New Tabs/Windows\n\n```javascript\nconst [newPage] = await Promise.all([\n  new Promise(resolve => browser.once('targetcreated', target => resolve(target.page()))),\n  page.click('a[target=\"_blank\"]')\n]);\nawait newPage.waitForSelector('.content');\n```\n\n## Request Interception\n\n```javascript\nawait page.setRequestInterception(true);\npage.on('request', req => {\n  if (req.resourceType() === 'image' || req.resourceType() === 'stylesheet') {\n    req.abort();  // Block images/stylesheets\n  } else {\n    req.continue();\n  }\n});\n```\n\n## Set Headers\n\n```javascript\nawait page.setExtraHTTPHeaders({\n  'Authorization': 'Bearer token123'\n});\n```\n\n## Cookies\n\n```javascript\n// Get cookies\nconst cookies = await page.cookies();\n\n// Set cookies\nawait page.setCookie({\n  name: 'session',\n  value: 'abc123',\n  domain: '.example.com'\n});\n```\n\n## Evaluate XPath\n\n```javascript\nconst elements = await page.evaluate(() => {\n  const result = [];\n  const iter = document.evaluate('//div[@class=\"item\"]', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);\n  for (let i = 0; i < iter.snapshotLength; i++) {\n    result.push(iter.snapshotItem(i).textContent);\n  }\n  return result;\n});\n```\n\n## Common Issues\n\n### Element not found\n\n```javascript\n// Check if element exists\nconst el = await page.$('.selector');\nif (!el) {\n  console.log('Element not found');\n} else {\n  // Proceed\n}\n```\n\n### Timeout errors\n\n```javascript\n// Increase timeout\nawait page.goto(url, { timeout: 60000 });\n\n// Or wrap in try/catch\ntry {\n  await page.waitForSelector('.content', { timeout: 5000 });\n} catch (e) {\n  console.log('Selector not found within timeout');\n}\n```\n\nFile v1.0.0:skill-card.md\n\n## Description:\n\nWeb scraping and browser automation using Puppeteer for extracting data from websites, crawling pages, scraping JavaScript-rendered content, taking screenshots, filling forms, and automating browser workflows.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[fasjdas](https://clawhub.ai/user/fasjdas)\n\n### License/Terms of Use:\n\nMIT\n\n## Use Case:\n\nDevelopers and engineers use this skill to guide browser-based scraping, crawling, screenshot capture, form interaction, and automation for pages that require JavaScript rendering.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Browser automation against arbitrary URLs can expose the agent environment to untrusted web content.\n\nMitigation: Run the skill only in an isolated, unprivileged environment with limited network access and restrict allowed URL targets where possible.\n\nRisk: The browser process could access secrets, credentials, cookies, or internal services if they are available in the execution environment.\n\nMitigation: Do not expose secrets or internal services to the browser process, and require explicit user confirmation before submitting forms or using credentials or cookies.\n\nRisk: Installing Puppeteer without a reviewed lockfile can introduce unpinned dependency changes.\n\nMitigation: Pin Puppeteer and related packages with a reviewed lockfile before production use.\n\n## Reference(s):\n\n- [Puppeteer API Reference](references/puppeteer-api.md)\n- [ClawHub skill page](https://clawhub.ai/fasjdas/skills/browser-automation-puppeteer)\n- [Publisher profile](https://clawhub.ai/user/fasjdas)\n\n## Skill Output:\n\n**Output Type(s):** [text, markdown, code, shell commands, configuration, guidance]\n\n**Output Format:** [Markdown guidance with JavaScript and shell command examples; included scripts emit JSON or PNG files when run.]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [May produce browser screenshots, extracted page data, crawler results, and Puppeteer automation snippets.]\n\n## Skill Version(s):\n\n1.0.0 (source: server release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nFile v1.0.0:LICENSE.txt\n\nMIT License\n\nCopyright (c) 2024\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.","readmeExcerpt":"Skill: Browser Automation Owner: fasjdas Summary: Web scraping and browser automation using Puppeteer. Use when the user wants to extract data from websites, crawl pages, scrape dynamic content rendered by J... Tags: latest:1.0.0 Version history: v1.0.0 | 2026-05-18T14:57:47.390Z | user - Initial release of browser-automation skill powered by Puppeteer. - Enables web scraping, crawling, form automation, and screensho","codeSnippets":[],"executableExamples":[{"language":"bash","snippet":"# Install Puppeteer\nnpm install puppeteer\n\n# Basic scraping\nnode scripts/scrape.js https://example.com"},{"language":"javascript","snippet":"const puppeteer = require('puppeteer');\n\nasync function scrape(url) {\n  const browser = await puppeteer.launch({\n    headless: 'new',\n    args: ['--no-sandbox', '--disable-setuid-sandbox']\n  });\n  \n  const page = await browser.newPage();\n  await page.goto(url, { waitUntil: 'networkidle2' });\n  \n  // ... extract data ...\n  \n  await browser.close();\n}"},{"language":"javascript","snippet":"// Get all text from a selector\nconst titles = await page.$$eval('h2', els => els.map(el => el.textContent.trim()));\n\n// Get text from single element\nconst price = await page.$eval('.price', el => el.textContent.trim());"},{"language":"javascript","snippet":"const html = await page.$eval('.product-list', el => el.innerHTML);"},{"language":"javascript","snippet":"const links = await page.$$eval('a', els => els.map(el => ({\n  text: el.textContent.trim(),\n  href: el.getAttribute('href')\n})));"},{"language":"javascript","snippet":"// Wait for selector\nawait page.waitForSelector('.results', { timeout: 10000 });\n\n// Wait for network idle\nawait page.goto(url, { waitUntil: 'networkidle2' });\n\n// Wait for function\nawait page.waitForFunction(() => document.querySelectorAll('.item').length > 10);"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: browser-automation\ndescription: Web scraping and browser automation using Puppeteer. Use when the user wants to extract data from websites, crawl pages, scrape dynamic content rendered by JavaScript, take screenshots, fill forms, or automate browser workflows. Triggers include \"scrape\", \"crawl\", \"extract data from\", \"web harvest\", \"take screenshot of\", or any request involving Puppeteer or headless browser automation.\n---\n\n# Browser Automation\n\nWeb scraping and browser automation powered by Puppeteer.\n\n## When to Use\n\n✅ **USE this skill when:**\n\n- \"Scrape data from [URL]\"\n- \"Extract all [products/listings/items] from [website]\"\n- \"Take a screenshot of [page]\"\n- \"Crawl [website] and collect [info]\"\n- \"Fill and submit [form]\"\n- Any JavaScript-rendered content that won't load without a browser\n\n❌ **DON'T use this skill when:**\n\n- Simple static pages → use `web_fetch` instead\n- APIs available → fetch API directly\n- Rate-limited sites → respect robots.txt\n\n## Quick Start\n\n```bash\n# Install Puppeteer\nnpm install puppeteer\n\n# Basic scraping\nnode scripts/scrape.js https://example.com\n```\n\n## Core Patterns\n\n### Launch Browser\n\n```javascript\nconst puppeteer = require('puppeteer');\n\nasync function scrape(url) {\n  const browser = await puppeteer.launch({\n    headless: 'new',\n    args: ['--no-sandbox', '--disable-setuid-sandbox']\n  });\n  \n  const page = await browser.newPage();\n  await page.goto(url, { waitUntil: 'networkidle2' });\n  \n  // ... extract data ...\n  \n  await browser.close();\n}\n```\n\n### Extract Text Content\n\n```javascript\n// Get all text from a selector\nconst titles = await page.$$eval('h2', els => els.map(el => el.textContent.trim()));\n\n// Get text from single element\nconst price = await page.$eval('.price', el => el.textContent.trim());\n```\n\n### Extract HTML\n\n```javascript\nconst html = await page.$eval('.product-list', el => el.innerHTML);\n```\n\n### Extract Attributes\n\n```javascript\nconst links = await page.$$eval('a', els => els.map(el => ({\n  text: el.textContent.trim(),\n  href: el.getAttribute('href')\n})));\n```\n\n### Wait for Content\n\n```javascript\n// Wait for selector\nawait page.waitForSelector('.results', { timeout: 10000 });\n\n// Wait for network idle\nawait page.goto(url, { waitUntil: 'networkidle2' });\n\n// Wait for function\nawait page.waitForFunction(() => document.querySelectorAll('.item').length > 10);\n```\n\n### Pagination\n\n```javascript\nasync function scrapeWithPagination(baseUrl, maxPages = 5) {\n  const browser = await puppeteer.launch({ headless: 'new' });\n  const page = await browser.newPage();\n  \n  let results = [];\n  \n  for (let i = 1; i <= maxPages; i++) {\n    const url = `${baseUrl}?page=${i}`;\n    await page.goto(url, { waitUntil: 'networkidle2' });\n    \n    const items = await page.$$eval('.item', els => \n      els.map(el => el.textContent.trim())\n    );\n    \n    if (items.length === 0) break;\n    results.push(...items);\n  }\n  \n  await browser.close();\n  return results;\n}\n```\n\n### Screenshots\n\n```javascript\n// Full page "},{"path":"README.md","content":"# Browser Automation\n\nWeb scraping and browser automation skill using Puppeteer for AI assistants.\n\n## Install\n\n```bash\nnpm install puppeteer\n```\n\n## Scripts\n\n### scrape.js — Extract text from a web page\n\n```bash\nnode scripts/scrape.js <url> [selector]\n```\n\n**Examples:**\n\n```bash\n# Scrape all headings\nnode scripts/scrape.js https://news.ycombinator.com h2\n\n# Scrape with default selector (body)\nnode scripts/scrape.js https://example.com\n\n# Scrape specific elements\nnode scripts/scrape.js https://shop.example.com .product-item\n```\n\n**Output:** JSON array of extracted content\n\n---\n\n### screenshot.js — Capture screenshots\n\n```bash\nnode scripts/screenshot.js <url> [output.png] [--full]\n```\n\n**Examples:**\n\n```bash\n# Basic screenshot (viewport only)\nnode scripts/screenshot.js https://example.com\n\n# Full page screenshot\nnode scripts/screenshot.js https://example.com full.png --full\n\n# Custom output path\nnode scripts/screenshot.js https://example.com ./screenshots/page.png\n```\n\n**Options:**\n\n- `output.png` — Output file path (default: screenshot.png)\n- `--full` — Capture entire scrollable page\n\n---\n\n### crawl.js — Multi-page crawler\n\n```bash\nnode scripts/crawl.js <url> <selector> [maxPages]\n```\n\n**Examples:**\n\n```bash\n# Crawl 5 pages of products\nnode scripts/crawl.js https://shop.example.com/products .product-item 5\n\n# Crawl Hacker News\nnode scripts/crawl.js https://news.ycombinator.com .athing 3\n\n# Default max pages is 10\nnode scripts/crawl.js https://example.com/blog .post-title\n```\n\n**Output:** JSON array of all extracted items across pages\n\n---\n\n## Node.js API\n\nUse the skill's patterns directly in your own scripts:\n\n```javascript\nconst puppeteer = require('puppeteer');\n\nasync function scrape(url, selector) {\n  const browser = await puppeteer.launch({\n    headless: 'new',\n    args: ['--no-sandbox', '--disable-setuid-sandbox']\n  });\n  \n  const page = await browser.newPage();\n  await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36');\n  \n  await page.goto(url, { waitUntil: 'networkidle2' });\n  \n  const results = await page.$$eval(selector, els => \n    els.map(el => el.textContent.trim())\n  );\n  \n  await browser.close();\n  return results;\n}\n\nscrape('https://example.com', 'h1').then(console.log);\n```\n\n---\n\n## Tips\n\n- **Check robots.txt** before scraping: `curl example.com/robots.txt`\n- **Add delays** between requests to avoid getting blocked\n- **Use screenshots** to debug when selectors don't match\n- **Set viewport** before taking screenshots: `await page.setViewport({ width: 1280, height: 800 })`\n\n## Requirements\n\n- Node.js 18+\n- npm\n- Puppeteer (installed via `npm install puppeteer`)\n\n## License\n\nMIT"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn7av1vf358r12x3h9g4w71r89831x43\",\n  \"slug\": \"browser-automation-puppeteer\",\n  \"version\": \"1.0.0\",\n  \"publishedAt\": 1779116267390\n}"},{"path":"references/puppeteer-api.md","content":"# Puppeteer API Reference\n\nComplete reference for Puppeteer used in this skill.\n\n## Browser Launch\n\n```javascript\nconst browser = await puppeteer.launch({\n  headless: 'new',           // 'new' = faster headless\n  args: [\n    '--no-sandbox',          // Required for Linux\n    '--disable-setuid-sandbox',\n    '--disable-dev-shm-usage',\n    '--disable-accelerated-2d-canvas',\n    '--no-first-run',\n    '--no-zygote',\n    '--disable-gpu'\n  ]\n});\n```\n\n## Page Navigation\n\n```javascript\nawait page.goto(url, {\n  waitUntil: 'networkidle2',  // Wait until network is idle\n  timeout: 30000               // 30s timeout\n});\n\n// Alternative wait strategies:\n// 'load' - default\n// 'domcontentloaded' - faster\n// 'networkidle0' - stricter\n// 'networkidle' - strictest\n```\n\n## Content Extraction\n\n### $$eval (Multiple Elements)\n\n```javascript\nconst data = await page.$$eval('selector', elements => {\n  return elements.map(el => ({\n    text: el.textContent.trim(),\n    href: el.href,\n    src: el.src\n  }));\n});\n```\n\n### $eval (Single Element)\n\n```javascript\nconst text = await page.$eval('.title', el => el.textContent.trim());\n```\n\n### Inner HTML/Text\n\n```javascript\nconst html = await page.$eval('.container', el => el.innerHTML);\nconst text = await page.$eval('.container', el => el.innerText);\n```\n\n## Waiting\n\n### Wait for Selector\n\n```javascript\nawait page.waitForSelector('.loaded-content', { timeout: 10000 });\n```\n\n### Wait for Function\n\n```javascript\nawait page.waitForFunction(() => {\n  return document.querySelectorAll('.item').length >= 10;\n});\n```\n\n### Wait for Navigation\n\n```javascript\nawait Promise.all([\n  page.waitForNavigation(),\n  page.click('.submit-btn')\n]);\n```\n\n## Click & Type\n\n```javascript\nawait page.click('#submit-button');\nawait page.type('#search-input', 'search term');\nawait page.focus('#input');\nawait page.keyboard.press('Enter');\n```\n\n## Evaluate (Raw JS in Page Context)\n\n```javascript\nconst result = await page.evaluate(() => {\n  const items = document.querySelectorAll('.item');\n  return Array.from(items).map(item => ({\n    title: item.querySelector('h3')?.textContent,\n    price: item.querySelector('.price')?.textContent\n  }));\n});\n```\n\n## Screenshots\n\n```javascript\n// Full page\nawait page.screenshot({ path: 'full.png', fullPage: true });\n\n// Specific area\nawait page.screenshot({ path: 'header.png', clip: { x: 0, y: 0, width: 800, height: 200 } });\n\n// Element\nconst el = await page.$('.chart');\nawait el.screenshot({ path: 'chart.png' });\n```\n\n## PDF Generation\n\n```javascript\nawait page.pdf({\n  path: 'page.pdf',\n  format: 'A4',\n  printBackground: true\n});\n```\n\n## Handle New Tabs/Windows\n\n```javascript\nconst [newPage] = await Promise.all([\n  new Promise(resolve => browser.once('targetcreated', target => resolve(target.page()))),\n  page.click('a[target=\"_blank\"]')\n]);\nawait newPage.waitForSelector('.content');\n```\n\n## Request Interception\n\n```javascript\nawait page.setRequestInterception(true);\npage.on('request', req => {\n  if (req.resourceType() === 'image'"},{"path":"skill-card.md","content":"## Description:\n\nWeb scraping and browser automation using Puppeteer for extracting data from websites, crawling pages, scraping JavaScript-rendered content, taking screenshots, filling forms, and automating browser workflows.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[fasjdas](https://clawhub.ai/user/fasjdas)\n\n### License/Terms of Use:\n\nMIT\n\n## Use Case:\n\nDevelopers and engineers use this skill to guide browser-based scraping, crawling, screenshot capture, form interaction, and automation for pages that require JavaScript rendering.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Browser automation against arbitrary URLs can expose the agent environment to untrusted web content.\n\nMitigation: Run the skill only in an isolated, unprivileged environment with limited network access and restrict allowed URL targets where possible.\n\nRisk: The browser process could access secrets, credentials, cookies, or internal services if they are available in the execution environment.\n\nMitigation: Do not expose secrets or internal services to the browser process, and require explicit user confirmation before submitting forms or using credentials or cookies.\n\nRisk: Installing Puppeteer without a reviewed lockfile can introduce unpinned dependency changes.\n\nMitigation: Pin Puppeteer and related packages with a reviewed lockfile before production use.\n\n## Reference(s):\n\n- [Puppeteer API Reference](references/puppeteer-api.md)\n- [ClawHub skill page](https://clawhub.ai/fasjdas/skills/browser-automation-puppeteer)\n- [Publisher profile](https://clawhub.ai/user/fasjdas)\n\n## Skill Output:\n\n**Output Type(s):** [text, markdown, code, shell commands, configuration, guidance]\n\n**Output Format:** [Markdown guidance with JavaScript and shell command examples; included scripts emit JSON or PNG files when run.]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [May produce browser screenshots, extracted page data, crawler results, and Puppeteer automation snippets.]\n\n## Skill Version(s):\n\n1.0.0 (source: server release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment."}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":"Web scraping and browser automation using Puppeteer. Use when the user wants to extract data from websites, crawl pages, scrape dynamic content rendered by J... Skill: Browser Automation Owner: fasjdas Summary: Web scraping and browser automation using Puppeteer. Use when the user wants to extract data from websites, crawl pages, scrape dynamic content rendered by J... Tags: latest:1.0.0 Version history: v1.0.0 | 2026-05-18T14:57:47.390Z | user - Initial release of browser-automation skill powered by Puppeteer. - Enables web scraping, crawling, form automation, and screensho","editorialQuality":{"score":100,"threshold":65,"status":"ready","wordCount":1361,"uniquenessScore":45,"reasons":[]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-09T23:02:47.355Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-09T23:02:47.355Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-10T07:20:57.748Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}