qiaomu-opencli-browser について
qiaomu-opencli-browser は、OpenCLI コマンドラインから Chrome を操作する AI エージェント向けブラウザー自動化スキルです。ページ構造の確認、要素操作、ネットワーク API の検出に加え、操作内容を再利用可能な CLI アダプターにできます。
主な機能
- 01コマンドラインからの Chrome 操作
- 02構造化 DOM の確認
- 03ページ操作とデータ抽出
- 04ネットワーク API の検出
- 05再利用可能な CLI アダプター作成
活用シーン
- 01ブラウザー上のワークフロー自動化
- 02Web ページからのデータ抽出
- 03API の調査と CLI アダプター作成
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ joeseesun/ qiaomu-opencli-skills --skill qiaomu-opencli-browserインストール後、Claude Code で/qiaomu-opencli-browserを入力して読み込まれたか確認します。
詳細
OpenCLI Browser — AI エージェント向けブラウザー自動化
CLI から Chrome をステップごとに操作します。既存のログインセッションを再利用するため、パスワードは不要です。
前提条件
opencli doctor # Verify extension + daemon connectivity
必要なもの:Chrome が起動していること、および OpenCLI Browser Bridge 拡張機能がインストールされていること。
重要なルール
- ページの確認には必ず
stateを使い、screenshotは絶対に使わないでください —stateは[N]の要素インデックスを含む構造化 DOM を返し、瞬時に実行でき、トークンを消費しません。screenshotは画像処理が必要なため、時間がかかります。ユーザーから画像を保存するよう明示的に依頼された場合にのみ、screenshotを使ってください。 - 操作には必ず
click/type/selectを使い、クリックや入力にevalは絶対に使わないでください —eval "el.click()"はscrollIntoViewと CDP のクリック処理を迂回するため、画面外の要素では失敗します。stateで[N]インデックスを確認してから、click <N>を実行してください。 - スクリーンショットではなく
get valueで入力内容を確認してください —typeの後にget value <index>を実行して確認します。 - ページが変わるたびに
stateを実行してください —open、リンクをクリックするclick、scrollの後は、必ずstateを実行して、新しい要素とそのインデックスを確認してください。インデックスを推測しないでください。 - コマンドは積極的に
&&で連結してください —open + state、複数のtype呼び出し、type + get valueを単一の&&チェーンにまとめます。ツール呼び出しにはオーバーヘッドがあるため、連結すれば削減できます。 evalは読み取り専用です —evalはデータ抽出(JSON.stringify(...))にのみ使い、クリック、入力、移動には使わないでください。変数の競合を避けるため、常に IIFE で囲みます:eval "(function(){ const x = ...; return JSON.stringify(x); })()"。- ツール呼び出しの総数を最小限にしてください — 操作する前に手順を計画します。タスクの完了には、15~20 回ではなく、3~5 回のツール呼び出しを目指してください。
open + stateは 1 回の呼び出しにまとめます。type + type + clickも 1 回の呼び出しにまとめます。新しいインデックスを確認する必要がある場合にのみ、stateを個別に実行してください。 - API の検出には
networkを優先してください — ほとんどのサイトには JSON API があります。API ベースのアダプターは DOM スクレイピングより信頼性が高いです。
コマンドのコストガイド
| コスト | コマンド | 使用する場面 |
|---|---|---|
| 無料かつ瞬時 | state、get *、eval、network、scroll、keys | デフォルト — これらを使用 |
| 無料だがページが変わる | open、click、type、select、back | 操作 — 後に state を実行 |
| 高コスト(画像処理トークン) | screenshot | 保存画像が必要な場合にのみ使用 |
アクションの連結ルール
コマンドは && で連結できます。ブラウザーはデーモン経由で維持されるため、連結しても安全です。
可能な場合は常に連結してください — ツール呼び出しが少ないほど、完了が速くなります:
# GOOD: open + inspect in one call (saves 1 round trip)
opencli browser open https://example.com && opencli browser state
# GOOD: fill form in one call (saves 2 round trips)
opencli browser type 3 "hello" && opencli browser type 4 "world" && opencli browser click 7
# GOOD: type + verify in one call
opencli browser type 5 "[email protected]" && opencli browser get value 5
# GOOD: click + wait + state in one call (for page-changing clicks)
opencli browser click 12 && opencli browser wait time 1 && opencli browser state
# BAD: separate calls for each action (wasteful)
opencli browser type 3 "hello" # Don't do this
opencli browser type 4 "world" # when you can chain
opencli browser click 7 # all three together
ページが変わるコマンドは、必ずチェーンの最後に置いてください(後続のコマンドでは古いインデックスが使われます):
open <url>、back、ページ遷移が発生するリンク/ボタンのclick
ルール:インデックスがすでに分かっている場合は連結します。最初にインデックスを確認する必要がある場合は、state を個別に実行してください。
基本的なワークフロー
- 移動:
opencli browser open <url> - 確認:
opencli browser state→[N]インデックス付きの要素 - 操作:インデックスを使って
click、type、select、keysを実行 - 待機(必要な場合):
opencli browser wait selector ".loaded"またはwait text "Success" - 検証:
opencli browser stateまたはopencli browser get value <N> - 繰り返し:コマンド間でブラウザーは開いたままです
- 保存:TS アダプターを
~/.opencli/clis/<site>/<command>.tsに書き込みます
コマンド
移動
opencli browser open <url> # Open URL (page-changing)
opencli browser back # Go back (page-changing)
opencli browser scroll down # Scroll (up/down, --amount N)
opencli browser scroll up --amount 1000
確認(無料かつ瞬時)
opencli browser state # Structured DOM with [N] indices — PRIMARY tool
opencli browser screenshot [path.png] # Save visual to file — ONLY for user deliverables
取得(無料かつ瞬時)
opencli browser get title # Page title
opencli browser get url # Current URL
opencli browser get text <index> # Element text content
opencli browser get value <index> # Input/textarea value (use to verify after type)
opencli browser get html # Full page HTML
opencli browser get html --selector "h1" # Scoped HTML
opencli browser get attributes <index> # Element attributes
操作
opencli browser click <index> # Click element [N]
opencli browser type <index> "text" # Type into element [N]
opencli browser select <index> "option" # Select dropdown
opencli browser keys "Enter" # Press key (Enter, Escape, Tab, Control+a)
待機
3 つの方法があります。状況に応じて適切なものを使ってください:
opencli browser wait time 3 # Wait N seconds (fixed delay)
opencli browser wait selector ".loaded" # Wait until element appears in DOM
opencli browser wait selector ".spinner" --timeout 5000 # With timeout (default 30s)
opencli browser wait text "Success" # Wait until text appears on page
待機する場面:SPA での open の後、非同期読み込みを開始する click の後、動的にレンダリングされるコンテンツに対して eval を実行する前。
抽出(無料かつ瞬時、読み取り専用)
データの読み取りにのみ eval を使ってください。クリック、入力、移動には使わないでください。
opencli browser eval "document.title"
opencli browser eval "JSON.stringify([...document.querySelectorAll('h2')].map(e => e.textContent))"
# IMPORTANT: wrap complex logic in IIFE to avoid "already declared" errors
opencli browser eval "(function(){ const items = [...document.querySelectorAll('.item')]; return JSON.stringify(items.map(e => e.textContent)); })()"
セレクターの安全性:querySelector は見つからない場合に null を返すため、常にフォールバックセレクターを使ってください:
# BAD: crashes if selector misses
opencli browser eval "document.querySelector('.title').textContent"
# GOOD: fallback with || or ?.
opencli browser eval "(document.querySelector('.title') || document.querySelector('h1') || {textContent:''}).textContent"
opencli browser eval "document.querySelector('.title')?.textContent ?? 'not found'"
Network(API の検出)
opencli browser network # Show captured API requests (auto-captured since open)
opencli browser network --detail 3 # Show full response body of request #3
opencli browser network --all # Include static resources
Sedimentation(CLI として保存)
opencli browser init hn/top # Generate adapter scaffold at ~/.opencli/clis/hn/top.ts
opencli browser verify hn/top # Test the adapter (adds --limit 3 only if `limit` arg is defined)
initはアクティブなブラウザーセッションからドメインを自動検出します(指定する必要はありません)initはファイルを作成し、現在のページからsite、name、domain、columnsを設定しますverifyはアダプターをエンドツーエンドで実行して出力を表示します。アダプターにlimit引数がない場合は、--limit 3を渡しません
セッション
opencli browser close # Close automation window
例:HN のストーリーを抽出する
opencli browser open https://news.ycombinator.com
opencli browser state # See [1] a "Story 1", [2] a "Story 2"...
opencli browser eval "JSON.stringify([...document.querySelectorAll('.titleline a')].slice(0,5).map(a => ({title: a.textContent, url: a.href})))"
opencli browser close
例:フォームに入力する
opencli browser open https://httpbin.org/forms/post
opencli browser state # See [3] input "Customer Name", [4] input "Telephone"
opencli browser type 3 "OpenCLI" && opencli browser type 4 "555-0100"
opencli browser get value 3 # Verify: "OpenCLI"
opencli browser close
再利用可能な CLI として保存 — 完全なワークフロー
段階的な sedimentation の流れ:
# 1. Explore the website
opencli browser open https://news.ycombinator.com
opencli browser state # Understand DOM structure
# 2. Discover APIs (crucial for high-quality adapters)
opencli browser eval "fetch('/api/...').then(r=>r.json())" # Trigger API calls
opencli browser network # See captured API requests
opencli browser network --detail 0 # Inspect response body
# 3. Generate scaffold
opencli browser init hn/top # Creates ~/.opencli/clis/hn/top.ts
# 4. Edit the adapter (fill in func logic)
# - If API found: use fetch() directly (Strategy.PUBLIC or COOKIE)
# - If no API: use page.evaluate() for DOM extraction (Strategy.UI)
# 5. Verify
opencli browser verify hn/top # Runs the adapter and shows output
# 6. If verify fails, edit and retry
# 7. Close when done
opencli browser close
アダプターの例:
// ~/.opencli/clis/hn/top.ts
import { cli, Strategy } from '@jackwener/opencli/registry';
cli({
site: 'hn',
name: 'top',
description: 'Top Hacker News stories',
domain: 'news.ycombinator.com',
strategy: Strategy.PUBLIC,
browser: false,
args: [{ name: 'limit', type: 'int', default: 5 }],
columns: ['rank', 'title', 'score', 'url'],
func: async (_page, kwargs) => {
const limit = Math.min(Math.max(1, kwargs.limit ?? 5), 50);
const resp = await fetch('https://hacker-news.firebaseio.com/v0/topstories.json');
const ids = await resp.json();
return Promise.all(
ids.slice(0, limit).map(async (id: number, i: number) => {
const item = await (await fetch(`https://hacker-news.firebaseio.com/v0/item/${id}.json`)).json();
return { rank: i + 1, title: item.title, score: item.score, url: item.url ?? '' };
})
);
},
});
~/.opencli/clis/<site>/<command>.ts に保存すると、すぐに opencli <site> <command> として利用できます。
戦略ガイド
| 戦略 | 使用する状況 | browser: |
|---|---|---|
Strategy.PUBLIC | パブリック API、認証不要 | false |
Strategy.COOKIE | ログイン Cookie が必要 | true |
Strategy.UI | DOM を直接操作 | true |
常に UI より API を優先してください — ブラウジング中に API を見つけた場合は、fetch() を直接使用してください。
ヒント
- まず必ず
stateを実行してください — 要素のインデックスを推測せず、必ず先に確認してください - セッションは維持されます — コマンド間でブラウザーは開いたままなので、再度開く必要はありません
- データの抽出には
evalを使用してください —eval "JSON.stringify(...)"は複数回のget呼び出しより高速です - API を見つけるには
networkを使用してください — JSON API は DOM のスクレイピングより信頼性が高いです - エイリアス:
opencli opはopencli browserの省略形です
よくある落とし穴
-
自動化では
form.submit()が失敗します — フォームの送信にform.submit()やevalを使用しないでください。代わりに検索 URL に直接移動してください:# BAD: form.submit() often silently fails opencli browser eval "document.querySelector('form').submit()" # GOOD: construct the URL and navigate opencli browser open "https://github.com/search?q=opencli&type=repositories" -
GitHub の DOM は頻繁に変更されます — 利用可能な場合は
data-testid属性を優先してください。クラス名やタグ構造より安定しています。 -
SPA ページでは抽出前に
waitが必要です — シングルページアプリでopenまたはclickを実行した後、DOM はすぐには準備できません。evalの前に必ずwait selectorまたはwait textを実行してください。 -
クリックする前に
stateを使用してください —opencli browser stateを実行して、利用可能な操作要素とそのインデックスを確認してください。記憶を頼りにインデックスを推測しないでください。 -
evaluateはブラウザーのコンテキストで実行されます — アダプター内のpage.evaluate()はブラウザー内で実行されます。Node.js の API(fs、path、process)は利用できません。ネットワーク呼び出しにはfetch()を、ページデータには DOM API を使用してください。 -
page.evaluate内のバッククォートは JSON への保存を妨げます — JSON として保存または転送するアダプターを書くときは、page.evaluate内でテンプレートリテラルを使用しないでください。代わりに文字列の連結、または関数形式の evaluate を使用してください:// BAD: template literal backticks break when adapter is in JSON page.evaluate(`document.querySelector("${selector}")`) // GOOD: function-style evaluate page.evaluate((sel) => document.querySelector(sel), selector)
トラブルシューティング
| エラー | 解決方法 |
|---|---|
| "Browser not connected" | opencli doctor を実行してください |
| "attach failed: chrome-extension://" | 1Password を一時的に無効にしてください |
| 要素が見つからない | opencli browser scroll down && opencli browser state |
| ページ変更後にインデックスが古くなった | 最新のインデックスを取得するため、opencli browser state を再度実行してください |