The most versatile skill in the OpenClaw toolbox is the browser skill. It spins up a headless (or headed) Chromium instance that the agent can drive just like a human: click links, type into inputs, scroll, scrape, and even take screenshots. If you searched for “OpenClaw browser automation skill for web scraping and forms,” this page is exactly what you need. I’ll walk through installation, navigation commands, form handling, persistent log-in sessions, and real-world recipes that have been running in production on my ClawCloud account for months.

Why a dedicated Chromium instance matters

Most JavaScript scraping libraries reuse puppeteer under the hood. OpenClaw bundles the same engine—but wires it into the agent runtime so you can call it from chat interfaces and schedules. No need for an external process manager. The gateway spins up Chromium, the daemon keeps it alive, and your agent gets a high-level API that works identically whether you run on localhost or ClawCloud’s container fleet.

  • Chromium 124.0.6384.0 is the current pinned build (as of OpenClaw v0.46.2).
  • Runs in a separate Docker namespace on ClawCloud, sandboxed by seccomp.
  • Full JavaScript execution, which beats HTML-only parsers on modern SPAs.
  • Screenshot and PDF export are first-class—handy for audit trails.

If you previously glued together node-cron, puppeteer, and a self-written cookie jar, the integrated setup feels more like cheating.

Installing and enabling the browser skill

You need Node 22 or later. The skill ships in the core package, but it’s off by default to keep cold-start memory low. Enable it explicitly.

1. Install or upgrade OpenClaw

npm install -g openclaw@^0.46.0

Verify:

openclaw --version # 0.46.2

2. Turn on the skill in claw.config.json

Add a block like:

{ "skills": { "browser": { "enabled": true, "headless": true, "timeoutMs": 30000, "maxConcurrentPages": 3 } } }

Restart:

openclaw daemon restart

3. Grant the role to your agent

In the gateway UI → Agent → Permissions → toggle “Browser Control.” Without this the agent refuses to execute navigation commands—even locally—because the devs got tired of accidental infinite-scroll scripts DOS-ing laptops.

Navigating pages and scraping data

Page navigation basics

The DSL is intentionally terse:

agent.browser.goto("https://news.ycombinator.com")

Behind the scenes OpenClaw resolves the promise only after networkidle2—two or fewer active connections. Change the wait-policy when scraping live scoreboards:

agent.browser.goto(url, { waitUntil: "domcontentloaded" })

Scrolling:

agent.browser.scroll({ y: 2000, smooth: true })

Clicking an element via selector:

agent.browser.click("button.buy")

Data extraction patterns

The browser skill exposes agent.browser.extract which runs a supplied function in the page context. Example—grab all story titles from HN:

const titles = await agent.browser.extract(() => [...document.querySelectorAll('.storylink')].map(a => a.textContent) )

Returned values are serialized with structuredClone semantics—so no functions, no DOM nodes, just JSON-serializable data.

For single-line scrapes the built-in shorthand is enough:

const price = await agent.browser.textContent('#priceblock_ourprice')

From ClawCloud’s side the call counts against the skill’s “queries” quota (20 K/month on the free tier). Keep that in mind when wiring tight polling loops.

Form filling and stateful sessions

Forms are two calls: type and submit. Example, subscribe an email address:

await agent.browser.type("input[name='email']", "bot@example.com") await agent.browser.click("button[type='submit']")

Both commands auto-wait for the element to exist. Turn that off by passing { waitFor: false } if the page is a skeleton SPA with hydration later.

OpenClaw keeps cookies, localStorage, and IndexedDB in a named profile. Specify profile on browser.open():

await agent.browser.open({ profile: "personal-amazon" })

The profile folder lives under ~/.openclaw/browser/profiles locally, or an encrypted volume in ClawCloud. That means your agent can log in once and then reuse that session on a nightly schedule without solving captchas every time.

Handling logins with profiles

  1. Create a temporary tunnel. In the gateway, press “Live Browser.” You get a VNC-style window streaming the headless session.
  2. Navigate to the site and log in manually.
  3. Close the tunnel. Cookies persist in the profile.
  4. Disable remote debugging so that future runs stay headless.

Community note: people had trouble with Google two-factor prompts. The workaround is adding --disable-web-security flags in claw.config.json under chromiumArgs. Doesn’t bypass 2FA, but at least the prompt renders.

Capturing screenshots and snapshots

Screenshots are single liners:

await agent.browser.screenshot({ path: "./hn.png", fullPage: true })

The image streams back to ClawCloud’s object store and shows up under the “Artifacts” tab. I keep a GitHub Action that fetches the latest artifact and commits it to the repo for diffs. Cheap visual regression testing.

Snapshots combine HTML + screenshot + console logs. It’s basically puppeteer’s page.pdf but frozen. Config:

await agent.browser.snapshot({ path: "report.clawshot", includeConsole: true, includeNetwork: false })

The .clawshot file is a ZIP you can unzip locally. Folks on Discord use this in security audits: prove that a vulnerability existed at 2024-05-12 T14:05Z.

Practical recipes: price monitoring, flight check-ins, account management

Recipe 1 – Amazon price monitor

Runs every hour, pings Telegram if a LEGO set drops below €85.

// schedule.js module.exports = { cron: "0 * * * *", // top of the hour task: async (agent) => { await agent.browser.open({ profile: "amazon-eu" }) await agent.browser.goto("https://www.amazon.de/dp/B09BNHP93T") const priceText = await agent.browser.textContent('#priceblock_ourprice') const price = parseFloat(priceText.replace(/[^0-9.,]/g, '').replace(',', '.')) if (price < 85) { await agent.telegram.sendMessage(`Price alert €${price}`) } } }

Real-world wart: Amazon occasionally serves robot checks. I added retry: 3 and a 30-second agent.sleep on failure.

Recipe 2 – Automatic flight check-in

Every airline has a different flow, but the skeleton is identical.

await agent.browser.open({ profile: "lufthansa" }) await agent.browser.goto("https://www.lufthansa.com/us/en/online-check-in") await agent.browser.type('#bookingCode', env.BOOKING_CODE) await agent.browser.type('#surname', env.LAST_NAME) await agent.browser.click('button[type="submit"]') await agent.browser.waitForSelector('#seatMap') // pick first available seat await agent.browser.click('.seat.available') await agent.browser.click('#confirm') await agent.telegram.sendMessage('Checked in and picked seat 14A')

Pro tip: set headless:false during development so you can watch the seats fly by.

Recipe 3 – Quarterly account deletion sweep

GDPR lets EU users request deletion. I scheduled a quarterly agent to walk through ten SaaS dashboards and confirm deletion—or at least fetch a PDF copy of the data export.

const targets = [ { url: "https://example.com/settings", removeBtn: "#destroy" }, // ... nine more ] for (const t of targets) { try { await agent.browser.goto(t.url) await agent.browser.click(t.removeBtn) await agent.browser.screenshot({ path: `screens/${t.url.replace(/https?:\/\//,'')}.png` }) } catch (err) { await agent.log.warn(`Failed on ${t.url}: ${err}`) } }

Takeaway: headless browsers remove the tedium of keeping your privacy house in order.

Hard edges, quotas, and production tips

  • Memory leaks – long-lived pages on sites with WebGL chew through RAM. Call agent.browser.close() regularly.
  • Anti-bot scripts – OpenClaw’s default user-agent string ends with OpenClawBot. Override via agent.browser.setUserAgent() if that trips defenses.
  • ClawCloud quotas – Free tier: 1 GB-RAM container, 20 K page actions/month, 500 screenshots. Pay-as-you-go starts after.
  • Timeouts – gateway kills any single command after 60 s unless you bump timeoutMs in config. Useful for PDF generation.
  • Version pinning – add chromiumVersion in skill config to stay on 124 even if upstream bumps to 125.

The browser skill isn’t magic. It breaks when sites deploy window.navigator.webdriver detection or cloudflare challenge pages. When that happens, fall back to HTTP fetch + cheerio or pay the captcha tax.

Next step: ship something this afternoon

OpenClaw’s browser skill is two config lines away. Enable it, grant the permission, write a ten-line script, and push to ClawCloud. You’ll have the agent pinging you on Slack when the price drops, or auto-checking you into your next flight, before lunch. The rest is just iterating on selectors.