OpenCLI Yahoo Search 适配器实战:把 Yahoo(Bing 驱动)搜索结果变成可脚本化的 CLI 命令
【免费下载链接】OpenCLIMake Any Website into CLI & Use your logged-in browser by AI agent.项目地址: https://gitcode.com/gh_mirrors/ope/OpenCLI
本篇指南聚焦 OpenCLI 仓库中的 Yahoo Search 适配器(对应文档 docs/adapters/browser/yahoo.md),讲解如何通过opencli yahoo search命令在浏览器会话中完成 Yahoo 搜索、结果提取与分页输出,并深入到 search.js 源码层剖析其 DOM 提取、RU=重定向 URL 解码与参数校验的实现细节。读完本文,你将掌握该命令的完整参数体系、浏览器模式前置条件、JSON 等机器友好输出方式,以及它当前的能力边界。
命令概览
Yahoo 适配器是一个公开(Public)模式的浏览器命令,托管域名为search.yahoo.com。当前仓库只注册了一个命令:
| 命令 | 说明 |
|---|---|
opencli yahoo search <keyword> | 搜索 Yahoo(由 Bing 提供搜索能力),并从页面中提取排名结果 |
该命令以只读(access: 'read')方式访问 Yahoo,不涉及任何写操作,符合"把任意网站变成确定性 CLI"的设计理念——同一命令、同一输出结构,可管道化、可脚本化、可接入 CI。适配器的命令注册信息可以在 clis/yahoo/search.js 中看到,其strategy为Strategy.PUBLIC、browser为true,输出列固定为rank / title / url / snippet四列。
前置条件:浏览器模式与 Browser Bridge
Yahoo 搜索结果依赖浏览器渲染,因此该命令必须运行在浏览器模式下。根据 docs/guide/browser-bridge.md 的说明,OpenCLI 通过"Browser Bridge Chrome 扩展 + 微守护进程"连接你的 Chrome:
- Standalone 模式:需要本地有 Chrome 正在运行,Standalone 模式会自动启动浏览器会话;
- Browser Bridge 扩展模式:安装扩展后复用 Chrome 的登录态,命令运行前请确保已在 Chrome 中完成目标网站的登录。
连接链路为opencli (Node.js) ←WebSocket:localhost:19825→ micro-daemon ←Chrome API→ Chrome Browser,守护进程在首次浏览器命令时自动启动,并持续常驻。可用opencli doctor校验扩展与守护进程的连通性,用opencli daemon stop优雅关闭。由于 Yahoo 命令复用浏览器会话,结果中的地域/语言偏好会受浏览器会话当前区域设置影响。
参数详解:keyword、limit 与 page
opencli yahoo search支持三个参数,其声明位于 clis/yahoo/search.js:
| 参数 | 类型 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|
keyword | 位置参数(必填) | — | 非空字符串 | 搜索关键词,源码会先经requireSearchQuery去除首尾空白并拒绝空串 |
--limit | int | 7 | 1 ~ 7 | 每页返回的结果条数;Yahoo 每页约 7 条结果,因此上限为 7 |
--page | int | 1 | 1 ~ 100 | 页码,第 2 页起通过&b=偏移参数翻页 |
参数在发起导航之前就会完成校验:requireBoundedInteger(实现在 clis/_shared/search-adapter.js)要求--limit必须是 1~7 的整数、--page必须是 1~100 的正整数;keyword为空会抛出ARGUMENT类型错误,并且不会触发任何页面导航——这是共享搜索适配器层的通用行为,保证无效输入零副作用。
使用示例
原文档给出的四个典型用法如下,全部可直接运行:
# 基础搜索 opencli yahoo search "machine learning" # 限制结果条数 opencli yahoo search "machine learning" --limit 5 # 翻页(第二页) opencli yahoo search "machine learning" --page 2 # JSON 输出 opencli yahoo search "machine learning" -f json在此基础上,结合 OpenCLI 全局输出格式约定(见 docs/guide/getting-started.md),你还可以这样组合:
# 默认表格输出(富终端表格) opencli yahoo search "opencli" -f table # YAML,适合人读 opencli yahoo search "opencli" -f yaml # Markdown,直接嵌入文档 opencli yahoo search "opencli" -f md # CSV,导入表格工具 opencli yahoo search "opencli" -f csv # 管道给 jq 做二次加工 opencli yahoo search "opencli" -f json | jq '.[] | {title, url}'所有内置命令均支持-f/--format,其中-f json是接入 LLM 与自动化流水线最常用的形态:JSON 结构直接保留了rank / title / url / snippet四个字段,字段名与命令声明的输出列一一对应。
源码级原理:结果如何被提取
DOM 提取与去重
导航完成后,适配器向页面注入一段提取脚本(buildExtractorJs,见 clis/yahoo/search.js),其逻辑为:
- 用
document.querySelectorAll('.algo')选中 Yahoo 结果卡片节点; - 对每个卡片依次读取
h3(标题)、.compTitle a(链接)、.compText(摘要); - 通过
seen对象对 href 去重,保证同一条结果只出现一次; - 达到
limit上限后立即break,避免提取多余节点。
提取结果以[title, href, snippet]三元组数组的形式返回。从源码结构看,.algo、.compTitle、.compText这些选择器直接依赖 Yahoo 当前的 DOM 结构,若 Yahoo 改版可能影响提取稳定性。
RU= 重定向 URL 解码
Yahoo 会把搜索结果包装在https://r.search.yahoo.com/.../RU=<url>/RK=.../RS=...形式的重定向链接中。适配器通过decodeYahooUrl(clis/yahoo/search.js)自动解码:
- 检测 href 中是否同时包含
RU=与/RK=; - 用正则
RU=([^/]+)\/RK=捕获真实目标 URL,并做decodeURIComponent解码; - 用
toHttpsUrl(clis/_shared/search-adapter.js)以https://search.yahoo.com为基准解析,并只放行 http/https 协议——例如RU=javascript:alert(1)这类非 Web 协议目标会被过滤掉,防止输出恶意链接。
分页与排名计算
分页通过 Yahoo 的b偏移参数实现(clis/yahoo/search.js):第 N 页使用&b=(N-1)*7+1。每条结果的rank按index + 1 + (pageNum - 1) * 7计算,因此第 2 页第一条结果的 rank 为 8,与 Yahoo 实际排名连续衔接。
等待与错误处理
导航后适配器会等待.algo选择器出现(超时 10 秒),超时则额外等待 3 秒兜底再尝试提取;提取结果必须是以数组形式出现的 payload(requireRows会拒绝形如{ rows: [] }的畸形结构并抛出COMMAND_EXEC类型错误);若最终没有任何有效结果,则抛出EMPTY_RESULT(emptySearchResults),而不会静默返回空数组。
测试覆盖:边界行为有据可依
仓库为 Yahoo 适配器提供了完整的单元测试 clis/yahoo/search.test.js,用 mock 页面对象验证了以下关键行为:
- 命令注册信息正确(
site: 'yahoo'、browser: true、strategy: 'public'、四列输出); - 空关键词、
--limit 8、--page 0均在导航前被拒绝(ARGUMENT),且page.goto不被调用; - 对
RU=https%3A%2F%2Fgithub.com%2Fjackwener%2FOpenCLI/RK=...形式的重定向 URL 能正确解码出真实地址,并正确计算第 2 页 rank=8; RU=javascript:alert(1)这类危险目标会被过滤,最终因无有效结果抛出EMPTY_RESULT;- 畸形提取 payload(
{ rows: [] })会以COMMAND_EXEC类型错误失败,而非静默返回[]。
这些测试印证了"typed error 优于静默失败"的工程约定,也说明你可以在不依赖真实网络的情况下,把该适配器当作可组合的command.func(page, kwargs)单元来使用。
当前限制与注意事项
原文档明确列出的限制如下,使用时需要留意:
- 必须浏览器模式:无法在纯 API(非浏览器)模式下运行;
- 每页结果少:Yahoo 每页约 7 条,远少于其他搜索引擎,需要更多结果时请配合
--page翻页; - 后续页质量:第 2 页及之后可能出现低相关度或不那么匹配的结果;
- URL 重定向:Yahoo 用
RU=.../RK=包装链接,适配器已自动解码,无需手动处理; - 地域/语言过滤未暴露:当前没有独立的 region/language 参数,结果受浏览器会话的区域与语言设置影响。
另外补充两点来自源码的事实:Yahoo 搜索结果由 Bing 提供,结果在初始 HTML 中服务端渲染完成,这正是 DOM 提取可行的基础;--page上限为 100,超过该值会直接报参数错误。
小结
opencli yahoo search是 OpenCLI 浏览器类适配器的一个典型样本:公开策略 + 浏览器渲染 + DOM 提取 + 参数严格校验 + 类型化错误。无论是把它接入搜索聚合脚本、喂给 AI Agent 做信息采集,还是作为学习"如何写一个搜索适配器"的参考实现,都可以从 clis/yahoo/search.js 及其测试 clis/yahoo/search.test.js 中找到完整的答案。若需要从远程机器驱动本地浏览器会话,可参考 Remote Orchestration 的 SSH 反向隧道方案。
【免费下载链接】OpenCLIMake Any Website into CLI & Use your logged-in browser by AI agent.项目地址: https://gitcode.com/gh_mirrors/ope/OpenCLI
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考