JavaScriptでChromeを外部から操作して、任意のJavaScriptを実行することができるか調べたところ
chrome-remote-interfaceを使うと簡単にできることが分かりました
Chrome DevTools Protocolというリモートデバッグ用プロトコル経由でChromeを操作する(DevToolsの機能を外部から操作することができる)ようです
(PlayWrightのようなE2Eテストツールでもできるのですが、純粋にChromeを操作するツールを探してみました)
chrome-remote-interfaceを使うための準備
npmでchrome-remote-interface
をインストールします
$ npm i chrome-remote-interface
ES Modulesを利用可能にするためpackage.json
に下記の設定を追加します
"type": "module",
リモートデバッグを有効にしてChromeを起動しておきます
(Chromeが起動している場合は、先に終了してから下記コマンドを実行します)
chrome --remote-debugging-port=9222
※Chromeのインストールパスは適宜補ってください
指定したURLを開いて、画面のDOMを変更するサンプルスクリプト
スクリプトを起動する前に、Chromeをデバッグモードで起動しておきます
スクリプトを実行するとexample.com
が表示され、<h1>タグが赤色になります
$ node cdp-open-url.js
import CDP from 'chrome-remote-interface';
async function openURL() {
let client;
try {
// Chromeに接続
client = await CDP();
// 必要な機能を有効化
const { Page, Runtime } = client;
await Page.enable();
await Runtime.enable();
// 指定したURLを開く
const url = 'https://example.com';
await Page.navigate({ url });
await Page.loadEventFired(); // 読み込み完了を待つ
// <h1>を赤くする
const expression = `document.querySelector('h1').style.color = 'red'`;
await Runtime.evaluate({ expression });
} catch (err) {
console.error(err);
} finally {
if (client) {
await client.close();
}
}
}
openURL();
Chrome上でGemini nanoを実行して、結果を受け取ってみる
Chrome128(stable)で利用可能になったGemini Nanoを試してみるという記事でChromeに導入したGemini nano
をブラウザ外部から利用してみます
Gemini nanoのインストール等、準備はこちら(https://qiita.com/murasuke/items/5ad4f7d338fe2054211e)
Geminiの呼び出しは非同期関数なので、呼び出し時に完了を待つためにawaitPromise: true
をつける必要がありました
const result = await Runtime.evaluate({
expression, // Gemini呼び出しjs
awaitPromise: true, // 非同期処理を待つ
});
実行結果(Chrome外部からGemini nanoを呼び出して、結果を受け取ることができました)
$ node cdp-gemini.js
result: 日本で一番高い山は標高3,776メートルの富士山です。
import CDP from 'chrome-remote-interface';
async function callGemini() {
let client;
try {
// Chromeに接続
client = await CDP();
// 必要な機能を有効化
const { Page, Runtime } = client;
await Page.enable();
await Runtime.enable();
// gemini nanoを呼び出して結果を待つ
const expression = `
(async function() {
const session = await window.ai.createTextSession();
const message = await session.prompt("日本で一番高い山はなんですか?");
return message;
})();
`;
const result = await Runtime.evaluate({
expression,
awaitPromise: true, // 非同期処理を待つ
});
// 実行結果を表示
console.log('result:', result.result.value);
} catch (err) {
console.error(err);
} finally {
if (client) {
await client.close();
}
}
}
callGemini();