{"id":"3b278292-4892-4462-a4da-616ea5cfe416","entityType":"agent","slug":"clawhub-ucsdzehualiu-free-web-search-js","name":"Free Web Search Js","canonicalUrl":"https://www.xpersona.co/agent/clawhub-ucsdzehualiu-free-web-search-js","canonicalPath":"/agent/clawhub-ucsdzehualiu-free-web-search-js","generatedAt":"2026-10-11T03:56:40.684Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"editorial-content","verified":true,"confidence":"high","updatedAt":"2026-10-11T00:31:55.962Z","emptyReason":null},"description":"Web search & content fetching via Playwright + HTTP — zero API keys. Searches Bing CN (domestic) or DDG (international), auto-fetches top page contents. For... Skill: Free Web Search Js Owner: ucsdzehualiu Summary: Web search & content fetching via Playwright + HTTP — zero API keys. Searches Bing CN (domestic) or DDG (international), auto-fetches top page contents. For... Tags: latest:29.1.0 Version history: v29.1.0 | 2026-06-22T07:29:35.102Z | user v29.1.0: Add LICENSE, fix playwright dep check, align metadata (version/author), remove dead engine docs, delete stale TEST_RE","descriptionLabel":"Technical summary","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1.2K downloads reported by the source. Last updated 10/11/2026.","installCommand":"clawhub skill install s17bk47xgrxy45rkmxpwv5p1z983nsd8:free-web-search-js","sourceUrl":"https://clawhub.ai/ucsdzehualiu/free-web-search-js","homepage":"https://clawhub.ai/ucsdzehualiu/skills/free-web-search-js","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/ucsdzehualiu/free-web-search-js","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/ucsdzehualiu/skills/free-web-search-js","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":62,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"Web search & content fetching via Playwright + HTTP — zero API keys. Searches Bing CN (domestic) or DDG (international), auto-fetches top page contents. For... "},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-11T00:31:55.962Z","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-11T00:31:55.962Z","emptyReason":null},"stars":null,"forks":null,"downloads":1218,"packageName":null,"latestVersion":"29.1.0","tractionLabel":"1.2K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T00:31:55.891Z","emptyReason":null},"lastUpdatedAt":"2026-10-11T00:31:55.962Z","lastCrawledAt":"2026-10-11T00:31:55.891Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-12T00:31:55.891Z","lastVerifiedAt":null,"highlights":[{"version":"29.1.0","createdAt":"2026-06-22T07:29:35.102Z","changelog":"v29.1.0: Add LICENSE, fix playwright dep check, align metadata (version/author), remove dead engine docs, delete stale TEST_REPORT.md, surface differentiator (pure search + Playwright anti-bot)","fileCount":14,"zipByteSize":31842},{"version":"29.0.0","createdAt":"2026-06-17T16:46:08.825Z","changelog":"Version 29.0.0 - Major version update with no user-facing or documented feature changes. - No adjustments to usage, APIs, or installation are noted in SKILL.md. - Internal file changes only; external behavior remains unchanged. - Safe to upgrade with no required migration steps.","fileCount":14,"zipByteSize":32434},{"version":"28.1.1","createdAt":"2026-06-17T15:20:09.396Z","changelog":"**Changelog for v28.1.1** - Major README and SKILL.md rewrite/cleanup: clearer English docs, condensed usage and install instructions, private-by-design notes. - All documentation now emphasizes region-aware autodetection, no runtime `npm install`, and privacy/supply-chain safety. - Added Windows setup script (`scripts/setup.ps1`); removed redundant and legacy scripts. - Daemon browser reuse and heartbeat process now documented; config validation clarified. - Skill triggers updated for broader English and Chinese search phrases. - No core logic changes outside documentation and setup scripts.","fileCount":14,"zipByteSize":33497},{"version":"1.0.1","createdAt":"2026-05-26T02:53:04.175Z","changelog":"- Enhanced reliability: search/fetch now prefer HTTP, falling back to Playwright only when needed for better cross-platform compatibility. - Playwright now defaults to headless mode and disables sandbox for improved support on servers and containers. - Overseas (DDG) search uses Playwright request as a fallback if fetch fails, and will retry Bing if still no results. - Improved environment checks: now verifies actual browser executables, not just the presence of the cache directory. - Installation help updated—added troubleshooting for Playwright download interruptions and Chromium path overrides. - SKILL.md now has a YAML frontmatter header and more detailed usage/troubleshooting sections.","fileCount":30,"zipByteSize":49035},{"version":"1.0.0","createdAt":"2026-04-25T07:38:13.589Z","changelog":"Initial release of free-web-search-js, a one-step Playwright-based web search and content scraping tool, requiring no API keys. - Supports both domestic (Bing CN via Playwright) and overseas (DDG via HTTP) search engines, auto-detecting region and using appropriate engines/strategies. - Automatically crawls and summarizes top 3 search results after searching. - Intelligent duplication removal based on core URLs, with Bing redirect decoding. - Adaptive content extraction: handles API responses, JSON-LD, Next.js data, meta tags, and GBK encoding. - Performance-optimized with optional browser daemon for faster repeated searches. - CLI tools for both search+fetch and standalone fetching by URL. - Includes robust region/IP detection and fallback strategies; manual override available.","fileCount":26,"zipByteSize":40958}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s17bk47xgrxy45rkmxpwv5p1z983nsd8:free-web-search-js","setupComplexity":"medium","setupSteps":["Setup complexity is MEDIUM. Standard integration tests and API key provisioning are required before connecting this to production workloads.","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-ucsdzehualiu-free-web-search-js/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-ucsdzehualiu-free-web-search-js/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-ucsdzehualiu-free-web-search-js/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-ucsdzehualiu-free-web-search-js/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-ucsdzehualiu-free-web-search-js/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-ucsdzehualiu-free-web-search-js/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-11T03:56:40.681Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-ucsdzehualiu-free-web-search-js/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-ucsdzehualiu-free-web-search-js/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-ucsdzehualiu-free-web-search-js/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-ucsdzehualiu-free-web-search-js/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-11T00:31:55.962Z","emptyReason":null},"readme":"Skill: Free Web Search Js\n\nOwner: ucsdzehualiu\n\nSummary: Web search & content fetching via Playwright + HTTP — zero API keys. Searches Bing CN (domestic) or DDG (international), auto-fetches top page contents. For...\n\nTags: latest:29.1.0\n\nVersion history:\n\nv29.1.0 | 2026-06-22T07:29:35.102Z | user\n\nv29.1.0: Add LICENSE, fix playwright dep check, align metadata (version/author), remove dead engine docs, delete stale TEST_REPORT.md, surface differentiator (pure search + Playwright anti-bot)\n\nv29.0.0 | 2026-06-17T16:46:08.825Z | auto\n\nVersion 29.0.0\n\n- Major version update with no user-facing or documented feature changes.\n- No adjustments to usage, APIs, or installation are noted in SKILL.md.\n- Internal file changes only; external behavior remains unchanged.\n- Safe to upgrade with no required migration steps.\n\nv28.1.1 | 2026-06-17T15:20:09.396Z | auto\n\n**Changelog for v28.1.1**\n\n- Major README and SKILL.md rewrite/cleanup: clearer English docs, condensed usage and install instructions, private-by-design notes.\n- All documentation now emphasizes region-aware autodetection, no runtime `npm install`, and privacy/supply-chain safety.\n- Added Windows setup script (`scripts/setup.ps1`); removed redundant and legacy scripts.\n- Daemon browser reuse and heartbeat process now documented; config validation clarified.\n- Skill triggers updated for broader English and Chinese search phrases.\n- No core logic changes outside documentation and setup scripts.\n\nv1.0.1 | 2026-05-26T02:53:04.175Z | user\n\n- Enhanced reliability: search/fetch now prefer HTTP, falling back to Playwright only when needed for better cross-platform compatibility.\n- Playwright now defaults to headless mode and disables sandbox for improved support on servers and containers.\n- Overseas (DDG) search uses Playwright request as a fallback if fetch fails, and will retry Bing if still no results.\n- Improved environment checks: now verifies actual browser executables, not just the presence of the cache directory.\n- Installation help updated—added troubleshooting for Playwright download interruptions and Chromium path overrides.\n- SKILL.md now has a YAML frontmatter header and more detailed usage/troubleshooting sections.\n\nv1.0.0 | 2026-04-25T07:38:13.589Z | user\n\nInitial release of free-web-search-js, a one-step Playwright-based web search and content scraping tool, requiring no API keys.\n\n- Supports both domestic (Bing CN via Playwright) and overseas (DDG via HTTP) search engines, auto-detecting region and using appropriate engines/strategies.\n- Automatically crawls and summarizes top 3 search results after searching.\n- Intelligent duplication removal based on core URLs, with Bing redirect decoding.\n- Adaptive content extraction: handles API responses, JSON-LD, Next.js data, meta tags, and GBK encoding.\n- Performance-optimized with optional browser daemon for faster repeated searches.\n- CLI tools for both search+fetch and standalone fetching by URL.\n- Includes robust region/IP detection and fallback strategies; manual override available.\n\nArchive index:\n\nArchive v29.1.0: 14 files, 31842 bytes\n\nFiles: _meta.json (138b), LICENSE (1093b), package-lock.json (12821b), package.json (687b), README.md (5345b), scripts/browser-daemon.js (4559b), scripts/check-env.js (2558b), scripts/fetch.js (15864b), scripts/playwright-support.js (4073b), scripts/search.js (16458b), scripts/setup.ps1 (5112b), scripts/setup.sh (4540b), skill-card.md (2312b), SKILL.md (7745b)\n\nFile v29.1.0:SKILL.md\n\n---\nname: free-web-search-js\ndescription: Web search & content fetching via Playwright + HTTP — zero API keys. Searches Bing CN (domestic) or DDG (international), auto-fetches top page contents. For real-time search, fact-checking, news, tutorials, documentation lookup.\nversion: 29.1.0\nlicense: MIT\nauthor: free-web-search-js\ntrigger_keywords:\n  - search\n  - find\n  - look up\n  - 搜索\n  - 查一下\n  - 找一下\ntools:\n  - name: search\n    description: Search + auto-fetch; Bing CN via Playwright, DDG via HTTP\n    script: scripts/search.js\n    parameters:\n      query:\n        type: string\n        description: \"Search query\"\n        required: true\n      max:\n        type: integer\n        description: \"Max results 1-30, default 10\"\n        required: false\n      region:\n        type: string\n        description: \"Region: auto/cn/intl, defaults to auto (IP detection)\"\n        required: false\n  - name: fetch\n    description: Fetch page content by URL, HTTP first with headed fallback\n    script: scripts/fetch.js\n    parameters:\n      urls:\n        type: string\n        description: \"URLs to fetch, space-separated\"\n        required: true\n      max-len:\n        type: integer\n        description: \"Max chars per page, default 12000\"\n        required: false\n---\n\n# free-web-search-js\n\nPure 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.\n\n## Quick start\n\n```bash\n# Search (auto-fetches top 3 page contents)\nnode scripts/search.js \"silver price\"\nnode scripts/search.js \"how to deploy docker\" --max=5\nnode scripts/search.js \"xxx\" --region=cn\nnode scripts/search.js \"xxx\" --fetch=5         # fetch top 5\nnode scripts/search.js \"xxx\" --no-fetch        # search only\n\n# Fetch specific URLs\nnode scripts/fetch.js \"https://example.com/page1\" \"https://example.com/page2\"\n```\n\n## Architecture\n\n```\nDomestic (CN IP):\n  Playwright headless → Bing CN → home page for cookie → search box submit\n  → 0 results? fallback to DDG HTML\n  → auto-fetch top N page contents\n\nInternational:\n  Pure HTTP → DDG HTML parse\n  → fetch fails? fallback to Playwright request\n  → DDG empty? fallback to Bing\n  → auto-fetch top N page contents\n```\n\n## Install\n\nAll 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.\n\n### Prerequisites\n\n| Dependency | Purpose | Size |\n|---|---|---|\n| Node.js >= 18 | Runtime | — |\n| cheerio | HTML parsing | small |\n| commander | CLI arg parsing | small |\n| iconv-lite | GBK charset conversion | small |\n| playwright | Browser automation | ~50 MB |\n| Chromium (Playwright) | Browser engine for Bing search + headed fetch | ~150 MB |\n\n### One-command setup\n\n```bash\n# Linux / macOS\nbash scripts/setup.sh\n\n# Windows\npowershell -File scripts/setup.ps1\n```\n\nThe scripts auto-detect region and use `npmmirror.com` mirrors inside China for faster downloads.\n\n### Manual install\n\n```bash\ncd skills/free-web-search-js\nnpm install\nnpx playwright install chromium    # ~150 MB\n\n# Verify\nnode scripts/check-env.js\n```\n\nIf you already have Chrome/Chromium installed:\n\n```bash\nexport CHROMIUM_EXECUTABLE_PATH=\"/path/to/chrome\"\nnode scripts/check-env.js\n```\n\n`check-env.js` will confirm whether the provided executable is usable.\n\n### Environment variables\n\n| Variable | Purpose |\n|---|---|\n| `CHROMIUM_EXECUTABLE_PATH` | Path to system Chrome/Chromium, skips 150 MB download |\n| `PLAYWRIGHT_DOWNLOAD_HOST` | Mirror for Chromium download (auto-set by setup script) |\n| `BROWSER_DAEMON_IDLE_MS` | Daemon idle timeout in ms (default 600000 = 10 min) |\n\n## Search engines\n\n| Engine | Method | Region | Notes |\n|---|---|---|---|\n| Bing CN | Playwright search box submit | Domestic | Visits home page first for cookie, then types into search box |\n| DDG | Playwright search box submit | International | Full browser automation |\n\n### Strategy\n\n| Region | Search | Fetch |\n|---|---|---|\n| Domestic | Bing CN, fallback DDG | Auto-fetch top 3 |\n| International | DDG HTML, fallback Playwright request; DDG empty→Bing | Auto-fetch top 3 |\n\n### IP detection\n\nOn each search, three probes run in parallel — first responder wins:\n\n| Probe | Service | Logic |\n|---|---|---|\n| 1 | `myip.ipip.net` / `cip.cc` | Reachable from China |\n| 2 | `ipinfo.io` / `ipapi.co` | International |\n| 3 | `cn.bing.com` | Reachable → likely CN |\n| Fallback | — | Defaults to domestic |\n\nOverride with `--region=cn` or `--region=intl` if your proxy causes misdetection.\n\n## Fetch mode\n\nAfter search, auto-fetches the top N results (default 3).\n\n| Tier | Method | Speed | Notes |\n|---|---|---|---|\n| 1 | Lightweight HTTP + cheerio | Fast | No browser launch |\n| 2 | Playwright headed | Slower | Full JS rendering |\n\nTier 1 enhancements:\n- JSON API response detection with structured content extraction\n- JSON-LD (`<script type=\"application/ld+json\">`) articleBody/description\n- `__NEXT_DATA__` embedded data extraction\n- Meta tag fallback (og:description / description)\n- Auto GBK charset detection & conversion\n\n## Deduplication\n\nSmart dedup: domain + path stem (ignores www/m subdomains, tracking params, trailing slash, .html suffix). Bing redirect URLs (`bing.com/ck/`) auto-decoded.\n\n## Browser daemon (optional, ~70% faster)\n\nAvoid 1.5s+ browser launch overhead by reusing a persistent Chromium instance:\n\n```bash\nnode scripts/browser-daemon.js            # Start (run with & or as background job)\nnode scripts/browser-daemon.js --status   # Show status\nnode scripts/browser-daemon.js --stop     # Stop\n```\n\nThe 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.\n\n## Verification & troubleshooting\n\n```bash\ncd skills/free-web-search-js\nnode scripts/check-env.js\nnode scripts/search.js \"OpenClaw\" --max 2 --region cn --fetch 0\nnode scripts/search.js \"OpenClaw\" --max 2 --region intl --fetch 0\n```\n\nCommon issues:\n- `node_modules not found` → run `npm install`\n- `Executable doesn't exist ...` → run `bash scripts/setup.sh` or set `CHROMIUM_EXECUTABLE_PATH`\n- `browserType.launch ... closed` → headless+no-sandbox is default; run `node scripts/check-env.js` to diagnose\n- 0 search results → try `--region=cn` / `--region=intl`, or `--fetch 0` to test search alone\n\n## Privacy & network\n\n- Searches connect to Bing CN / DDG HTML / Sogou directly from the skill's runtime — no intermediate proxy\n- The daemon heartbeat file (`.browser-heartbeat`) and endpoint file (`.browser-endpoint`) are written to the skill root directory\n- No analytics, no telemetry, no third-party logging beyond the search engine's own server logs\n- Headed warm-up fetches: Cookie warm-up for Bing uses a headed browser context to obtain session cookies from the search engine home page; no cookies are persisted to disk between sessions\n\n## Known limitations\n\n- **First domestic search slower**: Chromium cold start takes 3–6s; daemon avoids this\n- **Bing CN instant answers**: Weather/calculator cards don't use `li.b_algo`, return 0 results\n- **Sogou HTTP unstable**: No cookie, easily blocked by anti-crawl\n- **JS-required pages**: HTTP tier returns empty for SPA pages — headed tier catches them\n- **Region-specific sites**: Some domestic sites time out from international IPs\n- **Proxy interference**: IP detection may misclassify behind proxies — use `--region` to override\n- **DDG blocked in China**: DDG HTML is not reachable from mainland China; domestic strategy avoids it\n\nFile v29.1.0:README.md\n\n# free-web-search-js\n\n## 项目简介\n\nfree-web-search-js 是一个基于 Playwright和JS写 的免费网络搜索skill 可用于CC或者openclaw（clawhub install free-web-search-js），无需 API Key，支持国内和海外搜索，自动抓取搜索结果内容。\n\n**Pure search — no rewriting, no filtering.** 噪音交给 AI 处理。使用真实浏览器（Playwright）处理 Bing CN 反爬，国际查询则使用 HTTP 加速。\n\n- **免费**：零成本使用，无需 API Key\n- **稳定**：根据网络环境自动切换搜索策略，提高可达性\n- **快速**：首次搜索 3\\~6 秒，后续复用浏览器更快\n- **自动抓取**：搜索后自动抓取 top N 条结果内容\n- **跨区域**：国内使用 Bing，海外使用 DDG\n\n## 支持的搜索引擎\n\n| 引擎       | 协议               | 区域 | 说明                                          |\n| -------- | ---------------- | -- | ------------------------------------------- |\n| Bing CN  | Playwright 搜索框提交 | 国内 | 先访问首页拿 cookie，再搜索框输入提交                      |\n| DDG | Playwright 搜索框提交 | 海外 | 完整浏览器自动化                         |\n\n## 安装\n\n### 前置依赖\n\n| 依赖            | 说明                     | 大小/耗时              |\n| ------------- | ---------------------- | ------------------ |\n| Node.js >= 18 | 运行时                    | —                  |\n| cheerio       | HTML 解析                | 小，秒装               |\n| commander     | CLI 参数解析               | 小，秒装               |\n| iconv-lite    | GBK 编码转换               | 小，秒装               |\n| playwright    | 浏览器自动化（Bing 搜索 + 抓取兜底） | \\~50MB             |\n| Chromium      | Playwright 专用浏览器       | **\\~150MB，需几分钟下载** |\n\n### 安装步骤\n\n#### 一键安装\n\n```bash\n# Linux/macOS\nbash scripts/setup.sh\n\n# Windows\npowershell -File scripts/setup.ps1\n```\n\n#### 手动安装\n\n```bash\n# 进入项目目录\ncd free-web-search-js\n\n# 安装依赖\nnpm install\n\n# 安装 Playwright 浏览器\nnpx playwright install chromium    # ~150MB，需几分钟\n```\n\n### 国内镜像加速\n\n```bash\n# npm 镜像\nnpm install --registry=https://registry.npmmirror.com\n\n# Playwright/Chromium 镜像\nPLAYWRIGHT_DOWNLOAD_HOST=https://npmmirror.com/mirrors/playwright npx playwright install chromium\n```\n\n### 验证环境\n\n```bash\nnode scripts/check-env.js\n```\n\n## 用法\n\n### 搜索（搜 + 自动抓内容）\n\n```bash\n# 基本搜索\nnode scripts/search.js \"白银价格\"\n\n# 控制结果数量\nnode scripts/search.js \"how to deploy docker\" --max=5\n\n# 指定区域\nnode scripts/search.js \"xxx\" --region=cn\n\n# 控制抓取数量\nnode scripts/search.js \"xxx\" --fetch=5          # 抓前5条\n\n# 只搜索不抓取\nnode scripts/search.js \"xxx\" --no-fetch\n\n# 控制单页最大字符数\nnode scripts/search.js \"xxx\" --max-len=8000\n```\n\n### 单独抓取（给定 URL）\n\n```bash\nnode scripts/fetch.js \"https://example.com/page1\" \"https://example.com/page2\"\n```\n\n## 性能优化：浏览器守护进程\n\n搜索和抓取可复用浏览器守护进程，**提速约 70%**：\n\n```bash\nnode scripts/browser-daemon.js &       # 启动\nnode scripts/browser-daemon.js --status # 状态\nnode scripts/browser-daemon.js --stop   # 停止\n```\n\n守护进程空闲 10 分钟自动退出。\n\n## 架构\n\n### 国内搜索流程\n\n```\nPlaywright 打开 Bing → 首页拿 cookie → 搜索框提交 → 自动抓取 top N 页面内容\n延迟：首次 3~6s（启动浏览器），后续复用更快\n```\n\n### 海外搜索流程\n\n```\n纯 HTTP → DDG HTML 解析 → 自动抓取 top N 页面内容\n延迟：几百ms~1s\n```\n\n### 抓取模式\n\n| 层级  | 方式                | 速度   | 说明             |\n| --- | ----------------- | ---- | -------------- |\n| 第1层 | 轻量 HTTP + cheerio | ⚡ 秒出 | 不启动浏览器         |\n| 第2层 | Playwright headed | 🟡 慢 | 完整浏览器，支持 JS 渲染 |\n\n## 区域检测\n\n每次搜索时自动检测，三轮探测并行，谁先成功用谁：\n\n| 轮次  | 探测服务                       | 逻辑      |\n| --- | -------------------------- | ------- |\n| 第1轮 | `myip.ipip.net` / `cip.cc` | 国内可达优先  |\n| 第2轮 | `ipinfo.io` / `ipapi.co`   | 国际探测    |\n| 第3轮 | 试连 `cn.bing.com`           | 能通大概率国内 |\n| 兜底  | —                          | 默认国内    |\n\n## 去重\n\n智能去重：域名 + 路径主干（忽略 www/m 子域、tracking 参数、尾部斜杠、.html 后缀）。\n\nBing 跳转 URL（`bing.com/ck/`）自动解码为直链。\n\n## 已知限制\n\n- **国内首次搜索较慢**：需启动 Chromium（3\\~6s），后续复用更快\n- **Bing CN 即时答案不返回**：天气、计算器等即时卡片不走 `li.b_algo`，搜索结果为 0\n- **搜狗 HTTP 不稳定**：无 cookie 纯请求结果可能为空（`--engine=sogou` 慎用）\n- **部分站点 HTTP 抓不到**：需要 JS 渲染的页面——HTTP 失败会自动 headed 重试\n- **部分站点海外不可达**：国内专属站点从海外访问可能超时\n- **代理干扰 IP 检测**：出口 IP 走代理时可能误判区域，用 `--region=cn/intl` 手动指定\n- **海外引擎国内不可达**：DDG 在国内被墙，国内策略不使用\n\n## 许可证\n\nMIT License\n\nFile v29.1.0:_meta.json\n\n{\n  \"ownerId\": \"kn7ecgbzbya89gesghbv1kty9d82r8e4\",\n  \"slug\": \"free-web-search-js\",\n  \"version\": \"29.1.0\",\n  \"publishedAt\": 1782113375102\n}\n\nFile v29.1.0:skill-card.md\n\n## Description:\n\nFree Web Search Js searches the web with Playwright and HTTP, using Bing CN or DuckDuckGo and optionally fetching page content without API keys.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[ucsdzehualiu](https://clawhub.ai/user/ucsdzehualiu)\n\n### License/Terms of Use:\n\nMIT\n\n## Use Case:\n\nDevelopers and agents use this skill to look up current web information, fact-check claims, find documentation or tutorials, and fetch page text for downstream reasoning.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill can fetch arbitrary HTTP URLs from the agent runtime, which can expose internal, localhost, cloud metadata, or private-network endpoints if misused.\n\nMitigation: Use it in an isolated environment with restricted network access, avoid sensitive URLs, and prefer explicit --region plus --no-fetch when privacy matters.\n\nRisk: The skill may run untrusted pages in Chromium while default browser launch flags disable the browser sandbox.\n\nMitigation: Update Playwright before sensitive use and remove the default no-sandbox browser flags on hosts where browser isolation matters.\n\nRisk: Queries, fetched URLs, and page requests are sent directly to search engines and target websites from the runtime.\n\nMitigation: Do not submit confidential queries or URLs, and review fetched content before relying on it in downstream decisions.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/ucsdzehualiu/skills/free-web-search-js)\n- [ClawHub publisher profile](https://clawhub.ai/user/ucsdzehualiu)\n- [Node.js](https://nodejs.org)\n\n## Skill Output:\n\n**Output Type(s):** [text, json]\n\n**Output Format:** [JSON containing search results, URLs, snippets, and fetched page text.]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Result count and per-page content length are configurable; search may auto-fetch top results unless disabled.]\n\n## Skill Version(s):\n\n29.1.0 (source: frontmatter, package.json, 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 v29.1.0:package-lock.json\n\n{\n  \"name\": \"free-web-search-js\",\n  \"version\": \"28.1.0\",\n  \"lockfileVersion\": 3,\n  \"requires\": true,\n  \"packages\": {\n    \"\": {\n      \"name\": \"free-web-search-js\",\n      \"version\": \"28.1.0\",\n      \"dependencies\": {\n        \"cheerio\": \"~1.0.0\",\n        \"commander\": \"~12.1.0\",\n        \"iconv-lite\": \"~0.6.3\",\n        \"playwright\": \"~1.52.0\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/boolbase\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmmirror.com/boolbase/-/boolbase-1.0.0.tgz\",\n      \"integrity\": \"sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==\",\n      \"license\": \"ISC\"\n    },\n    \"node_modules/cheerio\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmmirror.com/cheerio/-/cheerio-1.0.0.tgz\",\n      \"integrity\": \"sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"cheerio-select\": \"^2.1.0\",\n        \"dom-serializer\": \"^2.0.0\",\n        \"domhandler\": \"^5.0.3\",\n        \"domutils\": \"^3.1.0\",\n        \"encoding-sniffer\": \"^0.2.0\",\n        \"htmlparser2\": \"^9.1.0\",\n        \"parse5\": \"^7.1.2\",\n        \"parse5-htmlparser2-tree-adapter\": \"^7.0.0\",\n        \"parse5-parser-stream\": \"^7.1.2\",\n        \"undici\": \"^6.19.5\",\n        \"whatwg-mimetype\": \"^4.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=18.17\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/cheeriojs/cheerio?sponsor=1\"\n      }\n    },\n    \"node_modules/cheerio-select\": {\n      \"version\": \"2.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/cheerio-select/-/cheerio-select-2.1.0.tgz\",\n      \"integrity\": \"sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==\",\n      \"license\": \"BSD-2-Clause\",\n      \"dependencies\": {\n        \"boolbase\": \"^1.0.0\",\n        \"css-select\": \"^5.1.0\",\n        \"css-what\": \"^6.1.0\",\n        \"domelementtype\": \"^2.3.0\",\n        \"domhandler\": \"^5.0.3\",\n        \"domutils\": \"^3.0.1\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/fb55\"\n      }\n    },\n    \"node_modules/commander\": {\n      \"version\": \"12.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/commander/-/commander-12.1.0.tgz\",\n      \"integrity\": \"sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/css-select\": {\n      \"version\": \"5.2.2\",\n      \"resolved\": \"https://registry.npmmirror.com/css-select/-/css-select-5.2.2.tgz\",\n      \"integrity\": \"sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==\",\n      \"license\": \"BSD-2-Clause\",\n      \"dependencies\": {\n        \"boolbase\": \"^1.0.0\",\n        \"css-what\": \"^6.1.0\",\n        \"domhandler\": \"^5.0.2\",\n        \"domutils\": \"^3.0.1\",\n        \"nth-check\": \"^2.0.1\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/fb55\"\n      }\n    },\n    \"node_modules/css-what\": {\n      \"version\": \"6.2.2\",\n      \"resolved\": \"https://registry.npmmirror.com/css-what/-/css-what-6.2.2.tgz\",\n      \"integrity\": \"sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==\",\n      \"license\": \"BSD-2-Clause\",\n      \"engines\": {\n        \"node\": \">= 6\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/fb55\"\n      }\n    },\n    \"node_modules/dom-serializer\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmmirror.com/dom-serializer/-/dom-serializer-2.0.0.tgz\",\n      \"integrity\": \"sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"domelementtype\": \"^2.3.0\",\n        \"domhandler\": \"^5.0.2\",\n        \"entities\": \"^4.2.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/cheeriojs/dom-serializer?sponsor=1\"\n      }\n    },\n    \"node_modules/domelementtype\": {\n      \"version\": \"2.3.0\",\n      \"resolved\": \"https://registry.npmmirror.com/domelementtype/-/domelementtype-2.3.0.tgz\",\n      \"integrity\": \"sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==\",\n      \"funding\": [\n        {\n          \"type\": \"github\",\n          \"url\": \"https://github.com/sponsors/fb55\"\n        }\n      ],\n      \"license\": \"BSD-2-Clause\"\n    },\n    \"node_modules/domhandler\": {\n      \"version\": \"5.0.3\",\n      \"resolved\": \"https://registry.npmmirror.com/domhandler/-/domhandler-5.0.3.tgz\",\n      \"integrity\": \"sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==\",\n      \"license\": \"BSD-2-Clause\",\n      \"dependencies\": {\n        \"domelementtype\": \"^2.3.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/fb55/domhandler?sponsor=1\"\n      }\n    },\n    \"node_modules/domutils\": {\n      \"version\": \"3.2.2\",\n      \"resolved\": \"https://registry.npmmirror.com/domutils/-/domutils-3.2.2.tgz\",\n      \"integrity\": \"sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==\",\n      \"license\": \"BSD-2-Clause\",\n      \"dependencies\": {\n        \"dom-serializer\": \"^2.0.0\",\n        \"domelementtype\": \"^2.3.0\",\n        \"domhandler\": \"^5.0.3\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/fb55/domutils?sponsor=1\"\n      }\n    },\n    \"node_modules/encoding-sniffer\": {\n      \"version\": \"0.2.1\",\n      \"resolved\": \"https://registry.npmmirror.com/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz\",\n      \"integrity\": \"sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"iconv-lite\": \"^0.6.3\",\n        \"whatwg-encoding\": \"^3.1.1\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/fb55/encoding-sniffer?sponsor=1\"\n      }\n    },\n    \"node_modules/entities\": {\n      \"version\": \"4.5.0\",\n      \"resolved\": \"https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz\",\n      \"integrity\": \"sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==\",\n      \"license\": \"BSD-2-Clause\",\n      \"engines\": {\n        \"node\": \">=0.12\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/fb55/entities?sponsor=1\"\n      }\n    },\n    \"node_modules/fsevents\": {\n      \"version\": \"2.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/fsevents/-/fsevents-2.3.2.tgz\",\n      \"integrity\": \"sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==\",\n      \"hasInstallScript\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"darwin\"\n      ],\n      \"engines\": {\n        \"node\": \"^8.16.0 || ^10.6.0 || >=11.0.0\"\n      }\n    },\n    \"node_modules/htmlparser2\": {\n      \"version\": \"9.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/htmlparser2/-/htmlparser2-9.1.0.tgz\",\n      \"integrity\": \"sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==\",\n      \"funding\": [\n        \"https://github.com/fb55/htmlparser2?sponsor=1\",\n        {\n          \"type\": \"github\",\n          \"url\": \"https://github.com/sponsors/fb55\"\n        }\n      ],\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"domelementtype\": \"^2.3.0\",\n        \"domhandler\": \"^5.0.3\",\n        \"domutils\": \"^3.1.0\",\n        \"entities\": \"^4.5.0\"\n      }\n    },\n    \"node_modules/iconv-lite\": {\n      \"version\": \"0.6.3\",\n      \"resolved\": \"https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.6.3.tgz\",\n      \"integrity\": \"sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"safer-buffer\": \">= 2.1.2 < 3.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      }\n    },\n    \"node_modules/nth-check\": {\n      \"version\": \"2.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/nth-check/-/nth-check-2.1.1.tgz\",\n      \"integrity\": \"sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==\",\n      \"license\": \"BSD-2-Clause\",\n      \"dependencies\": {\n        \"boolbase\": \"^1.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/fb55/nth-check?sponsor=1\"\n      }\n    },\n    \"node_modules/parse5\": {\n      \"version\": \"7.3.0\",\n      \"resolved\": \"https://registry.npmmirror.com/parse5/-/parse5-7.3.0.tgz\",\n      \"integrity\": \"sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"entities\": \"^6.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/inikulin/parse5?sponsor=1\"\n      }\n    },\n    \"node_modules/parse5-htmlparser2-tree-adapter\": {\n      \"version\": \"7.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz\",\n      \"integrity\": \"sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"domhandler\": \"^5.0.3\",\n        \"parse5\": \"^7.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/inikulin/parse5?sponsor=1\"\n      }\n    },\n    \"node_modules/parse5-parser-stream\": {\n      \"version\": \"7.1.2\",\n      \"resolved\": \"https://registry.npmmirror.com/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz\",\n      \"integrity\": \"sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"parse5\": \"^7.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/inikulin/parse5?sponsor=1\"\n      }\n    },\n    \"node_modules/parse5/node_modules/entities\": {\n      \"version\": \"6.0.1\",\n      \"resolved\": \"https://registry.npmmirror.com/entities/-/entities-6.0.1.tgz\",\n      \"integrity\": \"sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==\",\n      \"license\": \"BSD-2-Clause\",\n      \"engines\": {\n        \"node\": \">=0.12\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/fb55/entities?sponsor=1\"\n      }\n    },\n    \"node_modules/playwright\": {\n      \"version\": \"1.52.0\",\n      \"resolved\": \"https://registry.npmmirror.com/playwright/-/playwright-1.52.0.tgz\",\n      \"integrity\": \"sha512-JAwMNMBlxJ2oD1kce4KPtMkDeKGHQstdpFPcPH3maElAXon/QZeTvtsfXmTMRyO9TslfoYOXkSsvao2nE1ilTw==\",\n      \"license\": \"Apache-2.0\",\n      \"dependencies\": {\n        \"playwright-core\": \"1.52.0\"\n      },\n      \"bin\": {\n        \"playwright\": \"cli.js\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      },\n      \"optionalDependencies\": {\n        \"fsevents\": \"2.3.2\"\n      }\n    },\n    \"node_modules/playwright-core\": {\n      \"version\": \"1.52.0\",\n      \"resolved\": \"https://registry.npmmirror.com/playwright-core/-/playwright-core-1.52.0.tgz\",\n      \"integrity\": \"sha512-l2osTgLXSMeuLZOML9qYODUQoPPnUsKsb5/P6LJ2e6uPKXUdPK5WYhN4z03G+YNbWmGDY4YENauNu4ZKczreHg==\",\n      \"license\": \"Apache-2.0\",\n      \"bin\": {\n        \"playwright-core\": \"cli.js\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/safer-buffer\": {\n      \"version\": \"2.1.2\",\n      \"resolved\": \"https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz\",\n      \"integrity\": \"sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==\",\n      \"license\": \"MIT\"\n    },\n    \"node_modules/undici\": {\n      \"version\": \"6.27.0\",\n      \"resolved\": \"https://registry.npmmirror.com/undici/-/undici-6.27.0.tgz\",\n      \"integrity\": \"sha512-YmfV3YnEDzXRC5lZ2jWtWWHKGUm1zIt8AhesR1tens+HTNv+YZlN/dp6G727LOvMJ8xjP9Be7Y2Sdr96LDm+pg==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">=18.17\"\n      }\n    },\n    \"node_modules/whatwg-encoding\": {\n      \"version\": \"3.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz\",\n      \"integrity\": \"sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==\",\n      \"deprecated\": \"Use @exodus/bytes instead for a more spec-conformant and faster implementation\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"iconv-lite\": \"0.6.3\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/whatwg-mimetype\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmmirror.com/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz\",\n      \"integrity\": \"sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    }\n  }\n}\n\nFile v29.1.0:package.json\n\n{\n  \"name\": \"free-web-search-js\",\n  \"version\": \"29.1.0\",\n  \"type\": \"module\",\n  \"description\": \"Playwright 联网搜索，国内Bing/搜狗，海外DDG，自动抓取，零 API Key\",\n  \"license\": \"MIT\",\n  \"author\": \"free-web-search-js\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/openclaw/skills\"\n  },\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"scripts\": {\n    \"search\": \"node scripts/search.js\",\n    \"fetch\": \"node scripts/fetch.js\",\n    \"check\": \"node scripts/check-env.js\",\n    \"daemon\": \"node scripts/browser-daemon.js\"\n  },\n  \"dependencies\": {\n    \"cheerio\": \"~1.0.0\",\n    \"commander\": \"~12.1.0\",\n    \"iconv-lite\": \"~0.6.3\",\n    \"playwright\": \"~1.52.0\"\n  }\n}\n\nFile v29.1.0:LICENSE\n\nMIT License\n\nCopyright (c) 2024-2026 free-web-search-js contributors\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.\n\nArchive v29.0.0: 14 files, 32434 bytes\n\nFiles: _meta.json (138b), package-lock.json (12821b), package.json (543b), README.md (5450b), scripts/browser-daemon.js (4559b), scripts/check-env.js (2558b), scripts/fetch.js (15825b), scripts/playwright-support.js (4073b), scripts/search.js (16432b), scripts/setup.ps1 (5112b), scripts/setup.sh (4540b), skill-card.md (2400b), SKILL.md (7667b), TEST_REPORT.md (2321b)\n\nFile v29.0.0:SKILL.md\n\n---\nname: free-web-search-js\ndescription: Web search & content fetching via Playwright + HTTP — zero API keys. Searches Bing CN (domestic) or DDG (international), auto-fetches top page contents. For real-time search, fact-checking, news, tutorials, documentation lookup.\nversion: 29.0.0\ntrigger_keywords:\n  - search\n  - find\n  - look up\n  - 搜索\n  - 查一下\n  - 找一下\ntools:\n  - name: search\n    description: Search + auto-fetch; Bing CN via Playwright, DDG via HTTP\n    script: scripts/search.js\n    parameters:\n      query:\n        type: string\n        description: \"Search query\"\n        required: true\n      max:\n        type: integer\n        description: \"Max results 1-30, default 10\"\n        required: false\n      region:\n        type: string\n        description: \"Region: auto/cn/intl, defaults to auto (IP detection)\"\n        required: false\n  - name: fetch\n    description: Fetch page content by URL, HTTP first with headed fallback\n    script: scripts/fetch.js\n    parameters:\n      urls:\n        type: string\n        description: \"URLs to fetch, space-separated\"\n        required: true\n      max-len:\n        type: integer\n        description: \"Max chars per page, default 12000\"\n        required: false\n---\n\n# free-web-search-js v28.1\n\nWeb search + content fetching via Playwright & HTTP. No API keys required.\n\n## Quick start\n\n```bash\n# Search (auto-fetches top 3 page contents)\nnode scripts/search.js \"silver price\"\nnode scripts/search.js \"how to deploy docker\" --max=5\nnode scripts/search.js \"xxx\" --region=cn\nnode scripts/search.js \"xxx\" --fetch=5         # fetch top 5\nnode scripts/search.js \"xxx\" --no-fetch        # search only\n\n# Fetch specific URLs\nnode scripts/fetch.js \"https://example.com/page1\" \"https://example.com/page2\"\n```\n\n## Architecture\n\n```\nDomestic (CN IP):\n  Playwright headless → Bing CN → home page for cookie → search box submit\n  → 0 results? fallback to DDG HTML\n  → auto-fetch top N page contents\n\nInternational:\n  Pure HTTP → DDG HTML parse\n  → fetch fails? fallback to Playwright request\n  → DDG empty? fallback to Bing\n  → auto-fetch top N page contents\n```\n\n## Install\n\nAll 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.\n\n### Prerequisites\n\n| Dependency | Purpose | Size |\n|---|---|---|\n| Node.js >= 18 | Runtime | — |\n| cheerio | HTML parsing | small |\n| commander | CLI arg parsing | small |\n| iconv-lite | GBK charset conversion | small |\n| playwright | Browser automation | ~50 MB |\n| Chromium (Playwright) | Browser engine for Bing search + headed fetch | ~150 MB |\n\n### One-command setup\n\n```bash\n# Linux / macOS\nbash scripts/setup.sh\n\n# Windows\npowershell -File scripts/setup.ps1\n```\n\nThe scripts auto-detect region and use `npmmirror.com` mirrors inside China for faster downloads.\n\n### Manual install\n\n```bash\ncd skills/free-web-search-js\nnpm install\nnpx playwright install chromium    # ~150 MB\n\n# Verify\nnode scripts/check-env.js\n```\n\nIf you already have Chrome/Chromium installed:\n\n```bash\nexport CHROMIUM_EXECUTABLE_PATH=\"/path/to/chrome\"\nnode scripts/check-env.js\n```\n\n`check-env.js` will confirm whether the provided executable is usable.\n\n### Environment variables\n\n| Variable | Purpose |\n|---|---|\n| `CHROMIUM_EXECUTABLE_PATH` | Path to system Chrome/Chromium, skips 150 MB download |\n| `PLAYWRIGHT_DOWNLOAD_HOST` | Mirror for Chromium download (auto-set by setup script) |\n| `BROWSER_DAEMON_IDLE_MS` | Daemon idle timeout in ms (default 600000 = 10 min) |\n\n## Search engines\n\n| Engine | Method | Region | Notes |\n|---|---|---|---|\n| Bing CN | Playwright search box submit | Domestic | Visits home page first for cookie, then types into search box |\n| Sogou | Pure HTTP | Domestic | `--engine=sogou` opt-in; no cookie, unstable under anti-crawl |\n| DDG HTML Lite | Pure HTTP | International | html.duckduckgo.com |\n\n### Strategy\n\n| Region | Search | Fetch |\n|---|---|---|\n| Domestic | Bing CN, fallback DDG | Auto-fetch top 3 |\n| International | DDG HTML, fallback Playwright request; DDG empty→Bing | Auto-fetch top 3 |\n\n### IP detection\n\nOn each search, three probes run in parallel — first responder wins:\n\n| Probe | Service | Logic |\n|---|---|---|\n| 1 | `myip.ipip.net` / `cip.cc` | Reachable from China |\n| 2 | `ipinfo.io` / `ipapi.co` | International |\n| 3 | `cn.bing.com` | Reachable → likely CN |\n| Fallback | — | Defaults to domestic |\n\nOverride with `--region=cn` or `--region=intl` if your proxy causes misdetection.\n\n## Fetch mode\n\nAfter search, auto-fetches the top N results (default 3).\n\n| Tier | Method | Speed | Notes |\n|---|---|---|---|\n| 1 | Lightweight HTTP + cheerio | Fast | No browser launch |\n| 2 | Playwright headed | Slower | Full JS rendering |\n\nTier 1 enhancements:\n- JSON API response detection with structured content extraction\n- JSON-LD (`<script type=\"application/ld+json\">`) articleBody/description\n- `__NEXT_DATA__` embedded data extraction\n- Meta tag fallback (og:description / description)\n- Auto GBK charset detection & conversion\n\n## Deduplication\n\nSmart dedup: domain + path stem (ignores www/m subdomains, tracking params, trailing slash, .html suffix). Bing redirect URLs (`bing.com/ck/`) auto-decoded.\n\n## Browser daemon (optional, ~70% faster)\n\nAvoid 1.5s+ browser launch overhead by reusing a persistent Chromium instance:\n\n```bash\nnode scripts/browser-daemon.js            # Start (run with & or as background job)\nnode scripts/browser-daemon.js --status   # Show status\nnode scripts/browser-daemon.js --stop     # Stop\n```\n\nThe 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.\n\n## Verification & troubleshooting\n\n```bash\ncd skills/free-web-search-js\nnode scripts/check-env.js\nnode scripts/search.js \"OpenClaw\" --max 2 --region cn --fetch 0\nnode scripts/search.js \"OpenClaw\" --max 2 --region intl --fetch 0\n```\n\nCommon issues:\n- `node_modules not found` → run `npm install`\n- `Executable doesn't exist ...` → run `bash scripts/setup.sh` or set `CHROMIUM_EXECUTABLE_PATH`\n- `browserType.launch ... closed` → headless+no-sandbox is default; run `node scripts/check-env.js` to diagnose\n- 0 search results → try `--region=cn` / `--region=intl`, or `--fetch 0` to test search alone\n\n## Privacy & network\n\n- Searches connect to Bing CN / DDG HTML / Sogou directly from the skill's runtime — no intermediate proxy\n- The daemon heartbeat file (`.browser-heartbeat`) and endpoint file (`.browser-endpoint`) are written to the skill root directory\n- No analytics, no telemetry, no third-party logging beyond the search engine's own server logs\n- Headed warm-up fetches: Cookie warm-up for Bing uses a headed browser context to obtain session cookies from the search engine home page; no cookies are persisted to disk between sessions\n\n## Known limitations\n\n- **First domestic search slower**: Chromium cold start takes 3–6s; daemon avoids this\n- **Bing CN instant answers**: Weather/calculator cards don't use `li.b_algo`, return 0 results\n- **Sogou HTTP unstable**: No cookie, easily blocked by anti-crawl\n- **JS-required pages**: HTTP tier returns empty for SPA pages — headed tier catches them\n- **Region-specific sites**: Some domestic sites time out from international IPs\n- **Proxy interference**: IP detection may misclassify behind proxies — use `--region` to override\n- **DDG blocked in China**: DDG HTML is not reachable from mainland China; domestic strategy avoids it\n\nFile v29.0.0:README.md\n\n# free-web-search-js\n\n## 项目简介\n\nfree-web-search-js 是一个基于 Playwright和JS写 的免费网络搜索skill 可用于CC或者openclaw（clawhub install free-web-search-js），无需 API Key，支持国内和海外搜索，自动抓取搜索结果内容。\n\n- **免费**：零成本使用，无需 API Key\n- **稳定**：根据网络环境自动切换搜索策略，提高可达性\n- **快速**：首次搜索 3\\~6 秒，后续复用浏览器更快\n- **自动抓取**：搜索后自动抓取 top N 条结果内容\n- **跨区域**：国内使用 Bing/搜狗，海外使用 DDG\n\n## 支持的搜索引擎\n\n| 引擎       | 协议               | 区域 | 说明                                          |\n| -------- | ---------------- | -- | ------------------------------------------- |\n| Bing CN  | Playwright 搜索框提交 | 国内 | 先访问首页拿 cookie，再搜索框输入提交                      |\n| 搜狗       | 纯 HTTP           | 国内 | `--engine=sogou` 可选，无 cookie，结果不稳定 |\n| DDG HTML | 纯 HTTP           | 海外 | html.duckduckgo.com                         |\n\n## 安装\n\n### 前置依赖\n\n| 依赖            | 说明                     | 大小/耗时              |\n| ------------- | ---------------------- | ------------------ |\n| Node.js >= 18 | 运行时                    | —                  |\n| cheerio       | HTML 解析                | 小，秒装               |\n| commander     | CLI 参数解析               | 小，秒装               |\n| iconv-lite    | GBK 编码转换               | 小，秒装               |\n| playwright    | 浏览器自动化（Bing 搜索 + 抓取兜底） | \\~50MB             |\n| Chromium      | Playwright 专用浏览器       | **\\~150MB，需几分钟下载** |\n\n### 安装步骤\n\n#### 一键安装\n\n```bash\n# Linux/macOS\nbash scripts/setup.sh\n\n# Windows\n# 目前仅提供 Linux/macOS 一键安装脚本\n# Windows 用户请使用手动安装方式\n```\n\n#### 手动安装\n\n```bash\n# 进入项目目录\ncd free-web-search-js\n\n# 安装依赖\nnpm install\n\n# 安装 Playwright 浏览器\nnpx playwright install chromium    # ~150MB，需几分钟\n```\n\n### 国内镜像加速\n\n```bash\n# npm 镜像\nnpm install --registry=https://registry.npmmirror.com\n\n# Playwright/Chromium 镜像\nPLAYWRIGHT_DOWNLOAD_HOST=https://npmmirror.com/mirrors/playwright npx playwright install chromium\n```\n\n### 验证环境\n\n```bash\nnode scripts/check-env.js\n```\n\n### 卸载\n\n```bash\nnode scripts/uninstall.js\n```\n\n## 用法\n\n### 搜索（搜 + 自动抓内容）\n\n```bash\n# 基本搜索\nnode scripts/search.js \"白银价格\"\n\n# 控制结果数量\nnode scripts/search.js \"how to deploy docker\" --max=5\n\n# 指定区域\nnode scripts/search.js \"xxx\" --region=cn\n\n# 指定搜索引擎\nnode scripts/search.js \"xxx\" --engine=bing\n\n# 控制抓取数量\nnode scripts/search.js \"xxx\" --fetch=5          # 抓前5条\n\n# 只搜索不抓取\nnode scripts/search.js \"xxx\" --no-fetch\n\n# 控制单页最大字符数\nnode scripts/search.js \"xxx\" --max-len=8000\n```\n\n### 单独抓取（给定 URL）\n\n```bash\nnode scripts/fetch.js \"https://example.com/page1\" \"https://example.com/page2\"\n```\n\n## 性能优化：浏览器守护进程\n\n搜索和抓取可复用浏览器守护进程，**提速约 70%**：\n\n```bash\nnode scripts/browser-daemon.js &       # 启动\nnode scripts/browser-daemon.js --status # 状态\nnode scripts/browser-daemon.js --stop   # 停止\n```\n\n守护进程空闲 10 分钟自动退出。\n\n## 架构\n\n### 国内搜索流程\n\n```\nPlaywright 打开 Bing → 首页拿 cookie → 搜索框提交 → 自动抓取 top N 页面内容\n延迟：首次 3~6s（启动浏览器），后续复用更快\n```\n\n### 海外搜索流程\n\n```\n纯 HTTP → DDG HTML 解析 → 自动抓取 top N 页面内容\n延迟：几百ms~1s\n```\n\n### 抓取模式\n\n| 层级  | 方式                | 速度   | 说明             |\n| --- | ----------------- | ---- | -------------- |\n| 第1层 | 轻量 HTTP + cheerio | ⚡ 秒出 | 不启动浏览器         |\n| 第2层 | Playwright headed | 🟡 慢 | 完整浏览器，支持 JS 渲染 |\n\n## 区域检测\n\n每次搜索时自动检测，三轮探测并行，谁先成功用谁：\n\n| 轮次  | 探测服务                       | 逻辑      |\n| --- | -------------------------- | ------- |\n| 第1轮 | `myip.ipip.net` / `cip.cc` | 国内可达优先  |\n| 第2轮 | `ipinfo.io` / `ipapi.co`   | 国际探测    |\n| 第3轮 | 试连 `cn.bing.com`           | 能通大概率国内 |\n| 兜底  | —                          | 默认国内    |\n\n## 去重\n\n智能去重：域名 + 路径主干（忽略 www/m 子域、tracking 参数、尾部斜杠、.html 后缀）。\n\nBing 跳转 URL（`bing.com/ck/`）自动解码为直链。\n\n## 已知限制\n\n- **国内首次搜索较慢**：需启动 Chromium（3\\~6s），后续复用更快\n- **Bing CN 即时答案不返回**：天气、计算器等即时卡片不走 `li.b_algo`，搜索结果为 0\n- **搜狗 HTTP 不稳定**：无 cookie 纯请求结果可能为空（`--engine=sogou` 慎用）\n- **部分站点 HTTP 抓不到**：需要 JS 渲染的页面——HTTP 失败会自动 headed 重试\n- **部分站点海外不可达**：国内专属站点从海外访问可能超时\n- **代理干扰 IP 检测**：出口 IP 走代理时可能误判区域，用 `--region=cn/intl` 手动指定\n- **海外引擎国内不可达**：DDG 在国内被墙，国内策略不使用\n\n## 许可证\n\nMIT License\n\nFile v29.0.0:_meta.json\n\n{\n  \"ownerId\": \"kn7ecgbzbya89gesghbv1kty9d82r8e4\",\n  \"slug\": \"free-web-search-js\",\n  \"version\": \"29.0.0\",\n  \"publishedAt\": 1781714768825\n}\n\nFile v29.0.0:skill-card.md\n\n## Description: <br>\nFree Web Search Js searches the web and fetches page content through Playwright and HTTP without requiring API keys. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[ucsdzehualiu](https://clawhub.ai/user/ucsdzehualiu) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nDevelopers and agents use this skill to run real-time web searches, fetch result pages, and gather web content for fact-checking, news lookup, tutorials, and documentation research. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: Search terms, fetched URLs, IP address, and browser/request metadata may be visible to search engines, IP lookup services, and destination websites. <br>\nMitigation: Avoid confidential prompts, secrets, internal URLs, and private business data; use explicit region settings for sensitive work. <br>\nRisk: Auto-fetching search results sends requests to destination websites that the user did not manually inspect first. <br>\nMitigation: Disable auto-fetch or reduce the fetch count when researching sensitive topics or untrusted result sets. <br>\nRisk: Automatic region detection can contact external IP lookup services and may misclassify networks behind proxies. <br>\nMitigation: Set the region explicitly when proxy routing, geography, or data exposure matters. <br>\n\n\n## Reference(s): <br>\n- [ClawHub skill page](https://clawhub.ai/ucsdzehualiu/free-web-search-js) <br>\n- [SKILL.md](artifact/SKILL.md) <br>\n- [README.md](artifact/README.md) <br>\n- [TEST_REPORT.md](artifact/TEST_REPORT.md) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [text, markdown] <br>\n**Output Format:** [Markdown-like CLI text with result titles, URLs, snippets, and fetched page excerpts.] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [Search supports query, result count, region, fetch count, and page length controls; fetch accepts one or more URLs and a page length limit.] <br>\n\n## Skill Version(s): <br>\n29.0.0 (source: server release, SKILL.md frontmatter, package.json) <br>\n\n## Ethical Considerations: <br>\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. <br>\n\nFile v29.0.0:TEST_REPORT.md\n\n# free-web-search-js v24.0 测试报告\n\n日期: 2026-04-24\n\n## 搜索测试\n\n| 查询 | 引擎 | 结果数 | 质量 | 问题 |\n|------|------|--------|------|------|\n| 今日金价 | Bing CN + 百度 | 15→5 | ⚠️ 中 | 混了百度经验教程，AI需自行筛选 |\n| docker compose deploy production | Bing CN + 百度 | 13→5 | ⚠️ 差 | 全是Docker官网首页/下载页，没compose生产部署内容 |\n| 俄乌冲突 2026年4月 | Bing CN + 百度 | 13→5 | ✅ 好 | 知乎讨论+snippet，1条噪音（俄的来源） |\n| python asyncio tutorial | Bing CN + 百度 | 15→5 | ❌ 差 | 全是Python泛文，asyncio完全没命中 |\n| 新能源汽车补贴政策 2026 | Bing CN + 百度 | 14→5 | ✅ 很好 | 搜狐/知乎/新浪/光明网/发改委，全精准 |\n| openclaw AI assistant setup | Bing CN + 百度 | 15→5 | ✅ 好 | 官网/中文站/腾讯云/知乎全命中 |\n| 霍尔木兹海峡 今日 | Bing CN + 百度 | 15→5 | ⚠️ 中 | 混了\"霍尔效应\"噪音，AI需自行筛 |\n\n## Fetch测试\n\n| URL | 模式 | 结果 | 问题 |\n|-----|------|------|------|\n| quote.cngold.org (金投网) | http-only | ⚠️ 结构拿到，价格全---- | JS动态加载，HTTP拿不到实时价格 |\n| docs.docker.com | http-only | ❌ fetch failed | 国内不通 |\n| docs.docker.com | headed | ✅ 完整内容 | Playwright兜底有效 |\n| economy.gmw.cn (光明网) | http-only | ⚠️ 拿到侧边栏不是正文 | 正文选择器没命中 |\n\n## 核心发现\n\n1. **中文query效果好** — Bing CN + 百度对中文新闻/政策/时事类query效果很好\n2. **英文query效果差** — Bing CN把英文技术词按中文分词切碎，返回泛泛结果\n3. **海外引擎国内全挂** — DDG/Brave/秘迹从国内全部timeout/fetch failed\n4. **JS动态内容HTTP拿不到** — 金投网等价格页面需要headed模式\n5. **知乎403** — HTTP直接抓知乎被拒，需headed\n6. **百度跳转URL解析** — 大部分能解析为直链，少数失败\n7. **删掉改写/过滤后** — skill更纯粹，噪音交给AI处理，符合设计原则\n\n## 待改进（不过度优化）\n\n- 英文query可尝试给Bing CN加 `&setlang=en-US` 参数，可能改善英文结果质量\n- fetch正文提取对部分站点命中率不够，但这是泛用难题，不宜针对特定站硬编码\n\nFile v29.0.0:package-lock.json\n\n{\n  \"name\": \"free-web-search-js\",\n  \"version\": \"28.1.0\",\n  \"lockfileVersion\": 3,\n  \"requires\": true,\n  \"packages\": {\n    \"\": {\n      \"name\": \"free-web-search-js\",\n      \"version\": \"28.1.0\",\n      \"dependencies\": {\n        \"cheerio\": \"~1.0.0\",\n        \"commander\": \"~12.1.0\",\n        \"iconv-lite\": \"~0.6.3\",\n        \"playwright\": \"~1.52.0\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/boolbase\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmmirror.com/boolbase/-/boolbase-1.0.0.tgz\",\n      \"integrity\": \"sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==\",\n      \"license\": \"ISC\"\n    },\n    \"node_modules/cheerio\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmmirror.com/cheerio/-/cheerio-1.0.0.tgz\",\n      \"integrity\": \"sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"cheerio-select\": \"^2.1.0\",\n        \"dom-serializer\": \"^2.0.0\",\n        \"domhandler\": \"^5.0.3\",\n        \"domutils\": \"^3.1.0\",\n        \"encoding-sniffer\": \"^0.2.0\",\n        \"htmlparser2\": \"^9.1.0\",\n        \"parse5\": \"^7.1.2\",\n        \"parse5-htmlparser2-tree-adapter\": \"^7.0.0\",\n        \"parse5-parser-stream\": \"^7.1.2\",\n        \"undici\": \"^6.19.5\",\n        \"whatwg-mimetype\": \"^4.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=18.17\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/cheeriojs/cheerio?sponsor=1\"\n      }\n    },\n    \"node_modules/cheerio-select\": {\n      \"version\": \"2.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/cheerio-select/-/cheerio-select-2.1.0.tgz\",\n      \"integrity\": \"sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==\",\n      \"license\": \"BSD-2-Clause\",\n      \"dependencies\": {\n        \"boolbase\": \"^1.0.0\",\n        \"css-select\": \"^5.1.0\",\n        \"css-what\": \"^6.1.0\",\n        \"domelementtype\": \"^2.3.0\",\n        \"domhandler\": \"^5.0.3\",\n        \"domutils\": \"^3.0.1\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/fb55\"\n      }\n    },\n    \"node_modules/commander\": {\n      \"version\": \"12.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/commander/-/commander-12.1.0.tgz\",\n      \"integrity\": \"sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/css-select\": {\n      \"version\": \"5.2.2\",\n      \"resolved\": \"https://registry.npmmirror.com/css-select/-/css-select-5.2.2.tgz\",\n      \"integrity\": \"sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==\",\n      \"license\": \"BSD-2-Clause\",\n      \"dependencies\": {\n        \"boolbase\": \"^1.0.0\",\n        \"css-what\": \"^6.1.0\",\n        \"domhandler\": \"^5.0.2\",\n        \"domutils\": \"^3.0.1\",\n        \"nth-check\": \"^2.0.1\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/fb55\"\n      }\n    },\n    \"node_modules/css-what\": {\n      \"version\": \"6.2.2\",\n      \"resolved\": \"https://registry.npmmirror.com/css-what/-/css-what-6.2.2.tgz\",\n      \"integrity\": \"sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==\",\n      \"license\": \"BSD-2-Clause\",\n      \"engines\": {\n        \"node\": \">= 6\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/fb55\"\n      }\n    },\n    \"node_modules/dom-serializer\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmmirror.com/dom-serializer/-/dom-serializer-2.0.0.tgz\",\n      \"integrity\": \"sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"domelementtype\": \"^2.3.0\",\n        \"domhandler\": \"^5.0.2\",\n        \"entities\": \"^4.2.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/cheeriojs/dom-serializer?sponsor=1\"\n      }\n    },\n    \"node_modules/domelementtype\": {\n      \"version\": \"2.3.0\",\n      \"resolved\": \"https://registry.npmmirror.com/domelementtype/-/domelementtype-2.3.0.tgz\",\n      \"integrity\": \"sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==\",\n      \"funding\": [\n        {\n          \"type\": \"github\",\n          \"url\": \"https://github.com/sponsors/fb55\"\n        }\n      ],\n      \"license\": \"BSD-2-Clause\"\n    },\n    \"node_modules/domhandler\": {\n      \"version\": \"5.0.3\",\n      \"resolved\": \"https://registry.npmmirror.com/domhandler/-/domhandler-5.0.3.tgz\",\n      \"integrity\": \"sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==\",\n      \"license\": \"BSD-2-Clause\",\n      \"dependencies\": {\n        \"domelementtype\": \"^2.3.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/fb55/domhandler?sponsor=1\"\n      }\n    },\n    \"node_modules/domutils\": {\n      \"version\": \"3.2.2\",\n      \"resolved\": \"https://registry.npmmirror.com/domutils/-/domutils-3.2.2.tgz\",\n      \"integrity\": \"sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==\",\n      \"license\": \"BSD-2-Clause\",\n      \"dependencies\": {\n        \"dom-serializer\": \"^2.0.0\",\n        \"domelementtype\": \"^2.3.0\",\n        \"domhandler\": \"^5.0.3\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/fb55/domutils?sponsor=1\"\n      }\n    },\n    \"node_modules/encoding-sniffer\": {\n      \"version\": \"0.2.1\",\n      \"resolved\": \"https://registry.npmmirror.com/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz\",\n      \"integrity\": \"sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"iconv-lite\": \"^0.6.3\",\n        \"whatwg-encoding\": \"^3.1.1\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/fb55/encoding-sniffer?sponsor=1\"\n      }\n    },\n    \"node_modules/entities\": {\n      \"version\": \"4.5.0\",\n      \"resolved\": \"https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz\",\n      \"integrity\": \"sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==\",\n      \"license\": \"BSD-2-Clause\",\n      \"engines\": {\n        \"node\": \">=0.12\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/fb55/entities?sponsor=1\"\n      }\n    },\n    \"node_modules/fsevents\": {\n      \"version\": \"2.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/fsevents/-/fsevents-2.3.2.tgz\",\n      \"integrity\": \"sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==\",\n      \"hasInstallScript\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"darwin\"\n      ],\n      \"engines\": {\n        \"node\": \"^8.16.0 || ^10.6.0 || >=11.0.0\"\n      }\n    },\n    \"node_modules/htmlparser2\": {\n      \"version\": \"9.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/htmlparser2/-/htmlparser2-9.1.0.tgz\",\n      \"integrity\": \"sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==\",\n      \"funding\": [\n        \"https://github.com/fb55/htmlparser2?sponsor=1\",\n        {\n          \"type\": \"github\",\n          \"url\": \"https://github.com/sponsors/fb55\"\n        }\n      ],\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"domelementtype\": \"^2.3.0\",\n        \"domhandler\": \"^5.0.3\",\n        \"domutils\": \"^3.1.0\",\n        \"entities\": \"^4.5.0\"\n      }\n    },\n    \"node_modules/iconv-lite\": {\n      \"version\": \"0.6.3\",\n      \"resolved\": \"https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.6.3.tgz\",\n      \"integrity\": \"sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"safer-buffer\": \">= 2.1.2 < 3.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      }\n    },\n    \"node_modules/nth-check\": {\n      \"version\": \"2.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/nth-check/-/nth-check-2.1.1.tgz\",\n      \"integrity\": \"sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==\",\n      \"license\": \"BSD-2-Clause\",\n      \"dependencies\": {\n        \"boolbase\": \"^1.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/fb55/nth-check?sponsor=1\"\n      }\n    },\n    \"node_modules/parse5\": {\n      \"version\": \"7.3.0\",\n      \"resolved\": \"https://registry.npmmirror.com/parse5/-/parse5-7.3.0.tgz\",\n      \"integrity\": \"sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"entities\": \"^6.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/inikulin/parse5?sponsor=1\"\n      }\n    },\n    \"node_modules/parse5-htmlparser2-tree-adapter\": {\n      \"version\": \"7.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz\",\n      \"integrity\": \"sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"domhandler\": \"^5.0.3\",\n        \"parse5\": \"^7.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/inikulin/parse5?sponsor=1\"\n      }\n    },\n    \"node_modules/parse5-parser-stream\": {\n      \"version\": \"7.1.2\",\n      \"resolved\": \"https://registry.npmmirror.com/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz\",\n      \"integrity\": \"sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"parse5\": \"^7.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/inikulin/parse5?sponsor=1\"\n      }\n    },\n    \"node_modules/parse5/node_modules/entities\": {\n      \"version\": \"6.0.1\",\n      \"resolved\": \"https://registry.npmmirror.com/entities/-/entities-6.0.1.tgz\",\n      \"integrity\": \"sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==\",\n      \"license\": \"BSD-2-Clause\",\n      \"engines\": {\n        \"node\": \">=0.12\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/fb55/entities?sponsor=1\"\n      }\n    },\n    \"node_modules/playwright\": {\n      \"version\": \"1.52.0\",\n      \"resolved\": \"https://registry.npmmirror.com/playwright/-/playwright-1.52.0.tgz\",\n      \"integrity\": \"sha512-JAwMNMBlxJ2oD1kce4KPtMkDeKGHQstdpFPcPH3maElAXon/QZeTvtsfXmTMRyO9TslfoYOXkSsvao2nE1ilTw==\",\n      \"license\": \"Apache-2.0\",\n      \"dependencies\": {\n        \"playwright-core\": \"1.52.0\"\n      },\n      \"bin\": {\n        \"playwright\": \"cli.js\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      },\n      \"optionalDependencies\": {\n        \"fsevents\": \"2.3.2\"\n      }\n    },\n    \"node_modules/playwright-core\": {\n      \"version\": \"1.52.0\",\n      \"resolved\": \"https://registry.npmmirror.com/playwright-core/-/playwright-core-1.52.0.tgz\",\n      \"integrity\": \"sha512-l2osTgLXSMeuLZOML9qYODUQoPPnUsKsb5/P6LJ2e6uPKXUdPK5WYhN4z03G+YNbWmGDY4YENauNu4ZKczreHg==\",\n      \"license\": \"Apache-2.0\",\n      \"bin\": {\n        \"playwright-core\": \"cli.js\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/safer-buffer\": {\n      \"version\": \"2.1.2\",\n      \"resolved\": \"https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz\",\n      \"integrity\": \"sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==\",\n      \"license\": \"MIT\"\n    },\n    \"node_modules/undici\": {\n      \"version\": \"6.27.0\",\n      \"resolved\": \"https://registry.npmmirror.com/undici/-/undici-6.27.0.tgz\",\n      \"integrity\": \"sha512-YmfV3YnEDzXRC5lZ2jWtWWHKGUm1zIt8AhesR1tens+HTNv+YZlN/dp6G727LOvMJ8xjP9Be7Y2Sdr96LDm+pg==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">=18.17\"\n      }\n    },\n    \"node_modules/whatwg-encoding\": {\n      \"version\": \"3.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz\",\n      \"integrity\": \"sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==\",\n      \"deprecated\": \"Use @exodus/bytes instead for a more spec-conformant and faster implementation\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"iconv-lite\": \"0.6.3\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/whatwg-mimetype\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmmirror.com/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz\",\n      \"integrity\": \"sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    }\n  }\n}\n\nFile v29.0.0:package.json\n\n{\n  \"name\": \"free-web-search-js\",\n  \"version\": \"29.0.0\",\n  \"type\": \"module\",\n  \"description\": \"Playwright 联网搜索，国内Bing/搜狗，海外DDG，自动抓取，零 API Key\",\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"scripts\": {\n    \"search\": \"node scripts/search.js\",\n    \"fetch\": \"node scripts/fetch.js\",\n    \"check\": \"node scripts/check-env.js\",\n    \"daemon\": \"node scripts/browser-daemon.js\"\n  },\n  \"dependencies\": {\n    \"cheerio\": \"~1.0.0\",\n    \"commander\": \"~12.1.0\",\n    \"iconv-lite\": \"~0.6.3\",\n    \"playwright\": \"~1.52.0\"\n  }\n}\n\nArchive v28.1.1: 14 files, 33497 bytes\n\nFiles: _meta.json (138b), package-lock.json (12821b), package.json (543b), README.md (5450b), scripts/browser-daemon.js (4559b), scripts/check-env.js (2558b), scripts/fetch.js (15542b), scripts/playwright-support.js (4073b), scripts/search.js (20043b), scripts/setup.ps1 (5112b), scripts/setup.sh (4540b), skill-card.md (2555b), SKILL.md (7667b), TEST_REPORT.md (2321b)\n\nFile v28.1.1:SKILL.md\n\n---\nname: free-web-search-js\ndescription: Web search & content fetching via Playwright + HTTP — zero API keys. Searches Bing CN (domestic) or DDG (international), auto-fetches top page contents. For real-time search, fact-checking, news, tutorials, documentation lookup.\nversion: 28.1.1\ntrigger_keywords:\n  - search\n  - find\n  - look up\n  - 搜索\n  - 查一下\n  - 找一下\ntools:\n  - name: search\n    description: Search + auto-fetch; Bing CN via Playwright, DDG via HTTP\n    script: scripts/search.js\n    parameters:\n      query:\n        type: string\n        description: \"Search query\"\n        required: true\n      max:\n        type: integer\n        description: \"Max results 1-30, default 10\"\n        required: false\n      region:\n        type: string\n        description: \"Region: auto/cn/intl, defaults to auto (IP detection)\"\n        required: false\n  - name: fetch\n    description: Fetch page content by URL, HTTP first with headed fallback\n    script: scripts/fetch.js\n    parameters:\n      urls:\n        type: string\n        description: \"URLs to fetch, space-separated\"\n        required: true\n      max-len:\n        type: integer\n        description: \"Max chars per page, default 12000\"\n        required: false\n---\n\n# free-web-search-js v28.1\n\nWeb search + content fetching via Playwright & HTTP. No API keys required.\n\n## Quick start\n\n```bash\n# Search (auto-fetches top 3 page contents)\nnode scripts/search.js \"silver price\"\nnode scripts/search.js \"how to deploy docker\" --max=5\nnode scripts/search.js \"xxx\" --region=cn\nnode scripts/search.js \"xxx\" --fetch=5         # fetch top 5\nnode scripts/search.js \"xxx\" --no-fetch        # search only\n\n# Fetch specific URLs\nnode scripts/fetch.js \"https://example.com/page1\" \"https://example.com/page2\"\n```\n\n## Architecture\n\n```\nDomestic (CN IP):\n  Playwright headless → Bing CN → home page for cookie → search box submit\n  → 0 results? fallback to DDG HTML\n  → auto-fetch top N page contents\n\nInternational:\n  Pure HTTP → DDG HTML parse\n  → fetch fails? fallback to Playwright request\n  → DDG empty? fallback to Bing\n  → auto-fetch top N page contents\n```\n\n## Install\n\nAll 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.\n\n### Prerequisites\n\n| Dependency | Purpose | Size |\n|---|---|---|\n| Node.js >= 18 | Runtime | — |\n| cheerio | HTML parsing | small |\n| commander | CLI arg parsing | small |\n| iconv-lite | GBK charset conversion | small |\n| playwright | Browser automation | ~50 MB |\n| Chromium (Playwright) | Browser engine for Bing search + headed fetch | ~150 MB |\n\n### One-command setup\n\n```bash\n# Linux / macOS\nbash scripts/setup.sh\n\n# Windows\npowershell -File scripts/setup.ps1\n```\n\nThe scripts auto-detect region and use `npmmirror.com` mirrors inside China for faster downloads.\n\n### Manual install\n\n```bash\ncd skills/free-web-search-js\nnpm install\nnpx playwright install chromium    # ~150 MB\n\n# Verify\nnode scripts/check-env.js\n```\n\nIf you already have Chrome/Chromium installed:\n\n```bash\nexport CHROMIUM_EXECUTABLE_PATH=\"/path/to/chrome\"\nnode scripts/check-env.js\n```\n\n`check-env.js` will confirm whether the provided executable is usable.\n\n### Environment variables\n\n| Variable | Purpose |\n|---|---|\n| `CHROMIUM_EXECUTABLE_PATH` | Path to system Chrome/Chromium, skips 150 MB download |\n| `PLAYWRIGHT_DOWNLOAD_HOST` | Mirror for Chromium download (auto-set by setup script) |\n| `BROWSER_DAEMON_IDLE_MS` | Daemon idle timeout in ms (default 600000 = 10 min) |\n\n## Search engines\n\n| Engine | Method | Region | Notes |\n|---|---|---|---|\n| Bing CN | Playwright search box submit | Domestic | Visits home page first for cookie, then types into search box |\n| Sogou | Pure HTTP | Domestic | `--engine=sogou` opt-in; no cookie, unstable under anti-crawl |\n| DDG HTML Lite | Pure HTTP | International | html.duckduckgo.com |\n\n### Strategy\n\n| Region | Search | Fetch |\n|---|---|---|\n| Domestic | Bing CN, fallback DDG | Auto-fetch top 3 |\n| International | DDG HTML, fallback Playwright request; DDG empty→Bing | Auto-fetch top 3 |\n\n### IP detection\n\nOn each search, three probes run in parallel — first responder wins:\n\n| Probe | Service | Logic |\n|---|---|---|\n| 1 | `myip.ipip.net` / `cip.cc` | Reachable from China |\n| 2 | `ipinfo.io` / `ipapi.co` | International |\n| 3 | `cn.bing.com` | Reachable → likely CN |\n| Fallback | — | Defaults to domestic |\n\nOverride with `--region=cn` or `--region=intl` if your proxy causes misdetection.\n\n## Fetch mode\n\nAfter search, auto-fetches the top N results (default 3).\n\n| Tier | Method | Speed | Notes |\n|---|---|---|---|\n| 1 | Lightweight HTTP + cheerio | Fast | No browser launch |\n| 2 | Playwright headed | Slower | Full JS rendering |\n\nTier 1 enhancements:\n- JSON API response detection with structured content extraction\n- JSON-LD (`<script type=\"application/ld+json\">`) articleBody/description\n- `__NEXT_DATA__` embedded data extraction\n- Meta tag fallback (og:description / description)\n- Auto GBK charset detection & conversion\n\n## Deduplication\n\nSmart dedup: domain + path stem (ignores www/m subdomains, tracking params, trailing slash, .html suffix). Bing redirect URLs (`bing.com/ck/`) auto-decoded.\n\n## Browser daemon (optional, ~70% faster)\n\nAvoid 1.5s+ browser launch overhead by reusing a persistent Chromium instance:\n\n```bash\nnode scripts/browser-daemon.js            # Start (run with & or as background job)\nnode scripts/browser-daemon.js --status   # Show status\nnode scripts/browser-daemon.js --stop     # Stop\n```\n\nThe 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.\n\n## Verification & troubleshooting\n\n```bash\ncd skills/free-web-search-js\nnode scripts/check-env.js\nnode scripts/search.js \"OpenClaw\" --max 2 --region cn --fetch 0\nnode scripts/search.js \"OpenClaw\" --max 2 --region intl --fetch 0\n```\n\nCommon issues:\n- `node_modules not found` → run `npm install`\n- `Executable doesn't exist ...` → run `bash scripts/setup.sh` or set `CHROMIUM_EXECUTABLE_PATH`\n- `browserType.launch ... closed` → headless+no-sandbox is default; run `node scripts/check-env.js` to diagnose\n- 0 search results → try `--region=cn` / `--region=intl`, or `--fetch 0` to test search alone\n\n## Privacy & network\n\n- Searches connect to Bing CN / DDG HTML / Sogou directly from the skill's runtime — no intermediate proxy\n- The daemon heartbeat file (`.browser-heartbeat`) and endpoint file (`.browser-endpoint`) are written to the skill root directory\n- No analytics, no telemetry, no third-party logging beyond the search engine's own server logs\n- Headed warm-up fetches: Cookie warm-up for Bing uses a headed browser context to obtain session cookies from the search engine home page; no cookies are persisted to disk between sessions\n\n## Known limitations\n\n- **First domestic search slower**: Chromium cold start takes 3–6s; daemon avoids this\n- **Bing CN instant answers**: Weather/calculator cards don't use `li.b_algo`, return 0 results\n- **Sogou HTTP unstable**: No cookie, easily blocked by anti-crawl\n- **JS-required pages**: HTTP tier returns empty for SPA pages — headed tier catches them\n- **Region-specific sites**: Some domestic sites time out from international IPs\n- **Proxy interference**: IP detection may misclassify behind proxies — use `--region` to override\n- **DDG blocked in China**: DDG HTML is not reachable from mainland China; domestic strategy avoids it\n\nFile v28.1.1:README.md\n\n# free-web-search-js\n\n## 项目简介\n\nfree-web-search-js 是一个基于 Playwright和JS写 的免费网络搜索skill 可用于CC或者openclaw（clawhub install free-web-search-js），无需 API Key，支持国内和海外搜索，自动抓取搜索结果内容。\n\n- **免费**：零成本使用，无需 API Key\n- **稳定**：根据网络环境自动切换搜索策略，提高可达性\n- **快速**：首次搜索 3\\~6 秒，后续复用浏览器更快\n- **自动抓取**：搜索后自动抓取 top N 条结果内容\n- **跨区域**：国内使用 Bing/搜狗，海外使用 DDG\n\n## 支持的搜索引擎\n\n| 引擎       | 协议               | 区域 | 说明                                          |\n| -------- | ---------------- | -- | ------------------------------------------- |\n| Bing CN  | Playwright 搜索框提交 | 国内 | 先访问首页拿 cookie，再搜索框输入提交                      |\n| 搜狗       | 纯 HTTP           | 国内 | `--engine=sogou` 可选，无 cookie，结果不稳定 |\n| DDG HTML | 纯 HTTP           | 海外 | html.duckduckgo.com                         |\n\n## 安装\n\n### 前置依赖\n\n| 依赖            | 说明                     | 大小/耗时              |\n| ------------- | ---------------------- | ------------------ |\n| Node.js >= 18 | 运行时                    | —                  |\n| cheerio       | HTML 解析                | 小，秒装               |\n| commander     | CLI 参数解析               | 小，秒装               |\n| iconv-lite    | GBK 编码转换               | 小，秒装               |\n| playwright    | 浏览器自动化（Bing 搜索 + 抓取兜底） | \\~50MB             |\n| Chromium      | Playwright 专用浏览器       | **\\~150MB，需几分钟下载** |\n\n### 安装步骤\n\n#### 一键安装\n\n```bash\n# Linux/macOS\nbash scripts/setup.sh\n\n# Windows\n# 目前仅提供 Linux/macOS 一键安装脚本\n# Windows 用户请使用手动安装方式\n```\n\n#### 手动安装\n\n```bash\n# 进入项目目录\ncd free-web-search-js\n\n# 安装依赖\nnpm install\n\n# 安装 Playwright 浏览器\nnpx playwright install chromium    # ~150MB，需几分钟\n```\n\n### 国内镜像加速\n\n```bash\n# npm 镜像\nnpm install --registry=https://registry.npmmirror.com\n\n# Playwright/Chromium 镜像\nPLAYWRIGHT_DOWNLOAD_HOST=https://npmmirror.com/mirrors/playwright npx playwright install chromium\n```\n\n### 验证环境\n\n```bash\nnode scripts/check-env.js\n```\n\n### 卸载\n\n```bash\nnode scripts/uninstall.js\n```\n\n## 用法\n\n### 搜索（搜 + 自动抓内容）\n\n```bash\n# 基本搜索\nnode scripts/search.js \"白银价格\"\n\n# 控制结果数量\nnode scripts/search.js \"how to deploy docker\" --max=5\n\n# 指定区域\nnode scripts/search.js \"xxx\" --region=cn\n\n# 指定搜索引擎\nnode scripts/search.js \"xxx\" --engine=bing\n\n# 控制抓取数量\nnode scripts/search.js \"xxx\" --fetch=5          # 抓前5条\n\n# 只搜索不抓取\nnode scripts/search.js \"xxx\" --no-fetch\n\n# 控制单页最大字符数\nnode scripts/search.js \"xxx\" --max-len=8000\n```\n\n### 单独抓取（给定 URL）\n\n```bash\nnode scripts/fetch.js \"https://example.com/page1\" \"https://example.com/page2\"\n```\n\n## 性能优化：浏览器守护进程\n\n搜索和抓取可复用浏览器守护进程，**提速约 70%**：\n\n```bash\nnode scripts/browser-daemon.js &       # 启动\nnode scripts/browser-daemon.js --status # 状态\nnode scripts/browser-daemon.js --stop   # 停止\n```\n\n守护进程空闲 10 分钟自动退出。\n\n## 架构\n\n### 国内搜索流程\n\n```\nPlaywright 打开 Bing → 首页拿 cookie → 搜索框提交 → 自动抓取 top N 页面内容\n延迟：首次 3~6s（启动浏览器），后续复用更快\n```\n\n### 海外搜索流程\n\n```\n纯 HTTP → DDG HTML 解析 → 自动抓取 top N 页面内容\n延迟：几百ms~1s\n```\n\n### 抓取模式\n\n| 层级  | 方式                | 速度   | 说明             |\n| --- | ----------------- | ---- | -------------- |\n| 第1层 | 轻量 HTTP + cheerio | ⚡ 秒出 | 不启动浏览器         |\n| 第2层 | Playwright headed | 🟡 慢 | 完整浏览器，支持 JS 渲染 |\n\n## 区域检测\n\n每次搜索时自动检测，三轮探测并行，谁先成功用谁：\n\n| 轮次  | 探测服务                       | 逻辑      |\n| --- | -------------------------- | ------- |\n| 第1轮 | `myip.ipip.net` / `cip.cc` | 国内可达优先  |\n| 第2轮 | `ipinfo.io` / `ipapi.co`   | 国际探测    |\n| 第3轮 | 试连 `cn.bing.com`           | 能通大概率国内 |\n| 兜底  | —                          | 默认国内    |\n\n## 去重\n\n智能去重：域名 + 路径主干（忽略 www/m 子域、tracking 参数、尾部斜杠、.html 后缀）。\n\nBing 跳转 URL（`bing.com/ck/`）自动解码为直链。\n\n## 已知限制\n\n- **国内首次搜索较慢**：需启动 Chromium（3\\~6s），后续复用更快\n- **Bing CN 即时答案不返回**：天气、计算器等即时卡片不走 `li.b_algo`，搜索结果为 0\n- **搜狗 HTTP 不稳定**：无 cookie 纯请求结果可能为空（`--engine=sogou` 慎用）\n- **部分站点 HTTP 抓不到**：需要 JS 渲染的页面——HTTP 失败会自动 headed 重试\n- **部分站点海外不可达**：国内专属站点从海外访问可能超时\n- **代理干扰 IP 检测**：出口 IP 走代理时可能误判区域，用 `--region=cn/intl` 手动指定\n- **海外引擎国内不可达**：DDG 在国内被墙，国内策略不使用\n\n## 许可证\n\nMIT License\n\nFile v28.1.1:_meta.json\n\n{\n  \"ownerId\": \"kn7ecgbzbya89gesghbv1kty9d82r8e4\",\n  \"slug\": \"free-web-search-js\",\n  \"version\": \"28.1.1\",\n  \"publishedAt\": 1781709609396\n}\n\nFile v28.1.1:skill-card.md\n\n## Description: <br>\nWeb search and content fetching via Playwright and HTTP with no API keys; it searches Bing CN for domestic use or DuckDuckGo HTML internationally and can auto-fetch top page contents. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[ucsdzehualiu](https://clawhub.ai/user/ucsdzehualiu) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nDevelopers and agent users use this skill to perform live web searches, retrieve result snippets, and fetch page content for fact-checking, news lookup, tutorials, and documentation research without a search API key. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: Search terms and fetched URLs are sent to external search engines and websites from the user's machine. <br>\nMitigation: Avoid sensitive queries, or use --no-fetch or --fetch 0 when automatic page visits are not appropriate. <br>\nRisk: Automatic fetching can visit top result pages without separate confirmation. <br>\nMitigation: Limit the fetch count, disable auto-fetch for sensitive searches, and review fetched sources before relying on their contents. <br>\nRisk: Setup installs Node dependencies and may download a Playwright Chromium browser. <br>\nMitigation: Review the setup script before running it and use an existing trusted Chrome or Chromium executable through CHROMIUM_EXECUTABLE_PATH when preferred. <br>\n\n\n## Reference(s): <br>\n- [ClawHub Skill Page](https://clawhub.ai/ucsdzehualiu/free-web-search-js) <br>\n- [README](artifact/README.md) <br>\n- [Skill Definition](artifact/SKILL.md) <br>\n- [Test Report](artifact/TEST_REPORT.md) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [Text, Markdown, Shell commands, Configuration, Guidance] <br>\n**Output Format:** [Markdown or plain text search results with fetched page extracts and inline shell commands when setup or troubleshooting is needed] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [Search supports query, max result count, region selection, fetch count, no-fetch mode, and maximum fetched page length; fetch accepts one or more URLs.] <br>\n\n## Skill Version(s): <br>\n28.1.1 (source: SKILL.md frontmatter, package.json, release evidence) <br>\n\n## Ethical Considerations: <br>\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. <br>\n\nFile v28.1.1:TEST_REPORT.md\n\n# free-web-search-js v24.0 测试报告\n\n日期: 2026-04-24\n\n## 搜索测试\n\n| 查询 | 引擎 | 结果数 | 质量 | 问题 |\n|------|------|--------|------|------|\n| 今日金价 | Bing CN + 百度 | 15→5 | ⚠️ 中 | 混了百度经验教程，AI需自行筛选 |\n| docker compose deploy production | Bing CN + 百度 | 13→5 | ⚠️ 差 | 全是Docker官网首页/下载页，没compose生产部署内容 |\n| 俄乌冲突 2026年4月 | Bing CN + 百度 | 13→5 | ✅ 好 | 知乎讨论+snippet，1条噪音（俄的来源） |\n| python asyncio tutorial | Bing CN + 百度 | 15→5 | ❌ 差 | 全是Python泛文，asyncio完全没命中 |\n| 新能源汽车补贴政策 2026 | Bing CN + 百度 | 14→5 | ✅ 很好 | 搜狐/知乎/新浪/光明网/发改委，全精准 |\n| openclaw AI assistant setup | Bing CN + 百度 | 15→5 | ✅ 好 | 官网/中文站/腾讯云/知乎全命中 |\n| 霍尔木兹海峡 今日 | Bing CN + 百度 | 15→5 | ⚠️ 中 | 混了\"霍尔效应\"噪音，AI需自行筛 |\n\n## Fetch测试\n\n| URL | 模式 | 结果 | 问题 |\n|-----|------|------|------|\n| quote.cngold.org (金投网) | http-only | ⚠️ 结构拿到，价格全---- | JS动态加载，HTTP拿不到实时价格 |\n| docs.docker.com | http-only | ❌ fetch failed | 国内不通 |\n| docs.docker.com | headed | ✅ 完整内容 | Playwright兜底有效 |\n| economy.gmw.cn (光明网) | http-only | ⚠️ 拿到侧边栏不是正文 | 正文选择器没命中 |\n\n## 核心发现\n\n1. **中文query效果好** — Bing CN + 百度对中文新闻/政策/时事类query效果很好\n2. **英文query效果差** — Bing CN把英文技术词按中文分词切碎，返回泛泛结果\n3. **海外引擎国内全挂** — DDG/Brave/秘迹从国内全部timeout/fetch failed\n4. **JS动态内容HTTP拿不到** — 金投网等价格页面需要headed模式\n5. **知乎403** — HTTP直接抓知乎被拒，需headed\n6. **百度跳转URL解析** — 大部分能解析为直链，少数失败\n7. **删掉改写/过滤后** — skill更纯粹，噪音交给AI处理，符合设计原则\n\n## 待改进（不过度优化）\n\n- 英文query可尝试给Bing CN加 `&setlang=en-US` 参数，可能改善英文结果质量\n- fetch正文提取对部分站点命中率不够，但这是泛用难题，不宜针对特定站硬编码\n\nFile v28.1.1:package-lock.json\n\n{\n  \"name\": \"free-web-search-js\",\n  \"version\": \"28.1.0\",\n  \"lockfileVersion\": 3,\n  \"requires\": true,\n  \"packages\": {\n    \"\": {\n      \"name\": \"free-web-search-js\",\n      \"version\": \"28.1.0\",\n      \"dependencies\": {\n        \"cheerio\": \"~1.0.0\",\n        \"commander\": \"~12.1.0\",\n        \"iconv-lite\": \"~0.6.3\",\n        \"playwright\": \"~1.52.0\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/boolbase\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmmirror.com/boolbase/-/boolbase-1.0.0.tgz\",\n      \"integrity\": \"sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==\",\n      \"license\": \"ISC\"\n    },\n    \"node_modules/cheerio\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmmirror.com/cheerio/-/cheerio-1.0.0.tgz\",\n      \"integrity\": \"sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"cheerio-select\": \"^2.1.0\",\n        \"dom-serializer\": \"^2.0.0\",\n        \"domhandler\": \"^5.0.3\",\n        \"domutils\": \"^3.1.0\",\n        \"encoding-sniffer\": \"^0.2.0\",\n        \"htmlparser2\": \"^9.1.0\",\n        \"parse5\": \"^7.1.2\",\n        \"parse5-htmlparser2-tree-adapter\": \"^7.0.0\",\n        \"parse5-parser-stream\": \"^7.1.2\",\n        \"undici\": \"^6.19.5\",\n        \"whatwg-mimetype\": \"^4.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=18.17\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/cheeriojs/cheerio?sponsor=1\"\n      }\n    },\n    \"node_modules/cheerio-select\": {\n      \"version\": \"2.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/cheerio-select/-/cheerio-select-2.1.0.tgz\",\n      \"integrity\": \"sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==\",\n      \"license\": \"BSD-2-Clause\",\n      \"dependencies\": {\n        \"boolbase\": \"^1.0.0\",\n        \"css-select\": \"^5.1.0\",\n        \"css-what\": \"^6.1.0\",\n        \"domelementtype\": \"^2.3.0\",\n        \"domhandler\": \"^5.0.3\",\n        \"domutils\": \"^3.0.1\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/fb55\"\n      }\n    },\n    \"node_modules/commander\": {\n      \"version\": \"12.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/commander/-/commander-12.1.0.tgz\",\n      \"integrity\": \"sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/css-select\": {\n      \"version\": \"5.2.2\",\n      \"resolved\": \"https://registry.npmmirror.com/css-select/-/css-select-5.2.2.tgz\",\n      \"integrity\": \"sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==\",\n      \"license\": \"BSD-2-Clause\",\n      \"dependencies\": {\n        \"boolbase\": \"^1.0.0\",\n        \"css-what\": \"^6.1.0\",\n        \"domhandler\": \"^5.0.2\",\n        \"domutils\": \"^3.0.1\",\n        \"nth-check\": \"^2.0.1\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/fb55\"\n      }\n    },\n    \"node_modules/css-what\": {\n      \"version\": \"6.2.2\",\n      \"resolved\": \"https://registry.npmmirror.com/css-what/-/css-what-6.2.2.tgz\",\n      \"integrity\": \"sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==\",\n      \"license\": \"BSD-2-Clause\",\n      \"engines\": {\n        \"node\": \">= 6\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/fb55\"\n      }\n    },\n    \"node_modules/dom-serializer\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmmirror.com/dom-serializer/-/dom-serializer-2.0.0.tgz\",\n      \"integrity\": \"sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"domelementtype\": \"^2.3.0\",\n        \"domhandler\": \"^5.0.2\",\n        \"entities\": \"^4.2.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/cheeriojs/dom-serializer?sponsor=1\"\n      }\n    },\n    \"node_modules/domelementtype\": {\n      \"version\": \"2.3.0\",\n      \"resolved\": \"https://registry.npmmirror.com/domelementtype/-/domelementtype-2.3.0.tgz\",\n      \"integrity\": \"sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==\",\n      \"funding\": [\n        {\n          \"type\": \"github\",\n          \"url\": \"https://github.com/sponsors/fb55\"\n        }\n      ],\n      \"license\": \"BSD-2-Clause\"\n    },\n    \"node_modules/domhandler\": {\n      \"version\": \"5.0.3\",\n      \"resolved\": \"https://registry.npmmirror.com/domhandler/-/domhandler-5.0.3.tgz\",\n      \"integrity\": \"sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==\",\n      \"license\": \"BSD-2-Clause\",\n      \"dependencies\": {\n        \"domelementtype\": \"^2.3.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/fb55/domhandler?sponsor=1\"\n      }\n    },\n    \"node_modules/domutils\": {\n      \"version\": \"3.2.2\",\n      \"resolved\": \"https://registry.npmmirror.com/domutils/-/domutils-3.2.2.tgz\",\n      \"integrity\": \"sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==\",\n      \"license\": \"BSD-2-Clause\",\n      \"dependencies\": {\n        \"dom-serializer\": \"^2.0.0\",\n        \"domelementtype\": \"^2.3.0\",\n        \"domhandler\": \"^5.0.3\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/fb55/domutils?sponsor=1\"\n      }\n    },\n    \"node_modules/encoding-sniffer\": {\n      \"version\": \"0.2.1\",\n      \"resolved\": \"https://registry.npmmirror.com/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz\",\n      \"integrity\": \"sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"iconv-lite\": \"^0.6.3\",\n        \"whatwg-encoding\": \"^3.1.1\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/fb55/encoding-sniffer?sponsor=1\"\n      }\n    },\n    \"node_modules/entities\": {\n      \"version\": \"4.5.0\",\n      \"resolved\": \"https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz\",\n      \"integrity\": \"sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==\",\n      \"license\": \"BSD-2-Clause\",\n      \"engines\": {\n        \"node\": \">=0.12\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/fb55/entities?sponsor=1\"\n      }\n    },\n    \"node_modules/fsevents\": {\n      \"version\": \"2.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/fsevents/-/fsevents-2.3.2.tgz\",\n      \"integrity\": \"sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==\",\n      \"hasInstallScript\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"darwin\"\n      ],\n      \"engines\": {\n        \"node\": \"^8.16.0 || ^10.6.0 || >=11.0.0\"\n      }\n    },\n    \"node_modules/htmlparser2\": {\n      \"version\": \"9.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/htmlparser2/-/htmlparser2-9.1.0.tgz\",\n      \"integrity\": \"sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==\",\n      \"funding\": [\n        \"https://github.com/fb55/htmlparser2?sponsor=1\",\n        {\n          \"type\": \"github\",\n          \"url\": \"https://github.com/sponsors/fb55\"\n        }\n      ],\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"domelementtype\": \"^2.3.0\",\n        \"domhandler\": \"^5.0.3\",\n        \"domutils\": \"^3.1.0\",\n        \"entities\": \"^4.5.0\"\n      }\n    },\n    \"node_modules/iconv-lite\": {\n      \"version\": \"0.6.3\",\n      \"resolved\": \"https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.6.3.tgz\",\n      \"integrity\": \"sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"safer-buffer\": \">= 2.1.2 < 3.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      }\n    },\n    \"node_modules/nth-check\": {\n      \"version\": \"2.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/nth-check/-/nth-check-2.1.1.tgz\",\n      \"integrity\": \"sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==\",\n      \"license\": \"BSD-2-Clause\",\n      \"dependencies\": {\n        \"boolbase\": \"^1.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/fb55/nth-check?sponsor=1\"\n      }\n    },\n    \"node_modules/parse5\": {\n      \"version\": \"7.3.0\",\n      \"resolved\": \"https://registry.npmmirror.com/parse5/-/parse5-7.3.0.tgz\",\n      \"integrity\": \"sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"entities\": \"^6.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/inikulin/parse5?sponsor=1\"\n      }\n    },\n    \"node_modules/parse5-htmlparser2-tree-adapter\": {\n      \"version\": \"7.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz\",\n      \"integrity\": \"sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"domhandler\": \"^5.0.3\",\n        \"parse5\": \"^7.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/inikulin/parse5?sponsor=1\"\n      }\n    },\n    \"node_modules/parse5-parser-stream\": {\n      \"version\": \"7.1.2\",\n      \"resolved\": \"https://registry.npmmirror.com/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz\",\n      \"integrity\": \"sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"parse5\": \"^7.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/inikulin/parse5?sponsor=1\"\n      }\n    },\n    \"node_modules/parse5/node_modules/entities\": {\n      \"version\": \"6.0.1\",\n      \"resolved\": \"https://registry.npmmirror.com/entities/-/entities-6.0.1.tgz\",\n      \"integrity\": \"sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==\",\n      \"license\": \"BSD-2-Clause\",\n      \"engines\": {\n        \"node\": \">=0.12\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/fb55/entities?sponsor=1\"\n      }\n    },\n    \"node_modules/playwright\": {\n      \"version\": \"1.52.0\",\n      \"resolved\": \"https://registry.npmmirror.com/playwright/-/playwright-1.52.0.tgz\",\n      \"integrity\": \"sha512-JAwMNMBlxJ2oD1kce4KPtMkDeKGHQstdpFPcPH3maElAXon/QZeTvtsfXmTMRyO9TslfoYOXkSsvao2nE1ilTw==\",\n      \"license\": \"Apache-2.0\",\n      \"dependencies\": {\n        \"playwright-core\": \"1.52.0\"\n      },\n      \"bin\": {\n        \"playwright\": \"cli.js\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      },\n      \"optionalDependencies\": {\n        \"fsevents\": \"2.3.2\"\n      }\n    },\n    \"node_modules/playwright-core\": {\n      \"version\": \"1.52.0\",\n      \"resolved\": \"https://registry.npmmirror.com/playwright-core/-/playwright-core-1.52.0.tgz\",\n      \"integrity\": \"sha512-l2osTgLXSMeuLZOML9qYODUQoPPnUsKsb5/P6LJ2e6uPKXUdPK5WYhN4z03G+YNbWmGDY4YENauNu4ZKczreHg==\",\n      \"license\": \"Apache-2.0\",\n      \"bin\": {\n        \"playwright-core\": \"cli.js\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/safer-buffer\": {\n      \"version\": \"2.1.2\",\n      \"resolved\": \"https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz\",\n      \"integrity\": \"sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==\",\n      \"license\": \"MIT\"\n    },\n    \"node_modules/undici\": {\n      \"version\": \"6.27.0\",\n      \"resolved\": \"https://registry.npmmirror.com/undici/-/undici-6.27.0.tgz\",\n      \"integrity\": \"sha512-YmfV3YnEDzXRC5lZ2jWtWWHKGUm1zIt8AhesR1tens+HTNv+YZlN/dp6G727LOvMJ8xjP9Be7Y2Sdr96LDm+pg==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">=18.17\"\n      }\n    },\n    \"node_modules/whatwg-encoding\": {\n      \"version\": \"3.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz\",\n      \"integrity\": \"sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==\",\n      \"deprecated\": \"Use @exodus/bytes instead for a more spec-conformant and faster implementation\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"iconv-lite\": \"0.6.3\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/whatwg-mimetype\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmmirror.com/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz\",\n      \"integrity\": \"sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    }\n  }\n}\n\nFile v28.1.1:package.json\n\n{\n  \"name\": \"free-web-search-js\",\n  \"version\": \"28.1.1\",\n  \"type\": \"module\",\n  \"description\": \"Playwright 联网搜索，国内Bing/搜狗，海外DDG，自动抓取，零 API Key\",\n  \"engines\": {\n    \"node\": \">=18\"\n  },\n  \"scripts\": {\n    \"search\": \"node scripts/search.js\",\n    \"fetch\": \"node scripts/fetch.js\",\n    \"check\": \"node scripts/check-env.js\",\n    \"daemon\": \"node scripts/browser-daemon.js\"\n  },\n  \"dependencies\": {\n    \"cheerio\": \"~1.0.0\",\n    \"commander\": \"~12.1.0\",\n    \"iconv-lite\": \"~0.6.3\",\n    \"playwright\": \"~1.52.0\"\n  }\n}\n\nArchive v1.0.1: 30 files, 49035 bytes\n\nFiles: _meta.json (137b), package-lock.json (13239b), package.json (414b), README.md (5479b), scripts/_batch_test.js (1109b), scripts/_batch_test2.js (2550b), scripts/_bench.js (363b), scripts/_bench2.js (226b), scripts/_debug_baidu_box.js (1992b), scripts/_debug_baidu_pw.js (1519b), scripts/_debug_bing_cookie.js (2587b), scripts/_debug_bing_full.js (4731b), scripts/_debug_bing_pw.js (1458b), scripts/_debug_bing.js (1701b), scripts/_debug_bing2.js (3999b), scripts/_debug_bing3.js (1966b), scripts/_debug_cookie_combos.js (2786b), scripts/_debug_cookie_fetch.js (2159b), scripts/_debug_ddg.js (2682b), scripts/_debug_searchbox.js (1737b), scripts/_time_one.js (468b), scripts/browser-daemon.js (2967b), scripts/check-env.js (2742b), scripts/fetch.js (14937b), scripts/playwright-support.js (4124b), scripts/search.js (18890b), scripts/setup.sh (2371b), skill-card.md (2482b), SKILL.md (7908b), TEST_REPORT.md (2321b)\n\nFile v1.0.1:SKILL.md\n\n---\nname: free-web-search-js\ndescription: Playwright/HTTP 联网搜索与网页正文抓取，零 API Key。用于实时搜索、查资料、新闻、教程、网页内容读取；支持国内 Bing、海外 DDG、自动抓取正文。\nversion: 28.0.0\ntrigger_keywords:\n  - 搜索\n  - 查一下\n  - 找一下\n  - 最新消息\n  - 新闻\n  - 教程\n  - 是什么\n  - search\n  - find\ntools:\n  - name: search\n    description: 搜索+自动抓取，国内Bing Playwright，海外DDG HTTP\n    script: scripts/search.js\n    parameters:\n      query:\n        type: string\n        description: \"搜索关键词\"\n        required: true\n      max:\n        type: integer\n        description: \"最大结果数，默认10，上限30\"\n        required: false\n      region:\n        type: string\n        description: \"区域: auto/cn/intl，默认auto按IP检测\"\n        required: false\n  - name: fetch\n    description: 给定URL抓取正文，HTTP优先失败自动headed兜底\n    script: scripts/fetch.js\n    parameters:\n      urls:\n        type: string\n        description: \"要抓取的URL，多个用空格分隔\"\n        required: true\n      max-len:\n        type: integer\n        description: \"单页最大字符数，默认12000\"\n        required: false\n---\n\n# free-web-search-js\n\n一步式：**search** → 搜索 → 自动抓内容 → 返回。优先 HTTP，必要时 Playwright 兜底；在无桌面/服务器环境默认 headless，避免 GUI 依赖。\n\n## 架构\n\n```\n国内：\n  Playwright headless 打开 Bing → 首页拿 cookie → 搜索框提交\n  → 结果为空时自动兜底 DDG HTTP\n  → 自动抓取 top 3 页面内容\n\n海外：\n  纯 HTTP → DDG HTML 解析\n  → fetch 失败时用 Playwright request 兜底\n  → 自动抓取 top 3 页面内容\n```\n\n## 搜索引擎\n\n| 引擎 | 协议 | 区域 | 说明 |\n|------|------|------|------|\n| Bing CN | Playwright 搜索框提交 | 国内 | 先访问首页拿 cookie，再搜索框输入提交 |\n| 搜狗 | 纯 HTTP | 国内 | `--engine=sogou` 可选，⚠ 无 cookie 易被反爬拦截，结果不稳定 |\n| DDG HTML Lite | 纯 HTTP | 海外 | html.duckduckgo.com |\n\n### 策略\n\n| 区域 | 搜索 | 抓取 |\n|------|------|------|\n| 国内 | Bing CN (Playwright headless)，空结果兜底 DDG | 自动抓前 3 条 |\n| 海外 | DDG HTML，fetch 失败兜底 Playwright request；DDG 为空再兜底 Bing | 自动抓前 3 条 |\n\n### IP 怎么判断\n\n每次搜索时自动检测，三轮探测并行，谁先成功用谁：\n\n| 轮次 | 探测服务 | 逻辑 |\n|------|---------|------|\n| 第1轮 | `myip.ipip.net` / `cip.cc` | 国内可达优先 |\n| 第2轮 | `ipinfo.io` / `ipapi.co` | 国际探测 |\n| 第3轮 | 试连 `cn.bing.com` | 能通大概率国内 |\n| 兜底 | — | 默认国内 |\n\n出口 IP 走代理时可能误判，用 `--region=cn` 或 `--region=intl` 手动指定。\n\n## 去重\n\n智能去重：域名 + 路径主干（忽略 www/m 子域、tracking 参数、尾部斜杠、.html 后缀）。\n\nBing 跳转 URL（`bing.com/ck/`）自动解码为直链。\n\n## 抓取模式\n\n搜索后自动抓取 top N 条 URL 内容（默认 3 条）。\n\n| 层级 | 方式 | 速度 | 说明 |\n|------|------|------|------|\n| 第1层 | 轻量 HTTP + cheerio | ⚡ 秒出 | 不启动浏览器 |\n| 第2层 | Playwright headed | 🟡 慢 | 完整浏览器，支持 JS 渲染 |\n\n第1层增强：\n- **JSON API 响应**：自动检测 Content-Type 并提取结构化内容\n- **JSON-LD**：提取 `<script type=\"application/ld+json\">` 中的 articleBody/description\n- **__NEXT_DATA__**：提取 Next.js 嵌入数据\n- **meta 标签**：og:description / description 兜底\n- **GBK 编码**：自动检测并转换\n\n## 可靠性设计\n\n- `SKILL.md` 必须以 YAML frontmatter 开头；不要在 `---` 前加标题，否则 OpenClaw 可能无法发现技能。\n- `scripts/check-env.js` 检查的是**可执行浏览器文件**，不是只看 `~/.cache/ms-playwright` 目录，避免“缓存目录存在但浏览器缺文件”的假阳性。\n- Playwright 默认 `headless: true`，并带 `--no-sandbox` / `--disable-dev-shm-usage`，适配 Linux 服务器、Docker、无桌面环境。\n- 如果 Playwright 新版本要求 `chrome-headless-shell` 但下载慢/中断，脚本会优先复用已存在的 Chromium 可执行文件；也可设置 `CHROMIUM_EXECUTABLE_PATH=/path/to/chrome`。\n- DDG 的 Node `fetch` 在部分网络会 `fetch failed`，已内置 Playwright request 兜底；如果仍为空，会再用 Bing Playwright 兜底，保证海外策略在国内网络也尽量有结果。\n\n## 安装\n\n**前置依赖（全部必装）：**\n\n| 依赖 | 说明 | 大小/耗时 |\n|------|------|----------|\n| Node.js >= 18 | 运行时 | — |\n| cheerio | HTML 解析 | 小，秒装 |\n| commander | CLI 参数解析 | 小，秒装 |\n| iconv-lite | GBK 编码转换 | 小，秒装 |\n| playwright | 浏览器自动化（Bing 搜索 + 抓取兜底） | ~50MB |\n| Chromium | Playwright 专用浏览器 | **~150MB，需几分钟下载** |\n\n安装脚本自动检测网络区域，国内使用镜像源加速：\n\n```bash\n# Windows\npowershell -File scripts/setup.ps1\n\n# Linux/macOS\nbash scripts/setup.sh\n```\n\n国内镜像：\n- npm: `https://registry.npmmirror.com`\n- Playwright/Chromium: `https://npmmirror.com/mirrors/playwright`\n\n手动安装：\n```bash\ncd skills/free-web-search-js\nnpm install\nnpx playwright install chromium    # ~150MB，需几分钟\n# 如果下载慢/中断，可重试，或设置国内镜像：\nPLAYWRIGHT_DOWNLOAD_HOST=https://npmmirror.com/mirrors/playwright npx playwright install chromium\n# 如果系统已有 Chrome/Chromium：\nexport CHROMIUM_EXECUTABLE_PATH=/path/to/chrome\n```\n\n验证环境：`node scripts/check-env.js`\n\n卸载：`node scripts/uninstall.js`\n\n## 验证与故障排查\n\n```bash\ncd skills/free-web-search-js\nnode scripts/check-env.js\nnode scripts/search.js \"OpenClaw\" --max 2 --region cn --fetch 0\nnode scripts/search.js \"OpenClaw\" --max 2 --region intl --fetch 0\n```\n\n常见问题：\n\n- `node_modules not found`：运行 `npm install`。\n- `Executable doesn't exist ... chrome-headless-shell`：运行 `bash scripts/setup.sh`，或设置 `CHROMIUM_EXECUTABLE_PATH` 指向已有 Chrome/Chromium。\n- `browserType.launch ... closed`：通常是无桌面/沙箱/缺浏览器文件；当前脚本默认 headless + no-sandbox，如仍失败，先跑 `node scripts/check-env.js`。\n- 搜索 0 条：换 `--region=cn`/`--region=intl`，或 `--fetch 0` 先只测搜索。\n\n## 性能优化：浏览器守护进程\n\n搜索和抓取可复用浏览器守护进程，**提速约 70%**：\n\n```bash\nnode scripts/browser-daemon.js &       # 启动\nnode scripts/browser-daemon.js --status # 状态\nnode scripts/browser-daemon.js --stop   # 停止\n```\n\n守护进程空闲 10 分钟自动退出。\n\n## 用法\n\n```bash\n# 搜索（搜 + 自动抓前3条内容）\nnode scripts/search.js \"白银价格\"\nnode scripts/search.js \"how to deploy docker\" --max=5\nnode scripts/search.js \"xxx\" --region=cn\nnode scripts/search.js \"xxx\" --fetch=5          # 抓前5条\nnode scripts/search.js \"xxx\" --no-fetch         # 只搜不抓\n\n# 单独抓取（给定 URL）\nnode scripts/fetch.js \"https://example.com/page1\" \"https://example.com/page2\"\n```\n\n## 已知限制\n\n- **国内首次搜索较慢**：需启动 Chromium（3~6s），后续复用更快\n- **Bing CN 即时答案不返回**：天气、计算器等即时卡片不走 `li.b_algo`，搜索结果为 0\n- **搜狗 HTTP 不稳定**：无 cookie 纯请求易被反爬拦截，结果可能为空（`--engine=sogou` 慎用）\n- **部分站点 HTTP 抓不到**：需要 JS 渲染的页面——HTTP 失败会自动 headed 重试\n- **部分站点海外不可达**：国内专属站点从海外访问可能超时\n- **代理干扰 IP 检测**：出口 IP 走代理时可能误判区域，用 `--region=cn/intl` 手动指定\n- **海外引擎国内不可达**：DDG 在国内被墙，国内策略不使用\n\nFile v1.0.1:README.md\n\n# free-web-search-js\n\n## 项目简介\n\nfree-web-search-js 是一个基于 Playwright和JS写 的免费网络搜索skill 可用于CC或者openclaw（clawhub install free-web-search-js），无需 API Key，支持国内和海外搜索，自动抓取搜索结果内容。\n\n- **免费**：零成本使用，无需 API Key\n- **稳定**：智能选择搜索策略，自动应对反爬\n- **快速**：首次搜索 3\\~6 秒，后续复用浏览器更快\n- **自动抓取**：搜索后自动抓取 top N 条结果内容\n- **跨区域**：国内使用 Bing/搜狗，海外使用 DDG\n\n## 支持的搜索引擎\n\n| 引擎       | 协议               | 区域 | 说明                                          |\n| -------- | ---------------- | -- | ------------------------------------------- |\n| Bing CN  | Playwright 搜索框提交 | 国内 | 先访问首页拿 cookie，再搜索框输入提交                      |\n| 搜狗       | 纯 HTTP           | 国内 | `--engine=sogou` 可选，⚠ 无 cookie 易被反爬拦截，结果不稳定 |\n| DDG HTML | 纯 HTTP           | 海外 | html.duckduckgo.com                         |\n\n## 安装\n\n### 前置依赖\n\n| 依赖            | 说明                     | 大小/耗时              |\n| ------------- | ---------------------- | ------------------ |\n| Node.js >= 18 | 运行时                    | —                  |\n| cheerio       | HTML 解析                | 小，秒装               |\n| commander     | CLI 参数解析               | 小，秒装               |\n| iconv-lite    | GBK 编码转换               | 小，秒装               |\n| playwright    | 浏览器自动化（Bing 搜索 + 抓取兜底） | \\~50MB             |\n| Chromium      | Playwright 专用浏览器       | **\\~150MB，需几分钟下载** |\n\n### 安装步骤\n\n#### 一键安装\n\n```bash\n# Linux/macOS\nbash scripts/setup.sh\n\n# Windows\n# 目前仅提供 Linux/macOS 一键安装脚本\n# Windows 用户请使用手动安装方式\n```\n\n#### 手动安装\n\n```bash\n# 进入项目目录\ncd free-web-search-js\n\n# 安装依赖\nnpm install\n\n# 安装 Playwright 浏览器\nnpx playwright install chromium    # ~150MB，需几分钟\n```\n\n### 国内镜像加速\n\n```bash\n# npm 镜像\nnpm install --registry=https://registry.npmmirror.com\n\n# Playwright/Chromium 镜像\nPLAYWRIGHT_DOWNLOAD_HOST=https://npmmirror.com/mirrors/playwright npx playwright install chromium\n```\n\n### 验证环境\n\n```bash\nnode scripts/check-env.js\n```\n\n### 卸载\n\n```bash\nnode scripts/uninstall.js\n```\n\n## 用法\n\n### 搜索（搜 + 自动抓内容）\n\n```bash\n# 基本搜索\nnode scripts/search.js \"白银价格\"\n\n# 控制结果数量\nnode scripts/search.js \"how to deploy docker\" --max=5\n\n# 指定区域\nnode scripts/search.js \"xxx\" --region=cn\n\n# 指定搜索引擎\nnode scripts/search.js \"xxx\" --engine=bing\n\n# 控制抓取数量\nnode scripts/search.js \"xxx\" --fetch=5          # 抓前5条\n\n# 只搜索不抓取\nnode scripts/search.js \"xxx\" --no-fetch\n\n# 控制单页最大字符数\nnode scripts/search.js \"xxx\" --max-len=8000\n```\n\n### 单独抓取（给定 URL）\n\n```bash\nnode scripts/fetch.js \"https://example.com/page1\" \"https://example.com/page2\"\n```\n\n## 性能优化：浏览器守护进程\n\n搜索和抓取可复用浏览器守护进程，**提速约 70%**：\n\n```bash\nnode scripts/browser-daemon.js &       # 启动\nnode scripts/browser-daemon.js --status # 状态\nnode scripts/browser-daemon.js --stop   # 停止\n```\n\n守护进程空闲 10 分钟自动退出。\n\n## 架构\n\n### 国内搜索流程\n\n```\nPlaywright 打开 Bing → 首页拿 cookie → 搜索框提交 → 自动抓取 top N 页面内容\n延迟：首次 3~6s（启动浏览器），后续复用更快\n```\n\n### 海外搜索流程\n\n```\n纯 HTTP → DDG HTML 解析 → 自动抓取 top N 页面内容\n延迟：几百ms~1s\n```\n\n### 抓取模式\n\n| 层级  | 方式                | 速度   | 说明             |\n| --- | ----------------- | ---- | -------------- |\n| 第1层 | 轻量 HTTP + cheerio | ⚡ 秒出 | 不启动浏览器         |\n| 第2层 | Playwright headed | 🟡 慢 | 完整浏览器，支持 JS 渲染 |\n\n## 区域检测\n\n每次搜索时自动检测，三轮探测并行，谁先成功用谁：\n\n| 轮次  | 探测服务                       | 逻辑      |\n| --- | -------------------------- | ------- |\n| 第1轮 | `myip.ipip.net` / `cip.cc` | 国内可达优先  |\n| 第2轮 | `ipinfo.io` / `ipapi.co`   | 国际探测    |\n| 第3轮 | 试连 `cn.bing.com`           | 能通大概率国内 |\n| 兜底  | —                          | 默认国内    |\n\n## 去重\n\n智能去重：域名 + 路径主干（忽略 www/m 子域、tracking 参数、尾部斜杠、.html 后缀）。\n\nBing 跳转 URL（`bing.com/ck/`）自动解码为直链。\n\n## 已知限制\n\n- **国内首次搜索较慢**：需启动 Chromium（3\\~6s），后续复用更快\n- **Bing CN 即时答案不返回**：天气、计算器等即时卡片不走 `li.b_algo`，搜索结果为 0\n- **搜狗 HTTP 不稳定**：无 cookie 纯请求易被反爬拦截，结果可能为空（`--engine=sogou` 慎用）\n- **部分站点 HTTP 抓不到**：需要 JS 渲染的页面——HTTP 失败会自动 headed 重试\n- **部分站点海外不可达**：国内专属站点从海外访问可能超时\n- **代理干扰 IP 检测**：出口 IP 走代理时可能误判区域，用 `--region=cn/intl` 手动指定\n- **海外引擎国内不可达**：DDG 在国内被墙，国内策略不使用\n\n## 许可证\n\nMIT License\n\nFile v1.0.1:_meta.json\n\n{\n  \"ownerId\": \"kn7ecgbzbya89gesghbv1kty9d82r8e4\",\n  \"slug\": \"free-web-search-js\",\n  \"version\": \"1.0.1\",\n  \"publishedAt\": 1779763984175\n}\n\nFile v1.0.1:skill-card.md\n\n## Description: <br>\nProvides Playwright and HTTP-based web search and page-content fetching without an API key, using regional search strategies for Bing CN, Sogou, and DuckDuckGo. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[ucsdzehualiu](https://clawhub.ai/user/ucsdzehualiu) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nDevelopers and agents use this skill to run live web searches and fetch readable page content when a task needs current information without a paid search API. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: Search queries and fetched URLs are sent to third-party search engines and target websites. <br>\nMitigation: Avoid sensitive queries and review whether the target environment permits those external requests before use. <br>\nRisk: The skill drives Chromium through Playwright and can keep a browser daemon running. <br>\nMitigation: Run it in a constrained environment and stop the browser daemon when it is not needed. <br>\nRisk: The security review flags under-scoped shell and package-install behavior, including runtime npm installs and execSync URL handling. <br>\nMitigation: Review or patch those paths before deployment and prefer locked dependency installation. <br>\nRisk: The skill auto-fetches result pages, which can retrieve untrusted or misleading web content. <br>\nMitigation: Treat fetched content as untrusted input and have agents cite, cross-check, or otherwise validate important claims. <br>\n\n\n## Reference(s): <br>\n- [ClawHub skill page](https://clawhub.ai/ucsdzehualiu/free-web-search-js) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [text, JSON, shell commands, configuration] <br>\n**Output Format:** [JSON search or fetch results with extracted page text; setup and troubleshooting guidance as shell commands.] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [Search results can include automatically fetched content from the top results, with per-page length controls.] <br>\n\n## Skill Version(s): <br>\n1.0.1 (source: server release metadata; artifact frontmatter and package.json report 28.0.0) <br>\n\n## Ethical Considerations: <br>\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. <br>\n\nFile v1.0.1:TEST_REPORT.md\n\n# free-web-search-js v24.0 测试报告\n\n日期: 2026-04-24\n\n## 搜索测试\n\n| 查询 | 引擎 | 结果数 | 质量 | 问题 |\n|------|------|--------|------|------|\n| 今日金价 | Bing CN + 百度 | 15→5 | ⚠️ 中 | 混了百度经验教程，AI需自行筛选 |\n| docker compose deploy production | Bing CN + 百度 | 13→5 | ⚠️ 差 | 全是Docker官网首页/下载页，没compose生产部署内容 |\n| 俄乌冲突 2026年4月 | Bing CN + 百度 | 13→5 | ✅ 好 | 知乎讨论+snippet，1条噪音（俄的来源） |\n| python asyncio tutorial | Bing CN + 百度 | 15→5 | ❌ 差 | 全是Python泛文，asyncio完全没命中 |\n| 新能源汽车补贴政策 2026 | Bing CN + 百度 | 14→5 | ✅ 很好 | 搜狐/知乎/新浪/光明网/发改委，全精准 |\n| openclaw AI assistant setup | Bing CN + 百度 | 15→5 | ✅ 好 | 官网/中文站/腾讯云/知乎全命中 |\n| 霍尔木兹海峡 今日 | Bing CN + 百度 | 15→5 | ⚠️ 中 | 混了\"霍尔效应\"噪音，AI需自行筛 |\n\n## Fetch测试\n\n| URL | 模式 | 结果 | 问题 |\n|-----|------|------|------|\n| quote.cngold.org (金投网) | http-only | ⚠️ 结构拿到，价格全---- | JS动态加载，HTTP拿不到实时价格 |\n| docs.docker.com | http-only | ❌ fetch failed | 国内不通 |\n| docs.docker.com | headed | ✅ 完整内容 | Playwright兜底有效 |\n| economy.gmw.cn (光明网) | http-only | ⚠️ 拿到侧边栏不是正文 | 正文选择器没命中 |\n\n## 核心发现\n\n1. **中文query效果好** — Bing CN + 百度对中文新闻/政策/时事类query效果很好\n2. **英文query效果差** — Bing CN把英文技术词按中文分词切碎，返回泛泛结果\n3. **海外引擎国内全挂** — DDG/Brave/秘迹从国内全部timeout/fetch failed\n4. **JS动态内容HTTP拿不到** — 金投网等价格页面需要headed模式\n5. **知乎403** — HTTP直接抓知乎被拒，需headed\n6. **百度跳转URL解析** — 大部分能解析为直链，少数失败\n7. **删掉改写/过滤后** — skill更纯粹，噪音交给AI处理，符合设计原则\n\n## 待改进（不过度优化）\n\n- 英文query可尝试给Bing CN加 `&setlang=en-US` 参数，可能改善英文结果质量\n- fetch正文提取对部分站点命中率不够，但这是泛用难题，不宜针对特定站硬编码\n\nFile v1.0.1:package-lock.json\n\n{\n  \"name\": \"free-web-search-js\",\n  \"version\": \"28.0.0\",\n  \"lockfileVersion\": 3,\n  \"requires\": true,\n  \"packages\": {\n    \"\": {\n      \"name\": \"free-web-search-js\",\n      \"version\": \"28.0.0\",\n      \"dependencies\": {\n        \"cheerio\": \"^1.0.0\",\n        \"commander\": \"^12.0.0\",\n        \"iconv-lite\": \"^0.6.3\",\n        \"playwright\": \"^1.52.0\"\n      }\n    },\n    \"node_modules/boolbase\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmmirror.com/boolbase/-/boolbase-1.0.0.tgz\",\n      \"integrity\": \"sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==\",\n      \"license\": \"ISC\"\n    },\n    \"node_modules/cheerio\": {\n      \"version\": \"1.2.0\",\n      \"resolved\": \"https://registry.npmmirror.com/cheerio/-/cheerio-1.2.0.tgz\",\n      \"integrity\": \"sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"cheerio-select\": \"^2.1.0\",\n        \"dom-serializer\": \"^2.0.0\",\n        \"domhandler\": \"^5.0.3\",\n        \"domutils\": \"^3.2.2\",\n        \"encoding-sniffer\": \"^0.2.1\",\n        \"htmlparser2\": \"^10.1.0\",\n        \"parse5\": \"^7.3.0\",\n        \"parse5-htmlparser2-tree-adapter\": \"^7.1.0\",\n        \"parse5-parser-stream\": \"^7.1.2\",\n        \"undici\": \"^7.19.0\",\n        \"whatwg-mimetype\": \"^4.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=20.18.1\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/cheeriojs/cheerio?sponsor=1\"\n      }\n    },\n    \"node_modules/cheerio-select\": {\n      \"version\": \"2.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/cheerio-select/-/cheerio-select-2.1.0.tgz\",\n      \"integrity\": \"sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==\",\n      \"license\": \"BSD-2-Clause\",\n      \"dependencies\": {\n        \"boolbase\": \"^1.0.0\",\n        \"css-select\": \"^5.1.0\",\n        \"css-what\": \"^6.1.0\",\n        \"domelementtype\": \"^2.3.0\",\n        \"domhandler\": \"^5.0.3\",\n        \"domutils\": \"^3.0.1\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/fb55\"\n      }\n    },\n    \"node_modules/commander\": {\n      \"version\": \"12.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/commander/-/commander-12.1.0.tgz\",\n      \"integrity\": \"sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/css-select\": {\n      \"version\": \"5.2.2\",\n      \"resolved\": \"https://registry.npmmirror.com/css-select/-/css-select-5.2.2.tgz\",\n      \"integrity\": \"sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==\",\n      \"license\": \"BSD-2-Clause\",\n      \"dependencies\": {\n        \"boolbase\": \"^1.0.0\",\n        \"css-what\": \"^6.1.0\",\n        \"domhandler\": \"^5.0.2\",\n        \"domutils\": \"^3.0.1\",\n        \"nth-check\": \"^2.0.1\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/fb55\"\n      }\n    },\n    \"node_modules/css-what\": {\n      \"version\": \"6.2.2\",\n      \"resolved\": \"https://registry.npmmirror.com/css-what/-/css-what-6.2.2.tgz\",\n      \"integrity\": \"sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==\",\n      \"license\": \"BSD-2-Clause\",\n      \"engines\": {\n        \"node\": \">= 6\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/fb55\"\n      }\n    },\n    \"node_modules/dom-serializer\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmmirror.com/dom-serializer/-/dom-serializer-2.0.0.tgz\",\n      \"integrity\": \"sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"domelementtype\": \"^2.3.0\",\n        \"domhandler\": \"^5.0.2\",\n        \"entities\": \"^4.2.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/cheeriojs/dom-serializer?sponsor=1\"\n      }\n    },\n    \"node_modules/domelementtype\": {\n      \"version\": \"2.3.0\",\n      \"resolved\": \"https://registry.npmmirror.com/domelementtype/-/domelementtype-2.3.0.tgz\",\n      \"integrity\": \"sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==\",\n      \"funding\": [\n        {\n          \"type\": \"github\",\n          \"url\": \"https://github.com/sponsors/fb55\"\n        }\n      ],\n      \"license\": \"BSD-2-Clause\"\n    },\n    \"node_modules/domhandler\": {\n      \"version\": \"5.0.3\",\n      \"resolved\": \"https://registry.npmmirror.com/domhandler/-/domhandler-5.0.3.tgz\",\n      \"integrity\": \"sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==\",\n      \"license\": \"BSD-2-Clause\",\n      \"dependencies\": {\n        \"domelementtype\": \"^2.3.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/fb55/domhandler?sponsor=1\"\n      }\n    },\n    \"node_modules/domutils\": {\n      \"version\": \"3.2.2\",\n      \"resolved\": \"https://registry.npmmirror.com/domutils/-/domutils-3.2.2.tgz\",\n      \"integrity\": \"sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==\",\n      \"license\": \"BSD-2-Clause\",\n      \"dependencies\": {\n        \"dom-serializer\": \"^2.0.0\",\n        \"domelementtype\": \"^2.3.0\",\n        \"domhandler\": \"^5.0.3\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/fb55/domutils?sponsor=1\"\n      }\n    },\n    \"node_modules/encoding-sniffer\": {\n      \"version\": \"0.2.1\",\n      \"resolved\": \"https://registry.npmmirror.com/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz\",\n      \"integrity\": \"sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"iconv-lite\": \"^0.6.3\",\n        \"whatwg-encoding\": \"^3.1.1\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/fb55/encoding-sniffer?sponsor=1\"\n      }\n    },\n    \"node_modules/entities\": {\n      \"version\": \"4.5.0\",\n      \"resolved\": \"https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz\",\n      \"integrity\": \"sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==\",\n      \"license\": \"BSD-2-Clause\",\n      \"engines\": {\n        \"node\": \">=0.12\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/fb55/entities?sponsor=1\"\n      }\n    },\n    \"node_modules/fsevents\": {\n      \"version\": \"2.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/fsevents/-/fsevents-2.3.2.tgz\",\n      \"integrity\": \"sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==\",\n      \"hasInstallScript\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"darwin\"\n      ],\n      \"engines\": {\n        \"node\": \"^8.16.0 || ^10.6.0 || >=11.0.0\"\n      }\n    },\n    \"node_modules/htmlparser2\": {\n      \"version\": \"10.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/htmlparser2/-/htmlparser2-10.1.0.tgz\",\n      \"integrity\": \"sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==\",\n      \"funding\": [\n        \"https://github.com/fb55/htmlparser2?sponsor=1\",\n        {\n          \"type\": \"github\",\n          \"url\": \"https://github.com/sponsors/fb55\"\n        }\n      ],\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"domelementtype\": \"^2.3.0\",\n        \"domhandler\": \"^5.0.3\",\n        \"domutils\": \"^3.2.2\",\n        \"entities\": \"^7.0.1\"\n      }\n    },\n    \"node_modules/htmlparser2/node_modules/entities\": {\n      \"version\": \"7.0.1\",\n      \"resolved\": \"https://registry.npmmirror.com/entities/-/entities-7.0.1.tgz\",\n      \"integrity\": \"sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==\",\n      \"license\": \"BSD-2-Clause\",\n      \"engines\": {\n        \"node\": \">=0.12\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/fb55/entities?sponsor=1\"\n      }\n    },\n    \"node_modules/iconv-lite\": {\n      \"version\": \"0.6.3\",\n      \"resolved\": \"https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.6.3.tgz\",\n      \"integrity\": \"sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"safer-buffer\": \">= 2.1.2 < 3.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      }\n    },\n    \"node_modules/nth-check\": {\n      \"version\": \"2.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/nth-check/-/nth-check-2.1.1.tgz\",\n      \"integrity\": \"sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==\",\n      \"license\": \"BSD-2-Clause\",\n      \"dependencies\": {\n        \"boolbase\": \"^1.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/fb55/nth-check?sponsor=1\"\n      }\n    },\n    \"node_modules/parse5\": {\n      \"version\": \"7.3.0\",\n      \"resolved\": \"https://registry.npmmirror.com/parse5/-/parse5-7.3.0.tgz\",\n      \"integrity\": \"sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"entities\": \"^6.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/inikulin/parse5?sponsor=1\"\n      }\n    },\n    \"node_modules/parse5-htmlparser2-tree-adapter\": {\n      \"version\": \"7.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz\",\n      \"integrity\": \"sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"domhandler\": \"^5.0.3\",\n        \"parse5\": \"^7.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/inikulin/parse5?sponsor=1\"\n      }\n    },\n    \"node_modules/parse5-parser-stream\": {\n      \"version\": \"7.1.2\",\n      \"resolved\": \"https://registry.npmmirror.com/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz\",\n      \"integrity\": \"sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"parse5\": \"^7.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/inikulin/parse5?sponsor=1\"\n      }\n    },\n    \"node_modules/parse5/node_modules/entities\": {\n      \"version\": \"6.0.1\",\n      \"resolved\": \"https://registry.npmmirror.com/entities/-/entities-6.0.1.tgz\",\n      \"integrity\": \"sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==\",\n      \"license\": \"BSD-2-Clause\",\n      \"engines\": {\n        \"node\": \">=0.12\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/fb55/entities?sponsor=1\"\n      }\n    },\n    \"node_modules/playwright\": {\n      \"version\": \"1.59.1\",\n      \"resolved\": \"https://registry.npmmirror.com/playwright/-/playwright-1.59.1.tgz\",\n      \"integrity\": \"sha512-C8oWjPR3F81yljW9o5OxcWzfh6avkVwDD2VYdwIGqTkl+OGFISgypqzfu7dOe4QNLL2aqcWBmI3PMtLIK233lw==\",\n      \"license\": \"Apache-2.0\",\n      \"dependencies\": {\n        \"playwright-core\": \"1.59.1\"\n      },\n      \"bin\": {\n        \"playwright\": \"cli.js\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      },\n      \"optionalDependencies\": {\n        \"fsevents\": \"2.3.2\"\n      }\n    },\n    \"node_modules/playwright-core\": {\n      \"version\": \"1.59.1\",\n      \"resolved\": \"https://registry.npmmirror.com/playwright-core/-/playwright-core-1.59.1.tgz\",\n      \"integrity\": \"sha512-HBV/RJg81z5BiiZ9yPzIiClYV/QMsDCKUyogwH9p3MCP6IYjUFu/MActgYAvK0oWyV9NlwM3GLBjADyWgydVyg==\",\n      \"license\": \"Apache-2.0\",\n      \"bin\": {\n        \"playwright-core\": \"cli.js\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/safer-buffer\": {\n      \"version\": \"2.1.2\",\n      \"resolved\": \"https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz\",\n      \"integrity\": \"sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==\",\n      \"license\": \"MIT\"\n    },\n    \"node_modules/undici\": {\n      \"version\": \"7.25.0\",\n      \"resolved\": \"https://registry.npmmirror.com/undici/-/undici-7.25.0.tgz\",\n      \"integrity\": \"sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">=20.18.1\"\n      }\n    },\n    \"node_modules/whatwg-encoding\": {\n      \"version\": \"3.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz\",\n      \"integrity\": \"sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==\",\n      \"deprecated\": \"Use @exodus/bytes instead for a more spec-conformant and faster implementation\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"iconv-lite\": \"0.6.3\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/whatwg-mimetype\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmmirror.com/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz\",\n      \"integrity\": \"sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    }\n  }\n}\n\nFile v1.0.1:package.json\n\n{\n  \"name\": \"free-web-search-js\",\n  \"version\": \"28.0.0\",\n  \"type\": \"module\",\n  \"description\": \"Playwright 联网搜索，国内Bing/搜狗，海外DDG，自动抓取，零 API Key\",\n  \"scripts\": {\n    \"search\": \"node scripts/search.js\",\n    \"fetch\": \"node scripts/fetch.js\"\n  },\n  \"dependencies\": {\n    \"cheerio\": \"^1.0.0\",\n    \"commander\": \"^12.0.0\",\n    \"iconv-lite\": \"^0.6.3\",\n    \"playwright\": \"^1.52.0\"\n  }\n}\n\nArchive v1.0.0: 26 files, 40958 bytes\n\nFiles: package-lock.json (13322b), package.json (414b), scripts/_batch_test.js (1109b), scripts/_batch_test2.js (2550b), scripts/_bench.js (363b), scripts/_bench2.js (226b), scripts/_debug_baidu_box.js (1992b), scripts/_debug_baidu_pw.js (1519b), scripts/_debug_bing_cookie.js (2587b), scripts/_debug_bing_full.js (4731b), scripts/_debug_bing_pw.js (1458b), scripts/_debug_bing.js (1701b), scripts/_debug_bing2.js (3999b), scripts/_debug_bing3.js (1966b), scripts/_debug_cookie_combos.js (2786b), scripts/_debug_cookie_fetch.js (2159b), scripts/_debug_ddg.js (2682b), scripts/_debug_searchbox.js (1737b), scripts/_time_one.js (468b), scripts/browser-daemon.js (3062b), scripts/check-env.js (2651b), scripts/fetch.js (14963b), scripts/search.js (17787b), scripts/setup.sh (2152b), SKILL.md (5719b), _meta.json (137b)\n\nFile v1.0.0:SKILL.md\n\n# SKILL.md\n\n---\nname: free-web-search-js\ndescription: Playwright 联网搜索，自动抓取内容，零 API Key\nversion: 28.0.0\ntrigger_keywords:\n  - 搜索\n  - 查一下\n  - 找一下\n  - 最新消息\n  - 新闻\n  - 教程\n  - 是什么\n  - search\n  - find\ntools:\n  - name: search\n    description: 搜索+自动抓取，国内Bing Playwright，海外DDG HTTP\n    script: scripts/search.js\n    parameters:\n      query:\n        type: string\n        description: \"搜索关键词\"\n        required: true\n      max:\n        type: integer\n        description: \"最大结果数，默认10，上限30\"\n        required: false\n      region:\n        type: string\n        description: \"区域: auto/cn/intl，默认auto按IP检测\"\n        required: false\n  - name: fetch\n    description: 给定URL抓取正文，HTTP优先失败自动headed兜底\n    script: scripts/fetch.js\n    parameters:\n      urls:\n        type: string\n        description: \"要抓取的URL，多个用空格分隔\"\n        required: true\n      max-len:\n        type: integer\n        description: \"单页最大字符数，默认12000\"\n        required: false\n---\n\n# free-web-search-js\n\n一步式：**search** → Playwright 搜 → 自动抓内容 → 返回\n\n## 架构\n\n```\n国内：\n  Playwright 打开 Bing → 首页拿 cookie → 搜索框提交\n  → 自动抓取 top 3 页面内容\n  延迟：首次 3~6s（启动浏览器），后续复用更快\n\n海外：\n  纯 HTTP → DDG HTML 解析\n  → 自动抓取 top 3 页面内容\n  延迟：几百ms~1s\n```\n\n## 搜索引擎\n\n| 引擎 | 协议 | 区域 | 说明 |\n|------|------|------|------|\n| Bing CN | Playwright 搜索框提交 | 国内 | 先访问首页拿 cookie，再搜索框输入提交 |\n| 搜狗 | 纯 HTTP | 国内 | `--engine=sogou` 可选，⚠ 无 cookie 易被反爬拦截，结果不稳定 |\n| DDG HTML Lite | 纯 HTTP | 海外 | html.duckduckgo.com |\n\n### 策略\n\n| 区域 | 搜索 | 抓取 |\n|------|------|------|\n| 国内 | Bing CN (Playwright) | 自动抓前 3 条 |\n| 海外 | DDG HTML | 自动抓前 3 条 |\n\n### IP 怎么判断\n\n每次搜索时自动检测，三轮探测并行，谁先成功用谁：\n\n| 轮次 | 探测服务 | 逻辑 |\n|------|---------|------|\n| 第1轮 | `myip.ipip.net` / `cip.cc` | 国内可达优先 |\n| 第2轮 | `ipinfo.io` / `ipapi.co` | 国际探测 |\n| 第3轮 | 试连 `cn.bing.com` | 能通大概率国内 |\n| 兜底 | — | 默认国内 |\n\n出口 IP 走代理时可能误判，用 `--region=cn` 或 `--region=intl` 手动指定。\n\n## 去重\n\n智能去重：域名 + 路径主干（忽略 www/m 子域、tracking 参数、尾部斜杠、.html 后缀）。\n\nBing 跳转 URL（`bing.com/ck/`）自动解码为直链。\n\n## 抓取模式\n\n搜索后自动抓取 top N 条 URL 内容（默认 3 条）。\n\n| 层级 | 方式 | 速度 | 说明 |\n|------|------|------|------|\n| 第1层 | 轻量 HTTP + cheerio | ⚡ 秒出 | 不启动浏览器 |\n| 第2层 | Playwright headed | 🟡 慢 | 完整浏览器，支持 JS 渲染 |\n\n第1层增强：\n- **JSON API 响应**：自动检测 Content-Type 并提取结构化内容\n- **JSON-LD**：提取 `<script type=\"application/ld+json\">` 中的 articleBody/description\n- **__NEXT_DATA__**：提取 Next.js 嵌入数据\n- **meta 标签**：og:description / description 兜底\n- **GBK 编码**：自动检测并转换\n\n## 安装\n\n**前置依赖（全部必装）：**\n\n| 依赖 | 说明 | 大小/耗时 |\n|------|------|----------|\n| Node.js >= 18 | 运行时 | — |\n| cheerio | HTML 解析 | 小，秒装 |\n| commander | CLI 参数解析 | 小，秒装 |\n| iconv-lite | GBK 编码转换 | 小，秒装 |\n| playwright | 浏览器自动化（Bing 搜索 + 抓取兜底） | ~50MB |\n| Chromium | Playwright 专用浏览器 | **~150MB，需几分钟下载** |\n\n安装脚本自动检测网络区域，国内使用镜像源加速：\n\n```bash\n# Windows\npowershell -File scripts/setup.ps1\n\n# Linux/macOS\nbash scripts/setup.sh\n```\n\n国内镜像：\n- npm: `https://registry.npmmirror.com`\n- Playwright/Chromium: `https://npmmirror.com/mirrors/playwright`\n\n手动安装：\n```bash\ncd skills/free-web-search-js\nnpm install\nnpx playwright install chromium    # ~150MB，需几分钟\n```\n\n验证环境：`node scripts/check-env.js`\n\n卸载：`node scripts/uninstall.js`\n\n## 性能优化：浏览器守护进程\n\n搜索和抓取可复用浏览器守护进程，**提速约 70%**：\n\n```bash\nnode scripts/browser-daemon.js &       # 启动\nnode scripts/browser-daemon.js --status # 状态\nnode scripts/browser-daemon.js --stop   # 停止\n```\n\n守护进程空闲 10 分钟自动退出。\n\n## 用法\n\n```bash\n# 搜索（搜 + 自动抓前3条内容）\nnode scripts/search.js \"白银价格\"\nnode scripts/search.js \"how to deploy docker\" --max=5\nnode scripts/search.js \"xxx\" --region=cn\nnode scripts/search.js \"xxx\" --fetch=5          # 抓前5条\nnode scripts/search.js \"xxx\" --no-fetch         # 只搜不抓\n\n# 单独抓取（给定 URL）\nnode scripts/fetch.js \"https://example.com/page1\" \"https://example.com/page2\"\n```\n\n## 已知限制\n\n- **国内首次搜索较慢**：需启动 Chromium（3~6s），后续复用更快\n- **Bing CN 即时答案不返回**：天气、计算器等即时卡片不走 `li.b_algo`，搜索结果为 0\n- **搜狗 HTTP 不稳定**：无 cookie 纯请求易被反爬拦截，结果可能为空（`--engine=sogou` 慎用）\n- **部分站点 HTTP 抓不到**：需要 JS 渲染的页面——HTTP 失败会自动 headed 重试\n- **部分站点海外不可达**：国内专属站点从海外访问可能超时\n- **代理干扰 IP 检测**：出口 IP 走代理时可能误判区域，用 `--region=cn/intl` 手动指定\n- **海外引擎国内不可达**：DDG 在国内被墙，国内策略不使用\n\nFile v1.0.0:_meta.json\n\n{\n  \"ownerId\": \"kn7ecgbzbya89gesghbv1kty9d82r8e4\",\n  \"slug\": \"free-web-search-js\",\n  \"version\": \"1.0.0\",\n  \"publishedAt\": 1777102693589\n}\n\nFile v1.0.0:package-lock.json\n\n{\n  \"name\": \"free-web-search\",\n  \"version\": \"15.0.0\",\n  \"lockfileVersion\": 3,\n  \"requires\": true,\n  \"packages\": {\n    \"\": {\n      \"name\": \"free-web-search\",\n      \"version\": \"15.0.0\",\n      \"dependencies\": {\n        \"cheerio\": \"^1.0.0\",\n        \"commander\": \"^12.0.0\",\n        \"playwright\": \"^1.59.1\"\n      },\n      \"optionalDependencies\": {\n        \"playwright\": \"^1.59.1\"\n      }\n    },\n    \"node_modules/boolbase\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmmirror.com/boolbase/-/boolbase-1.0.0.tgz\",\n      \"integrity\": \"sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==\",\n      \"license\": \"ISC\"\n    },\n    \"node_modules/cheerio\": {\n      \"version\": \"1.2.0\",\n      \"resolved\": \"https://registry.npmmirror.com/cheerio/-/cheerio-1.2.0.tgz\",\n      \"integrity\": \"sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"cheerio-select\": \"^2.1.0\",\n        \"dom-serializer\": \"^2.0.0\",\n        \"domhandler\": \"^5.0.3\",\n        \"domutils\": \"^3.2.2\",\n        \"encoding-sniffer\": \"^0.2.1\",\n        \"htmlparser2\": \"^10.1.0\",\n        \"parse5\": \"^7.3.0\",\n        \"parse5-htmlparser2-tree-adapter\": \"^7.1.0\",\n        \"parse5-parser-stream\": \"^7.1.2\",\n        \"undici\": \"^7.19.0\",\n        \"whatwg-mimetype\": \"^4.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=20.18.1\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/cheeriojs/cheerio?sponsor=1\"\n      }\n    },\n    \"node_modules/cheerio-select\": {\n      \"version\": \"2.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/cheerio-select/-/cheerio-select-2.1.0.tgz\",\n      \"integrity\": \"sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==\",\n      \"license\": \"BSD-2-Clause\",\n      \"dependencies\": {\n        \"boolbase\": \"^1.0.0\",\n        \"css-select\": \"^5.1.0\",\n        \"css-what\": \"^6.1.0\",\n        \"domelementtype\": \"^2.3.0\",\n        \"domhandler\": \"^5.0.3\",\n        \"domutils\": \"^3.0.1\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/fb55\"\n      }\n    },\n    \"node_modules/commander\": {\n      \"version\": \"12.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/commander/-/commander-12.1.0.tgz\",\n      \"integrity\": \"sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/css-select\": {\n      \"version\": \"5.2.2\",\n      \"resolved\": \"https://registry.npmmirror.com/css-select/-/css-select-5.2.2.tgz\",\n      \"integrity\": \"sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==\",\n      \"license\": \"BSD-2-Clause\",\n      \"dependencies\": {\n        \"boolbase\": \"^1.0.0\",\n        \"css-what\": \"^6.1.0\",\n        \"domhandler\": \"^5.0.2\",\n        \"domutils\": \"^3.0.1\",\n        \"nth-check\": \"^2.0.1\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/fb55\"\n      }\n    },\n    \"node_modules/css-what\": {\n      \"version\": \"6.2.2\",\n      \"resolved\": \"https://registry.npmmirror.com/css-what/-/css-what-6.2.2.tgz\",\n      \"integrity\": \"sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==\",\n      \"license\": \"BSD-2-Clause\",\n      \"engines\": {\n        \"node\": \">= 6\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/fb55\"\n      }\n    },\n    \"node_modules/dom-serializer\": {\n      \"version\": \"2.0.0\",\n      \"resolved\": \"https://registry.npmmirror.com/dom-serializer/-/dom-serializer-2.0.0.tgz\",\n      \"integrity\": \"sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"domelementtype\": \"^2.3.0\",\n        \"domhandler\": \"^5.0.2\",\n        \"entities\": \"^4.2.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/cheeriojs/dom-serializer?sponsor=1\"\n      }\n    },\n    \"node_modules/domelementtype\": {\n      \"version\": \"2.3.0\",\n      \"resolved\": \"https://registry.npmmirror.com/domelementtype/-/domelementtype-2.3.0.tgz\",\n      \"integrity\": \"sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==\",\n      \"funding\": [\n        {\n          \"type\": \"github\",\n          \"url\": \"https://github.com/sponsors/fb55\"\n        }\n      ],\n      \"license\": \"BSD-2-Clause\"\n    },\n    \"node_modules/domhandler\": {\n      \"version\": \"5.0.3\",\n      \"resolved\": \"https://registry.npmmirror.com/domhandler/-/domhandler-5.0.3.tgz\",\n      \"integrity\": \"sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==\",\n      \"license\": \"BSD-2-Clause\",\n      \"dependencies\": {\n        \"domelementtype\": \"^2.3.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 4\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/fb55/domhandler?sponsor=1\"\n      }\n    },\n    \"node_modules/domutils\": {\n      \"version\": \"3.2.2\",\n      \"resolved\": \"https://registry.npmmirror.com/domutils/-/domutils-3.2.2.tgz\",\n      \"integrity\": \"sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==\",\n      \"license\": \"BSD-2-Clause\",\n      \"dependencies\": {\n        \"dom-serializer\": \"^2.0.0\",\n        \"domelementtype\": \"^2.3.0\",\n        \"domhandler\": \"^5.0.3\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/fb55/domutils?sponsor=1\"\n      }\n    },\n    \"node_modules/encoding-sniffer\": {\n      \"version\": \"0.2.1\",\n      \"resolved\": \"https://registry.npmmirror.com/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz\",\n      \"integrity\": \"sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"iconv-lite\": \"^0.6.3\",\n        \"whatwg-encoding\": \"^3.1.1\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/fb55/encoding-sniffer?sponsor=1\"\n      }\n    },\n    \"node_modules/entities\": {\n      \"version\": \"4.5.0\",\n      \"resolved\": \"https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz\",\n      \"integrity\": \"sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==\",\n      \"license\": \"BSD-2-Clause\",\n      \"engines\": {\n        \"node\": \">=0.12\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/fb55/entities?sponsor=1\"\n      }\n    },\n    \"node_modules/fsevents\": {\n      \"version\": \"2.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/fsevents/-/fsevents-2.3.2.tgz\",\n      \"integrity\": \"sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==\",\n      \"hasInstallScript\": true,\n      \"license\": \"MIT\",\n      \"optional\": true,\n      \"os\": [\n        \"darwin\"\n      ],\n      \"engines\": {\n        \"node\": \"^8.16.0 || ^10.6.0 || >=11.0.0\"\n      }\n    },\n    \"node_modules/htmlparser2\": {\n      \"version\": \"10.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/htmlparser2/-/htmlparser2-10.1.0.tgz\",\n      \"integrity\": \"sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==\",\n      \"funding\": [\n        \"https://github.com/fb55/htmlparser2?sponsor=1\",\n        {\n          \"type\": \"github\",\n          \"url\": \"https://github.com/sponsors/fb55\"\n        }\n      ],\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"domelementtype\": \"^2.3.0\",\n        \"domhandler\": \"^5.0.3\",\n        \"domutils\": \"^3.2.2\",\n        \"entities\": \"^7.0.1\"\n      }\n    },\n    \"node_modules/htmlparser2/node_modules/entities\": {\n      \"version\": \"7.0.1\",\n      \"resolved\": \"https://registry.npmmirror.com/entities/-/entities-7.0.1.tgz\",\n      \"integrity\": \"sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==\",\n      \"license\": \"BSD-2-Clause\",\n      \"engines\": {\n        \"node\": \">=0.12\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/fb55/entities?sponsor=1\"\n      }\n    },\n    \"node_modules/iconv-lite\": {\n      \"version\": \"0.6.3\",\n      \"resolved\": \"https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.6.3.tgz\",\n      \"integrity\": \"sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"safer-buffer\": \">= 2.1.2 < 3.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=0.10.0\"\n      }\n    },\n    \"node_modules/nth-check\": {\n      \"version\": \"2.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/nth-check/-/nth-check-2.1.1.tgz\",\n      \"integrity\": \"sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==\",\n      \"license\": \"BSD-2-Clause\",\n      \"dependencies\": {\n        \"boolbase\": \"^1.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/fb55/nth-check?sponsor=1\"\n      }\n    },\n    \"node_modules/parse5\": {\n      \"version\": \"7.3.0\",\n      \"resolved\": \"https://registry.npmmirror.com/parse5/-/parse5-7.3.0.tgz\",\n      \"integrity\": \"sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"entities\": \"^6.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/inikulin/parse5?sponsor=1\"\n      }\n    },\n    \"node_modules/parse5-htmlparser2-tree-adapter\": {\n      \"version\": \"7.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz\",\n      \"integrity\": \"sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"domhandler\": \"^5.0.3\",\n        \"parse5\": \"^7.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/inikulin/parse5?sponsor=1\"\n      }\n    },\n    \"node_modules/parse5-parser-stream\": {\n      \"version\": \"7.1.2\",\n      \"resolved\": \"https://registry.npmmirror.com/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz\",\n      \"integrity\": \"sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"parse5\": \"^7.0.0\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/inikulin/parse5?sponsor=1\"\n      }\n    },\n    \"node_modules/parse5/node_modules/entities\": {\n      \"version\": \"6.0.1\",\n      \"resolved\": \"https://registry.npmmirror.com/entities/-/entities-6.0.1.tgz\",\n      \"integrity\": \"sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==\",\n      \"license\": \"BSD-2-Clause\",\n      \"engines\": {\n        \"node\": \">=0.12\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/fb55/entities?sponsor=1\"\n      }\n    },\n    \"node_modules/playwright\": {\n      \"version\": \"1.59.1\",\n      \"resolved\": \"https://registry.npmmirror.com/playwright/-/playwright-1.59.1.tgz\",\n      \"integrity\": \"sha512-C8oWjPR3F81yljW9o5OxcWzfh6avkVwDD2VYdwIGqTkl+OGFISgypqzfu7dOe4QNLL2aqcWBmI3PMtLIK233lw==\",\n      \"license\": \"Apache-2.0\",\n      \"optional\": true,\n      \"dependencies\": {\n        \"playwright-core\": \"1.59.1\"\n      },\n      \"bin\": {\n        \"playwright\": \"cli.js\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      },\n      \"optionalDependencies\": {\n        \"fsevents\": \"2.3.2\"\n      }\n    },\n    \"node_modules/playwright-core\": {\n      \"version\": \"1.59.1\",\n      \"resolved\": \"https://registry.npmmirror.com/playwright-core/-/playwright-core-1.59.1.tgz\",\n      \"integrity\": \"sha512-HBV/RJg81z5BiiZ9yPzIiClYV/QMsDCKUyogwH9p3MCP6IYjUFu/MActgYAvK0oWyV9NlwM3GLBjADyWgydVyg==\",\n      \"license\": \"Apache-2.0\",\n      \"optional\": true,\n      \"bin\": {\n        \"playwright-core\": \"cli.js\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/safer-buffer\": {\n      \"version\": \"2.1.2\",\n      \"resolved\": \"https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz\",\n      \"integrity\": \"sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==\",\n      \"license\": \"MIT\"\n    },\n    \"node_modules/undici\": {\n      \"version\": \"7.25.0\",\n      \"resolved\": \"https://registry.npmmirror.com/undici/-/undici-7.25.0.tgz\",\n      \"integrity\": \"sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">=20.18.1\"\n      }\n    },\n    \"node_modules/whatwg-encoding\": {\n      \"version\": \"3.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz\",\n      \"integrity\": \"sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==\",\n      \"deprecated\": \"Use @exodus/bytes instead for a more spec-conformant and faster implementation\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"iconv-lite\": \"0.6.3\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/whatwg-mimetype\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmmirror.com/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz\",\n      \"integrity\": \"sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    }\n  }\n}\n\nFile v1.0.0:package.json\n\n{\n  \"name\": \"free-web-search-js\",\n  \"version\": \"28.0.0\",\n  \"type\": \"module\",\n  \"description\": \"Playwright 联网搜索，国内Bing/搜狗，海外DDG，自动抓取，零 API Key\",\n  \"scripts\": {\n    \"search\": \"node scripts/search.js\",\n    \"fetch\": \"node scripts/fetch.js\"\n  },\n  \"dependencies\": {\n    \"cheerio\": \"^1.0.0\",\n    \"commander\": \"^12.0.0\",\n    \"iconv-lite\": \"^0.6.3\",\n    \"playwright\": \"^1.52.0\"\n  }\n}","readmeExcerpt":"Skill: Free Web Search Js Owner: ucsdzehualiu Summary: Web search & content fetching via Playwright + HTTP — zero API keys. Searches Bing CN (domestic) or DDG (international), auto-fetches top page contents. For... Tags: latest:29.1.0 Version history: v29.1.0 | 2026-06-22T07:29:35.102Z | user v29.1.0: Add LICENSE, fix playwright dep check, align metadata (version/author), remove dead engine docs, delete stale TEST_RE","codeSnippets":[],"executableExamples":[{"language":"bash","snippet":"# Search (auto-fetches top 3 page contents)\nnode scripts/search.js \"silver price\"\nnode scripts/search.js \"how to deploy docker\" --max=5\nnode scripts/search.js \"xxx\" --region=cn\nnode scripts/search.js \"xxx\" --fetch=5         # fetch top 5\nnode scripts/search.js \"xxx\" --no-fetch        # search only\n\n# Fetch specific URLs\nnode scripts/fetch.js \"https://example.com/page1\" \"https://example.com/page2\""},{"language":"text","snippet":"Domestic (CN IP):\n  Playwright headless → Bing CN → home page for cookie → search box submit\n  → 0 results? fallback to DDG HTML\n  → auto-fetch top N page contents\n\nInternational:\n  Pure HTTP → DDG HTML parse\n  → fetch fails? fallback to Playwright request\n  → DDG empty? fallback to Bing\n  → auto-fetch top N page contents"},{"language":"bash","snippet":"# Linux / macOS\nbash scripts/setup.sh\n\n# Windows\npowershell -File scripts/setup.ps1"},{"language":"bash","snippet":"cd skills/free-web-search-js\nnpm install\nnpx playwright install chromium    # ~150 MB\n\n# Verify\nnode scripts/check-env.js"},{"language":"bash","snippet":"export CHROMIUM_EXECUTABLE_PATH=\"/path/to/chrome\"\nnode scripts/check-env.js"},{"language":"bash","snippet":"node scripts/browser-daemon.js            # Start (run with & or as background job)\nnode scripts/browser-daemon.js --status   # Show status\nnode scripts/browser-daemon.js --stop     # Stop"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: free-web-search-js\ndescription: Web search & content fetching via Playwright + HTTP — zero API keys. Searches Bing CN (domestic) or DDG (international), auto-fetches top page contents. For real-time search, fact-checking, news, tutorials, documentation lookup.\nversion: 29.1.0\nlicense: MIT\nauthor: free-web-search-js\ntrigger_keywords:\n  - search\n  - find\n  - look up\n  - 搜索\n  - 查一下\n  - 找一下\ntools:\n  - name: search\n    description: Search + auto-fetch; Bing CN via Playwright, DDG via HTTP\n    script: scripts/search.js\n    parameters:\n      query:\n        type: string\n        description: \"Search query\"\n        required: true\n      max:\n        type: integer\n        description: \"Max results 1-30, default 10\"\n        required: false\n      region:\n        type: string\n        description: \"Region: auto/cn/intl, defaults to auto (IP detection)\"\n        required: false\n  - name: fetch\n    description: Fetch page content by URL, HTTP first with headed fallback\n    script: scripts/fetch.js\n    parameters:\n      urls:\n        type: string\n        description: \"URLs to fetch, space-separated\"\n        required: true\n      max-len:\n        type: integer\n        description: \"Max chars per page, default 12000\"\n        required: false\n---\n\n# free-web-search-js\n\nPure 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.\n\n## Quick start\n\n```bash\n# Search (auto-fetches top 3 page contents)\nnode scripts/search.js \"silver price\"\nnode scripts/search.js \"how to deploy docker\" --max=5\nnode scripts/search.js \"xxx\" --region=cn\nnode scripts/search.js \"xxx\" --fetch=5         # fetch top 5\nnode scripts/search.js \"xxx\" --no-fetch        # search only\n\n# Fetch specific URLs\nnode scripts/fetch.js \"https://example.com/page1\" \"https://example.com/page2\"\n```\n\n## Architecture\n\n```\nDomestic (CN IP):\n  Playwright headless → Bing CN → home page for cookie → search box submit\n  → 0 results? fallback to DDG HTML\n  → auto-fetch top N page contents\n\nInternational:\n  Pure HTTP → DDG HTML parse\n  → fetch fails? fallback to Playwright request\n  → DDG empty? fallback to Bing\n  → auto-fetch top N page contents\n```\n\n## Install\n\nAll 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.\n\n### Prerequisites\n\n| Dependency | Purpose | Size |\n|---|---|---|\n| Node.js >= 18 | Runtime | — |\n| cheerio | HTML parsing | small |\n| commander | CLI arg parsing | small |\n| iconv-lite | GBK charset conversion | small |\n| playwright | Browser automation | ~50 MB |\n| Chromium (Playwright) | Browser engine for Bing search + headed fetch | ~150 MB |\n\n### One-command setup\n\n```bash\n# Linux / macOS\nbash scripts/setup.sh\n\n# Windows\npowershell -File scripts/setup.ps1\n```\n\nThe scripts auto-detect region and use `npmmirror.com` mirrors inside China for faste"},{"path":"README.md","content":"# free-web-search-js\n\n## 项目简介\n\nfree-web-search-js 是一个基于 Playwright和JS写 的免费网络搜索skill 可用于CC或者openclaw（clawhub install free-web-search-js），无需 API Key，支持国内和海外搜索，自动抓取搜索结果内容。\n\n**Pure search — no rewriting, no filtering.** 噪音交给 AI 处理。使用真实浏览器（Playwright）处理 Bing CN 反爬，国际查询则使用 HTTP 加速。\n\n- **免费**：零成本使用，无需 API Key\n- **稳定**：根据网络环境自动切换搜索策略，提高可达性\n- **快速**：首次搜索 3\\~6 秒，后续复用浏览器更快\n- **自动抓取**：搜索后自动抓取 top N 条结果内容\n- **跨区域**：国内使用 Bing，海外使用 DDG\n\n## 支持的搜索引擎\n\n| 引擎       | 协议               | 区域 | 说明                                          |\n| -------- | ---------------- | -- | ------------------------------------------- |\n| Bing CN  | Playwright 搜索框提交 | 国内 | 先访问首页拿 cookie，再搜索框输入提交                      |\n| DDG | Playwright 搜索框提交 | 海外 | 完整浏览器自动化                         |\n\n## 安装\n\n### 前置依赖\n\n| 依赖            | 说明                     | 大小/耗时              |\n| ------------- | ---------------------- | ------------------ |\n| Node.js >= 18 | 运行时                    | —                  |\n| cheerio       | HTML 解析                | 小，秒装               |\n| commander     | CLI 参数解析               | 小，秒装               |\n| iconv-lite    | GBK 编码转换               | 小，秒装               |\n| playwright    | 浏览器自动化（Bing 搜索 + 抓取兜底） | \\~50MB             |\n| Chromium      | Playwright 专用浏览器       | **\\~150MB，需几分钟下载** |\n\n### 安装步骤\n\n#### 一键安装\n\n```bash\n# Linux/macOS\nbash scripts/setup.sh\n\n# Windows\npowershell -File scripts/setup.ps1\n```\n\n#### 手动安装\n\n```bash\n# 进入项目目录\ncd free-web-search-js\n\n# 安装依赖\nnpm install\n\n# 安装 Playwright 浏览器\nnpx playwright install chromium    # ~150MB，需几分钟\n```\n\n### 国内镜像加速\n\n```bash\n# npm 镜像\nnpm install --registry=https://registry.npmmirror.com\n\n# Playwright/Chromium 镜像\nPLAYWRIGHT_DOWNLOAD_HOST=https://npmmirror.com/mirrors/playwright npx playwright install chromium\n```\n\n### 验证环境\n\n```bash\nnode scripts/check-env.js\n```\n\n## 用法\n\n### 搜索（搜 + 自动抓内容）\n\n```bash\n# 基本搜索\nnode scripts/search.js \"白银价格\"\n\n# 控制结果数量\nnode scripts/search.js \"how to deploy docker\" --max=5\n\n# 指定区域\nnode scripts/search.js \"xxx\" --region=cn\n\n# 控制抓取数量\nnode scripts/search.js \"xxx\" --fetch=5          # 抓前5条\n\n# 只搜索不抓取\nnode scripts/search.js \"xxx\" --no-fetch\n\n# 控制单页最大字符数\nnode scripts/search.js \"xxx\" --max-len=8000\n```\n\n### 单独抓取（给定 URL）\n\n```bash\nnode scripts/fetch.js \"https://example.com/page1\" \"https://example.com/page2\"\n```\n\n## 性能优化：浏览器守护进程\n\n搜索和抓取可复用浏览器守护进程，**提速约 70%**：\n\n```bash\nnode scripts/browser-daemon.js &       # 启动\nnode scripts/browser-daemon.js --status # 状态\nnode scripts/browser-daemon.js --stop   # 停止\n```\n\n守护进程空闲 10 分钟自动退出。\n\n## 架构\n\n### 国内搜索流程\n\n```\nPlaywright 打开 Bing → 首页拿 cookie → 搜索框提交 → 自动抓取 top N 页面内容\n延迟：首次 3~6s（启动浏览器），后续复用更快\n```\n\n### 海外搜索流程\n\n```\n纯 HTTP → DDG HTML 解析 → 自动抓取 top N 页面内容\n延迟：几百ms~1s\n```\n\n### 抓取模式\n\n| 层级  | 方式                | 速度   | 说明             |\n| --- | ----------------- | ---- | -------------- |\n| 第1层 | 轻量 HTTP + cheerio | ⚡ 秒出 | 不启动浏览器         |\n| 第2层 | Playwright headed | 🟡 慢 | 完整浏览器，支持 JS 渲染 |\n\n## 区域检测\n\n每次搜索时自动检测，三轮探测并行，谁先成功用谁：\n\n| 轮次  | 探测服务                       | 逻辑      |\n| --- | -------------------"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn7ecgbzbya89gesghbv1kty9d82r8e4\",\n  \"slug\": \"free-web-search-js\",\n  \"version\": \"29.1.0\",\n  \"publishedAt\": 1782113375102\n}"},{"path":"skill-card.md","content":"## Description:\n\nFree Web Search Js searches the web with Playwright and HTTP, using Bing CN or DuckDuckGo and optionally fetching page content without API keys.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[ucsdzehualiu](https://clawhub.ai/user/ucsdzehualiu)\n\n### License/Terms of Use:\n\nMIT\n\n## Use Case:\n\nDevelopers and agents use this skill to look up current web information, fact-check claims, find documentation or tutorials, and fetch page text for downstream reasoning.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill can fetch arbitrary HTTP URLs from the agent runtime, which can expose internal, localhost, cloud metadata, or private-network endpoints if misused.\n\nMitigation: Use it in an isolated environment with restricted network access, avoid sensitive URLs, and prefer explicit --region plus --no-fetch when privacy matters.\n\nRisk: The skill may run untrusted pages in Chromium while default browser launch flags disable the browser sandbox.\n\nMitigation: Update Playwright before sensitive use and remove the default no-sandbox browser flags on hosts where browser isolation matters.\n\nRisk: Queries, fetched URLs, and page requests are sent directly to search engines and target websites from the runtime.\n\nMitigation: Do not submit confidential queries or URLs, and review fetched content before relying on it in downstream decisions.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/ucsdzehualiu/skills/free-web-search-js)\n- [ClawHub publisher profile](https://clawhub.ai/user/ucsdzehualiu)\n- [Node.js](https://nodejs.org)\n\n## Skill Output:\n\n**Output Type(s):** [text, json]\n\n**Output Format:** [JSON containing search results, URLs, snippets, and fetched page text.]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Result count and per-page content length are configurable; search may auto-fetch top results unless disabled.]\n\n## Skill Version(s):\n\n29.1.0 (source: frontmatter, package.json, 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."},{"path":"package-lock.json","content":"{\n  \"name\": \"free-web-search-js\",\n  \"version\": \"28.1.0\",\n  \"lockfileVersion\": 3,\n  \"requires\": true,\n  \"packages\": {\n    \"\": {\n      \"name\": \"free-web-search-js\",\n      \"version\": \"28.1.0\",\n      \"dependencies\": {\n        \"cheerio\": \"~1.0.0\",\n        \"commander\": \"~12.1.0\",\n        \"iconv-lite\": \"~0.6.3\",\n        \"playwright\": \"~1.52.0\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/boolbase\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmmirror.com/boolbase/-/boolbase-1.0.0.tgz\",\n      \"integrity\": \"sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==\",\n      \"license\": \"ISC\"\n    },\n    \"node_modules/cheerio\": {\n      \"version\": \"1.0.0\",\n      \"resolved\": \"https://registry.npmmirror.com/cheerio/-/cheerio-1.0.0.tgz\",\n      \"integrity\": \"sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==\",\n      \"license\": \"MIT\",\n      \"dependencies\": {\n        \"cheerio-select\": \"^2.1.0\",\n        \"dom-serializer\": \"^2.0.0\",\n        \"domhandler\": \"^5.0.3\",\n        \"domutils\": \"^3.1.0\",\n        \"encoding-sniffer\": \"^0.2.0\",\n        \"htmlparser2\": \"^9.1.0\",\n        \"parse5\": \"^7.1.2\",\n        \"parse5-htmlparser2-tree-adapter\": \"^7.0.0\",\n        \"parse5-parser-stream\": \"^7.1.2\",\n        \"undici\": \"^6.19.5\",\n        \"whatwg-mimetype\": \"^4.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=18.17\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/cheeriojs/cheerio?sponsor=1\"\n      }\n    },\n    \"node_modules/cheerio-select\": {\n      \"version\": \"2.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/cheerio-select/-/cheerio-select-2.1.0.tgz\",\n      \"integrity\": \"sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==\",\n      \"license\": \"BSD-2-Clause\",\n      \"dependencies\": {\n        \"boolbase\": \"^1.0.0\",\n        \"css-select\": \"^5.1.0\",\n        \"css-what\": \"^6.1.0\",\n        \"domelementtype\": \"^2.3.0\",\n        \"domhandler\": \"^5.0.3\",\n        \"domutils\": \"^3.0.1\"\n      },\n      \"funding\": {\n        \"url\": \"https://github.com/sponsors/fb55\"\n      }\n    },\n    \"node_modules/commander\": {\n      \"version\": \"12.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/commander/-/commander-12.1.0.tgz\",\n      \"integrity\": \"sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==\",\n      \"license\": \"MIT\",\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/css-select\": {\n      \"version\": \"5.2.2\",\n      \"resolved\": \"https://registry.npmmirror.com/css-select/-/css-select-5.2.2.tgz\",\n      \"integrity\": \"sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==\",\n      \"license\": \"BSD-2-Clause\",\n      \"dependencies\": {\n        \"boolbase\": \"^1.0.0\",\n        \"css-what\": \"^6.1.0\",\n        \"domhandler\": \"^5.0.2\",\n        \"domutils\": \"^3.0.1\",\n        \"nth-check\": \"^2.0.1\"\n      },\n      \"funding"}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":"Web search & content fetching via Playwright + HTTP — zero API keys. Searches Bing CN (domestic) or DDG (international), auto-fetches top page contents. For... Skill: Free Web Search Js Owner: ucsdzehualiu Summary: Web search & content fetching via Playwright + HTTP — zero API keys. Searches Bing CN (domestic) or DDG (international), auto-fetches top page contents. For... Tags: latest:29.1.0 Version history: v29.1.0 | 2026-06-22T07:29:35.102Z | user v29.1.0: Add LICENSE, fix playwright dep check, align metadata (version/author), remove dead engine docs, delete stale TEST_RE","editorialQuality":{"score":100,"threshold":65,"status":"ready","wordCount":1618,"uniquenessScore":47,"reasons":[]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-11T00:31:55.962Z","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-11T00:31:55.962Z","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-11T03:56:40.684Z","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"}]}}}