Skip to content

LazyLinchen/openclaw-broswer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

win-browser

Remotely control a real Chrome browser on a Windows machine over LAN HTTP — from a NAS, Docker container, or any Linux/Mac client. No Playwright required on the client side.

NAS / Docker (client)                  Windows Machine
  scripts/client.py  ──HTTP POST /start──►  controller.js (Node.js + Playwright)
                     ──HTTP POST /goto ──►    └─ launches Chrome (CDP 127.0.0.1:9222)
                     ──HTTP POST /eval ──►    └─ executes JS inside page
                     ──HTTP GET /screenshot►  └─ returns PNG screenshot
                     ──  all ops via HTTP  ──►

Typical use-cases: login-state reuse, anti-bot site automation (Douyin, Xiaohongshu, 1688, Taobao), remote page scraping in a real Windows browser environment.


File Structure

File Runs on Description
controller/controller.js Windows Node.js HTTP server + Playwright; launches Chrome and exposes a full page-operation API
scripts/client.py NAS / Docker Lightweight HTTP client; pure Python stdlib, zero extra dependencies
references/api.md Full API specification and response format reference

Step 1 — Windows: Start the Controller

Prerequisites

  • Node.js 16+
  • playwright-core: npm install playwright-core
  • Google Chrome installed
  • Firewall rules allowing inbound TCP on port 17373 (controller) and 9223 (CDP proxy)

Setup

git clone https://github.com/LazyLinchen/openclaw-broswe.git
npm init -y
npm install playwright-core
node controller/controller.js

Environment Variables (Windows side)

Variable Default Description
WIN_BROWSER_PORT 17373 Controller HTTP listen port
WIN_BROWSER_TOKEN Auth token (sent as X-Token header)
CHROME_PATH auto-detected Path to chrome.exe
CDP_PORT 9222 Chrome local CDP debug port
CDP_PROXY_PORT 9223 TCP proxy external port (for direct CDP access)
CHROME_USER_DATA_DIR %TEMP%\chrome-cdp-profile Chrome profile directory (preserves login state)

⚠️ Security: The controller listens on 0.0.0.0. Always set WIN_BROWSER_TOKEN to restrict access.

Open Firewall

netsh advfirewall firewall add rule name="win-browser controller" dir=in action=allow protocol=TCP localport=17373
netsh advfirewall firewall add rule name="win-browser CDP proxy"  dir=in action=allow protocol=TCP localport=9223

Step 2 — Client: Set Environment Variables

export WIN_BROWSER_HOST=192.168.1.100   # LAN IP of the Windows machine
export WIN_BROWSER_PORT=17373
export WIN_BROWSER_TOKEN=mysecret       # must match controller

Step 3 — Verify Connectivity

python3 scripts/client.py status

CLI Quick Reference

WB="python3 scripts/client.py"

# Lifecycle
$WB start
$WB status
$WB stop

# Navigation
$WB goto https://www.example.com
$WB goto https://www.example.com --wait-until networkidle

# Screenshot (saved to /tmp/wb-shot.png by default)
$WB shot
$WB shot --path /tmp/shot.png

# Page content
$WB content

# JavaScript evaluation
$WB eval "document.title"
$WB eval '() => [...document.querySelectorAll("h2")].map(e => e.innerText)'

# Data extraction helpers
$WB text "h1.title"
$WB text ".product-name" --all
$WB attr "a" href --all
$WB cookies

# Interaction
$WB click "button.submit"
$WB fill "input#search" "keyword"
$WB press Enter
$WB scroll down 700
$WB scroll up 500

# Wait
$WB wait ".product-list" --state visible --timeout 5000

# Tab management
$WB tabs
$WB switch-tab           # switch to latest tab
$WB switch-tab 0         # switch to tab by index
$WB close-tab
$WB contexts

# Batch mode (one command per line, # for comments)
$WB batch commands.txt
echo -e "start\ngoto https://example.com\nshot\nstop" | $WB batch

HTTP API Summary

All requests require the X-Token header. See references/api.md for the full specification.

Method Path Body Description
POST /start Launch Chrome
GET /status Query controller & browser state
POST /stop Stop Chrome and clean up
POST /goto {url, waitUntil?} Navigate to URL
GET /screenshot Capture viewport (returns PNG binary)
GET /content Get full page HTML
POST /eval {script} Execute JavaScript
POST /click {selector, timeout?} Click element
POST /fill {selector, value} Fill input
POST /press {key} Press keyboard key
POST /scroll {direction, amount?} Mouse-wheel scroll
POST /wait {selector?, state?, timeout?} Wait for element or time
GET /tabs List all open tabs
POST /switch-tab {index?} Switch active tab
POST /close-tab Close current tab
GET /contexts List browser contexts

Architecture Notes

  • controller.js runs on Windows, maintains a persistent Playwright + CDP connection to Chrome, and exposes all page operations over HTTP (~50 ms overhead per call).
  • client.py uses only Python stdlib — no Playwright, no WebSocket, just urllib.
  • Chrome's CDP is bound only to 127.0.0.1:9222; controller.js also starts a TCP proxy on 0.0.0.0:9223 for optional direct CDP access from external tools.

Credit

About

Remotely control a real Chrome browser on a Windows machine over LAN HTTP — from a OpenClaw, Docker container, or any Linux/Mac client. No Playwright required on the client side.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors