Pure search — no rewriting, no filtering, noise handled by the AI. Uses real browser automation (Playwright) for Bing CN anti-bot, with HTTP fallback for international queries. Zero API keys required.
bash
# Search (auto-fetches top 3 page contents)
node scripts/search.js "silver price"
node scripts/search.js "how to deploy docker" --max=5
node scripts/search.js "xxx" --region=cn
node scripts/search.js "xxx" --fetch=5 # fetch top 5
node scripts/search.js "xxx" --no-fetch # search only
# Fetch specific URLs
node scripts/fetch.js "https://example.com/page1" "https://example.com/page2"
text
Domestic (CN IP):
Playwright headless → Bing CN → home page for cookie → search box submit
→ 0 results? fallback to DDG HTML
→ auto-fetch top N page contents
International:
Pure HTTP → DDG HTML parse
→ fetch fails? fallback to Playwright request
→ DDG empty? fallback to Bing
→ auto-fetch top N page contents
All dependencies are installed upfront by the setup script. The skill never runs npm install or pip install at runtime. This avoids audit flags and supply-chain risks.
DependencyPurposeSizeNode.js >= 18Runtime—cheerioHTML parsingsmallcommanderCLI arg parsingsmalliconv-liteGBK charset conversionsmallplaywrightBrowser automation50 MBChromium (Playwright)Browser engine for Bing search + headed fetch150 MB
bash
# Linux / macOS
bash scripts/setup.sh
# Windows
powershell -File scripts/setup.ps1
The scripts auto-detect region and use npmmirror.com mirrors inside China for faster downloads.
bash
cd skills/free-web-search-js
npm install
npx playwright install chromium # ~150 MB
# Verify
node scripts/check-env.js
If you already have Chrome/Chromium installed:
bash
export CHROMIUM_EXECUTABLE_PATH="/path/to/chrome"
node scripts/check-env.js
check-env.js will confirm whether the provided executable is usable.
VariablePurposeCHROMIUM_EXECUTABLE_PATHPath to system Chrome/Chromium, skips 150 MB downloadPLAYWRIGHT_DOWNLOAD_HOSTMirror for Chromium download (auto-set by setup script)BROWSER_DAEMON_IDLE_MSDaemon idle timeout in ms (default 600000 = 10 min)
EngineMethodRegionNotesBing CNPlaywright search box submitDomesticVisits home page first for cookie, then types into search boxDDGPlaywright search box submitInternationalFull browser automation
RegionSearchFetchDomesticBing CN, fallback DDGAuto-fetch top 3InternationalDDG HTML, fallback Playwright request; DDG empty→BingAuto-fetch top 3
On each search, three probes run in parallel — first responder wins:
ProbeServiceLogic1myip.ipip.net / cip.ccReachable from China2ipinfo.io / ipapi.coInternational3cn.bing.comReachable → likely CNFallback—Defaults to domestic
Override with --region=cn or --region=intl if your proxy causes misdetection.
After search, auto-fetches the top N results (default 3).
TierMethodSpeedNotes1Lightweight HTTP + cheerioFastNo browser launch2Playwright headedSlowerFull JS rendering
Tier 1 enhancements:
<script type="application/ld+json">) articleBody/description__NEXT_DATA__ embedded data extractionSmart dedup: domain + path stem (ignores www/m subdomains, tracking params, trailing slash, .html suffix). Bing redirect URLs ( bing.com/ck/) auto-decoded.
Avoid 1.5s+ browser launch overhead by reusing a persistent Chromium instance:
bash
node scripts/browser-daemon.js # Start (run with & or as background job)
node scripts/browser-daemon.js --status # Show status
node scripts/browser-daemon.js --stop # Stop
The daemon auto-exits after 10 minutes of inactivity (configurable via BROWSER_DAEMON_IDLE_MS). Activity is tracked via a .browser-heartbeat file that search.js and fetch.js touch on each connection. The daemon checks the heartbeat every 60 seconds.
bash
cd skills/free-web-search-js
node scripts/check-env.js
node scripts/search.js "OpenClaw" --max 2 --region cn --fetch 0
node scripts/search.js "OpenClaw" --max 2 --region intl --fetch 0
Common issues:
node_modules not found → run npm installExecutable doesn't exist ... → run bash scripts/setup.sh or set CHROMIUM_EXECUTABLE_PATHbrowserType.launch ... closed → headless+no-sandbox is default; run node scripts/check-env.js to diagnose--region=cn / --region=intl, or --fetch 0 to test search alone.browser-heartbeat) and endpoint file ( .browser-endpoint) are written to the skill root directoryli.b_algo, return 0 results--region to override