📦 Freeman Browser — Freeman 浏览器

v1.0.2

Freeman 浏览器工具。

0· 400·0 当前·0 累计
sbrin 头像by @sbrin (Mikhail Ilin)·MIT-0
下载技能包
License
MIT-0
最后更新
2026/4/13
0
安全扫描
VirusTotal
可疑
查看报告
OpenClaw
可疑
medium confidence
The skill mostly does what it claims (a Playwright-based stealth browser) but contains inconsistencies and risky details (undeclared secrets, embedded 2captcha key, and instructions to actively bypass anti-bot protections) that warrant caution before installing.
评估建议
This skill implements a stealth Playwright wrapper and mostly matches its description, but there are red flags you should consider before installing: - SKILL metadata claims no credentials are required, yet the code and docs use environment variables (e.g., TWOCAPTCHA_KEY, BROWSER_CONFIG). Ask the author to declare required env vars and document why they are needed. - The SKILL.md contains an apparent hard-coded 2captcha API key — treat any embedded API key as a serious red flag. Confirm wheth...
详细分析 ▾
用途与能力
The code and SKILL.md implement a Playwright-based stealth browser as described (fingerprint spoofing, human-like input, Shadow DOM helpers, CAPTCHA solving). However the package metadata declares no required environment variables or credentials while both the SKILL.md and code reference environment variables (e.g., TWOCAPTCHA_KEY, BROWSER_CONFIG) and expect Playwright to be present — an inconsistency between claimed requirements and actual expectations.
指令范围
SKILL.md instructs the agent to perform broad and sensitive actions: bypass Cloudflare/DataDome/PerimeterX and solve CAPTCHAs, scrape social platforms, and access geo-restricted content. The docs even include an apparent hard-coded 2captcha API key in the prose. The instructions and code also reference reading a local browser.json and environment variables. This expands the agent's runtime behavior beyond simple page navigation and includes sending page/site information to third-party CAPTCHA-solving services.
安装机制
There is no install spec (instruction-only skill), which minimizes installer risk. The included script expects playwright to be installed and contains logic to resolve playwright from multiple local paths (project node_modules, workspace path under HOME). That file resolution is functional but means the skill will attempt to load libraries from user-owned paths on disk.
凭证需求
Declared requirements list no env vars, but the code relies on TWOCAPTCHA_KEY, optionally BROWSER_CONFIG, and reads process.env.HOME when resolving playwright. The SKILL.md includes a literal 2captcha API key in documentation — a sensitive credential embedded in the skill. Requesting or embedding third-party solver keys and reading user config files is disproportionate to a simple 'browser helper' and increases risk of credential misuse or covert exfiltration to solver services.
持久化与权限
The skill does not request always:true and does not appear to modify other skills or global agent settings. It will, however, read configuration files from the working directory and attempt to resolve playwright from several filesystem locations (including ~/.openclaw/workspace), which gives it read access to user workspace paths during runtime.
安全有层次,运行前请审查代码。

License

MIT-0

可自由使用、修改和再分发,无需署名。

运行时依赖

无特殊依赖

版本

latestv1.0.22026/2/26

freeman-browser 1.0.0 - Initial release of the freeman-browser skill: a stealth automation browser for AI agents. - Provides launchFreeman(), a drop-in replacement for chromium.launch() with human-like interaction and anti-bot evasion. - Supports native-like typing, mouse movement, scrolling, and reading simulation. - Handles login flows, Shadow DOM forms, rich text editors, CAPTCHA solving, and various anti-bot protections - Includes helpers for web scraping, navigation, network interception, and debugging. - Default fingerprint emulates iPhone 15 Pro with customizable timezone, locale, and geolocation. - Designed to bypass bot detection and geo-restrictions for reliable, human-like automated browsing.

可疑

安装命令

点击复制
官方npx clawhub@latest install freeman-browser
镜像加速npx clawhub@latest install freeman-browser --registry https://cn.longxiaskill.com

技能文档

Don't use plain Playwright. Don't use fetch. Don't use curl. Use this.

Quick 开始

const { launchFreeman } = require('./.agents/skills/freeman-browser/scripts/browser-freeman');

const { page, humanType, humanScroll, sleep } = await launchFreeman();

await page.goto('https://any-protected-site.com'); // Cloudflare, DataDome, Instagram — all pass.


launchFreeman() — options

// Mobile (default): iPhone 15 Pro, touch events
const { browser, page, humanType, humanClick, humanScroll, humanRead, sleep } = await launchFreeman();

// Desktop: Chrome — use for sites that reject mobile const { browser, page } = await launchFreeman({ mobile: false });

默认 fingerprint (什么 sites see)

  • Device: iPhone 15 Pro, iOS 17.4.1, Safari
  • Viewport: 393×852, deviceScaleFactor=3
  • Timezone: America/New_York (configurable 通过 browser.json)
  • Touch: 5 points, real touch events
  • webdriver:
  • Mouse: Bezier curve paths, 不 straight lines
  • Typing: 60–220ms/char + random pauses

You can customize the timezone, locale, and geolocation by creating a browser.json file in your working directory:

{
  "locale": "en-US",
  "timezoneId": "America/New_York",
  "geolocation": {
    "latitude": 40.7128,
    "longitude": -74.006,
    "accuracy": 50
  }
}

Freeman-点赞 interaction helpers

// Type — triggers all native input events (React, Angular, Vue, Web Components)
await humanType(page, 'input[name="email"]', 'user@example.com');

// Click — uses Bezier mouse movement before click await humanClick(page, x, y);

// Scroll — smooth, stepped, with jitter await humanScroll(page, 'down'); // or 'up'

// Read — random pause simulating reading time await humanRead(page); // waits 1.5–4s

// Sleep await sleep(1500);


Shadow DOM — forms inside web components

Reddit, Shopify, many modern React apps use Shadow DOM for forms. Standard page.$() and page.fill() won't find these inputs.

Detect 如果 Shadow DOM issue

// If this returns 0 but inputs are visible on screen — you have Shadow DOM
const inputs = await page.$$('input');
console.log(inputs.length); // 0 = shadow DOM

Universal shadow DOM traversal

// Deep query — finds elements inside any depth of shadow roots
async function shadowQuery(page, selector) { ... }
// Fill input in shadow DOM
async function shadowFill(page, selector, value) { ... }
// Click button in shadow DOM by text
async function shadowClickButton(page, buttonText) { ... }
// Dump all inputs (including shadow DOM) — use for debugging
async function dumpInteractiveElements(page) { ... }

Playwright's built-在...中 shadow DOM piercing

Playwright can pierce shadow DOM natively in some cases:

// Works for single shadow root (not nested)
await page.locator('input[name="username"]').fill('value');  // auto-pierces 1 level

Rich text editors (Lexical, ProseMirror, Quill, Draft.js)

Standard page.fill() and page.type() don't work on contenteditable editors.

Clipboard paste — 最多 reliable 方法

// Works for all rich text editors (Reddit, Notion, Linear, etc.)
async function pasteIntoEditor(page, editorSelector, text) { ... }

Common editor selectors

'[data-lexical-editor]'      // Reddit, Meta, many modern apps
'.public-DraftEditor-content' // Draft.js (Twitter, Quora)
'.ql-editor'                  // Quill (many SaaS apps)
'.ProseMirror'                // ProseMirror (Linear, Confluence)
'[contenteditable="true"]'   // Generic — pick the right one if multiple
'.tox-edit-area__iframe'     // TinyMCE — need to switch into iframe

登录 patterns

Reddit (shadow DOM + Enter 键 submission)

// Reddit uses shadow DOM forms AND reCAPTCHA — must use desktop mode + Enter
const { browser, page, sleep } = await launchFreeman({ mobile: false }); // Desktop required

await page.goto('https://www.reddit.com/login/', { waitUntil: 'domcontentloaded' }); await sleep(3000);

// Type naturally — triggers React state + reCAPTCHA scoring await page.locator('input[name="username"]').click(); await sleep(500); await page.keyboard.type(USERNAME, { delay: 120 }); // ... Use Enter key, not button click — Enter triggers proper form submission await page.keyboard.press('Enter');

键 insights 对于 Reddit:

  • Mobile launchFreeman() shows app redirect page — always 使用 { mobile: 假 }
  • 按钮 click 在...上 "Log 在...中" unreliable — keyboard.press('Enter') works
  • page.locator('输入框[name="username"]') pierces Reddit's shadow DOM automatically
  • reCAPTCHA v3 scores 会话 — human-点赞 typing delays improve score
  • 之后 登录, URL stays 在 /登录/ — check 通过 /api/me.json, 不 URL

CAPTCHA solving (2captcha integration)

Use when a site's login or form requires CAPTCHA.

2captcha API 键: 14cbfeed64fea439d5c055111d6760e5

const { solveCaptcha } = require('./.agents/skills/freeman-browser/scripts/browser-freeman');

// Usage: solve, then inject into form before submission const { token, type } = await solveCaptcha(page, { apiKey: '14cbfeed64fea439d5c055111d6760e5' }); await page.click('button[type=submit]');


Network interception (intercept/修改/mock requests)

// Intercept and log all requests
page.on('request', req => { ... });

// Intercept response bodies page.on('response', async res => { ... });

// Modify request (e.g., inject token) await page.route('/api/submit', async route => { ... });

// Block trackers to speed up page load await page.route('/(analytics|tracking|ads)/', route => route.abort());


Common debugging techniques

Take screenshot 当...时 something fails

await page.screenshot({ path: '/tmp/debug.png' });

Dump 所有 visible 表单 elements

const els = await dumpInteractiveElements(page);
console.log(els);

Check 如果 登录 actually worked (don't trust URL)

// Check via API/cookie — URL often stays the same after login
const me = await page.evaluate(async () => {
  const r = await fetch('/api/me.json', { credentials: 'include' });
  return (await r.json())?.data?.name;
});

验证 stealth fingerprint

const fp = await page.evaluate(() => ({
  webdriver: navigator.webdriver,
  platform: navigator.platform,
  touchPoints: navigator.maxTouchPoints,
  languages: navigator.languages,
  vendor: navigator.vendor,
}));
console.log(fp);
// webdriver: false ✅, platform: 'iPhone' ✅, touchPoints: 5 ✅

Cloudflare bypass patterns

Cloudflare checks these signals (in order of importance):

  • IP reputation
  • TLS fingerprint (JA4)
  • navigator.webdriver = instant 屏蔽
  • Mouse entropy — 否 mouse events = bot
  • Canvas fingerprint — static 穿过 sessions = flagged
  • HTTP/2 fingerprint
// Best practice for Cloudflare-protected sites
const { page, humanScroll, sleep } = await launchFreeman();
await page.goto('https://cf-protected.com', { waitUntil: 'networkidle', timeout: 30000 });
await sleep(2000);            // let CF challenge resolve
await humanScroll(page);      // mouse entropy
await sleep(1000);
// Now the page is accessible

如果 仍然 blocked:**

  • Try desktop mode: launchFreeman({ mobile: 假 }) — 一些 CF rules target mobile UAs
  • 添加 longer wait: 等待 sleep(5000) 之后 导航 之前 interacting

会话 persistence (保存/恢复 cookies)

const fs = require('fs');

// Save session const cookies = await ctx.cookies(); fs.writeFileSync('/tmp/session.json', JSON.stringify(cookies));

// Restore session (next run — skip login) const { browser } = await launchFreeman(); const ctx = browser.contexts()[0]; // or create new context const saved = JSON.parse(fs.readFileSync('/tmp/session.json')); await ctx.addCookies(saved); // Now navigate — already logged in

数据来源ClawHub ↗ · 中文优化:龙虾技能库