TabbitBlog

Browser UseのPythonで読み取りエージェント

モデルとブラウザをつなぎ、テストページで結果を検証します。

この記事の内容
  1. 要点
  2. ブラウザーとモデルの実行場所を決める
  3. 答えが分かっているテストページを作る
  4. エージェントを実行して2つの項目を照合する
  5. ページへのアクセスと出力、副作用を別々に確認する
  6. 最初に失敗した段階から調べる
  7. Python連携が向く場面

Browser UseでPythonのエージェントを作るには、モデル、新しい Browser セッション、答えを確かめられるタスクを Agent に渡します。この例ではローカルHTMLから見出しと番号を読み取ります。Pydanticで形式を確認し、Pythonでページの値と照合します。

以前のバージョンでは、モデルが生成した操作が検証を通らず止まったという GitHubの報告があります。以下はクイックスタートと出力形式のドキュメントに沿った例です。APIはドキュメントと照合しました。実行による通しの検証は行っていません。

要点

  • セッション、タスク、検証をアプリ側で管理するなら、Browser UseのPythonライブラリを使います。

  • 最初はローカルHTMLを、アカウントにログインしていないセッションで開きます。

  • ブラウザーとモデルの実行場所は別々に選べます。ChatBrowserUse はローカルのChromiumを使っていてもホスト型のモデルを呼びます。

  • history.is_successful() はエージェント自身の判定です。結果はページと別途照合します。

  • 最初のテストページにはフォーム、アカウント、アップロードを入れません。

ブラウザーとモデルの実行場所を決める

モデルが操作を選び、ブラウザーが実行します。Pythonは両者をつなぎます。ブラウザーエージェント、決められた手順のPlaywright、ウェブ検索のどれが必要かを、この役割の違いから判断できます。

構成ブラウザーの実行場所選ぶ場面
Pythonライブラリとローカルブラウザースクリプトを実行する端末ローカルのテストページを読み、Pythonで検証する
Pythonライブラリとリモートブラウザースクリプトから接続できるリモートセッションリモート環境が必要で、その環境から対象ページに届く
Browser Use Cloudのホスト型エージェント管理された環境ホスト型APIを使い、その環境から届くURLを渡せる

この例では最初の構成を使います。クイックスタートに従い、BROWSER_USE_API_KEY を環境変数またはローカルの .env に設定します。鍵をリポジトリに含めないでください。uv を入れた環境で新しいプロジェクトを作ります。

uv init --python 3.12
uv add browser-use
uvx browser-use install

最後のコマンドでChromiumを準備します。環境を再現するにはロックファイルを残します。対応モデルの一覧には ChatOllama もあります。モデルを変えるときはテストページと期待値を固定し、ブラウザー操作と出力を確認します。Cloudのクイックスタートには別の認証とセッション設定があります。

RedditのQA担当者の投稿では、顧客データを社内に置くために自前で動くモデルを求めています。同じ条件ならローカルモデルを選びます。この例で送るのは架空のテストデータだけです。

答えが分かっているテストページを作る

HTMLを fixture/index.html に保存します。番号は架空で、フォームや認証情報はありません。別のターミナルでサーバーを起動します。公開する範囲は fixture ディレクトリだけです。

<!doctype html>
<html lang="en">
<meta charset="utf-8">
<title>Inventory fixture</title>
<main>
  <h1>Inventory Check</h1>
  <p>Reference code: BU-741</p>
</main>
</html>
uv run python -m http.server 8765 --bind 127.0.0.1 --directory fixture

127.0.0.1 はブラウザーを実行する端末を指します。リモートブラウザーなら、そのリモート端末自身に接続します。この例では両方を同じ端末で動かします。接続できるか確かめるときは、まずページを手動で開きます。

エージェントを実行して2つの項目を照合する

プロジェクトの直下に check_page.py を保存します。ブラウザー設定で許可ドメインを、Agentの設定で出力形式を確認できます。タスクにはURLを渡します。期待値は照合コードにだけ書き、モデルにはページから読み取らせます。

import asyncio
from tempfile import TemporaryDirectory

from browser_use import Agent, Browser, ChatBrowserUse
from pydantic import BaseModel

URL = "http://127.0.0.1:8765/"


class PageCheck(BaseModel):
    heading: str
    reference: str


async def main():
    with TemporaryDirectory(prefix="browser-use-fixture-") as profile:
        browser = Browser(
            headless=True,
            user_data_dir=profile,
            allowed_domains=["127.0.0.1"],
            accept_downloads=False,
        )
        try:
            agent = Agent(
                task=(
                    f"Open {URL} and read its visible heading and reference code. "
                    "Return only those two values. Do not interact with any form."
                ),
                browser=browser,
                llm=ChatBrowserUse(),
                output_model_schema=PageCheck,
            )
            history = await agent.run(max_steps=5)
            result = history.structured_output
            expected = PageCheck(heading="Inventory Check", reference="BU-741")
            if result != expected:
                raise RuntimeError("The output does not match the fixture.")
            print(result.model_dump_json())
        finally:
            await browser.stop()


if __name__ == "__main__":
    asyncio.run(main())
uv run python check_page.py

期待する見出しは Inventory Check、番号は BU-741 です。不一致ならステップ上限を増やす前に履歴を確認します。上限を増やしても同じ操作が繰り返し失敗することがあります。

ページへのアクセスと出力、副作用を別々に確認する

ページへのリクエスト、PageCheckオブジェクト、値の照合を示す図
リクエストログ、出力形式、値の照合はそれぞれ別の情報を確かめます。

実行時に / へのリクエストがあったか、まずサーバーログで調べます。次に history.urls()、history.errors()、ターミナルの出力を照合します。出力形式のガイドでは、終了、エージェントの成功判定、外部からの検証を分けています。

日常使うプロファイルとテスト用のセッションを分けます。既存ブラウザーに接続すると、エージェントがアクセスできるセッションやCookieが変わります。許可リストが制限するのはナビゲーションです。実サービスでは読み取り権限をサーバー側で設定し、テストアカウントを使います。詳しくはエージェントのセキュリティリスクを参照してください。

最初に失敗した段階から調べる

症状先に見る箇所次の確認
ブラウザーは起動するがリクエストが届かない実行場所、ローカルアドレス、ポート、許可ドメインChromiumと同じ環境からページを開く
モデル提供元がリクエストを拒否する鍵、接続先、アダプター、モデルの利用権限ブラウザー設定を変える前に提供元のエラーを読む
履歴に操作の検証エラーがあるモデルのアダプターとBrowser Useのバージョン公式文書にあるアダプターで同じテストを実行する
形式は正しいが値が違うページの状態とモデルが転記した値項目ごとにHTMLとログを照合する

別のリモートCDPの報告では、ブラウザープロトコルの呼び出しが止まった事例が記録されています。操作の検証とは異なる段階です。どちらも特定バージョンの報告なので、手元のエラーを起点に調べてください。

レコード作成やメッセージ送信を伴うタスクがタイムアウトしたときは、再実行の前に対象システムを確認します。今回の読み取り用ページなら、もう一度アクセスしてログを照合できます。

Python連携が向く場面

後続の処理が型付きのデータを受け取り、値を検証するならPythonが向いています。URL、セレクター、手順が固定ならブラウザースクリプトで十分です。テキストを一度確認するだけなら、ページを開いて読めます。TabbitとBrowser Useの比較とエージェント型ブラウザーの解説では、ブラウザー画面とコード連携の用途の違いを説明しています。

最初の実行では、リクエストが届き、2つの値が一致したところまで確認します。ブラウザー、モデル、対象ページを変えるときは、ひとつずつ切り替えて同じ確認を繰り返します。

よくある質問

PythonライブラリにBrowser UseのAPIキーは必要ですか?

この例のChatBrowserUseにはキーが必要です。他のアダプターは別の設定を使い、ローカルのOllamaにはこのキーが不要です。

ローカルのOllamaモデルを使えますか?

公式ドキュメントにChatOllamaが掲載されています。選んだモデルでブラウザー操作を生成でき、指定した形式で結果を返せるかを確認してください。

最初のタスクを読み取り専用にするには?

アカウントや書き込み先がないテストページと独立したセッションを使います。実際のアプリではサーバー側でも読み取り権限を設定します。

リモートブラウザーでlocalhostを開けないのはなぜですか?

そのアドレスはブラウザーを実行しているホストを指します。この例では同じ端末で両方を動かすか、リモート環境から届くテスト用URLを用意します。

history.is_successful()は何を示しますか?

エージェント自身の成功判定です。対象ページの状態と返された値を個別に確認してから完了と判断します。

structured_outputが空なら何を確認しますか?

履歴でナビゲーション、モデル提供元、操作のエラーを調べます。スキーマやステップ数を変更する前に、output_model_schemaが設定され、処理が完了したかを確認してください。

次のステップへ

Tabbit と一緒に仕事をしましょう。

タブをまたいで調査し、繰り返しのブラウザ作業を自動化し、あらゆる文脈を手の届くところに。