API リファレンス

paprika_client の全公開関数。 SessionPage を継承するので page.* はセッションでもそのまま使えます。

コード例の表示モード

接続

async_paprika.connect(base_url=None, *, token=None, timeout=180.0) → PaprikaClient

ハブへの接続。接続先は 引数 → PAPRIKA_HUBhttp://localhost:8000

async with async_paprika.connect() as cli:
    ...
with sync_paprika.connect() as cli:
    ...
use Paprika\Client\Paprika;

$cli = Paprika::connect();   // PAPRIKA_HUB or http://localhost:8000
// ...

同期版(sync_paprika)

async/await を使えない・使いたくない場面(簡単なスクリプト、ノートブック、既存の同期コード)向けに、 非同期 API を 1:1 でブロッキングに写した同期ファサードがあります。裏でバックグラウンドの asyncio ループに橋渡しするだけなので、メソッド名・引数・戻り値は async 版と同一(await を外すだけ)。

例1: セッションを動かす

Hacker News のトップ記事をクリックして、辿り着いた先の URL とタイトルを表示します。

from paprika_client import sync_paprika

with sync_paprika.connect() as cli:                      # await 不要
    with cli.session("https://news.ycombinator.com") as page:
        page.locator(".athing .titleline > a").first.click()
        st = page.state()
        print("url:  ", st["url"])
        print("title:", st["title"])

実行結果(例):

url:   https://www.anthropic.com/research/glasswing-initial-update
title: Project Glasswing: An initial update \ Anthropic

例2: fetch で画像を一括取得

Wikipedia の記事を fetch ジョブで丸ごと取得し、保存された画像の URL を表示します。

from paprika_client import sync_paprika

with sync_paprika.connect() as cli:
    job = cli.fetch("https://en.wikipedia.org/wiki/Cat", scroll=True)
    imgs = cli.job_images(job["job_id"])
    print("status:", job["status"])
    print("images:", len(imgs))
    print("first 3:")
    for u in imgs[:3]:
        print(" ", u)

実行結果(例):

status: completed
images: 49
first 3:
  http://paprika.lan:8000/jobs/08dbe3379087/assets/120px-Felis_chaus_-_…jpg
  http://paprika.lan:8000/jobs/08dbe3379087/assets/120px-Gustav_chocolate.jpg
  http://paprika.lan:8000/jobs/08dbe3379087/assets/120px-Orange_tabby_cat_…jpg

本リファレンスの cli.* / page.* / loc.* がそのまま(同期で)使えます。 connect(base_url=None, *, token=None, timeout=180.0, auto_start=True) が既定でループを起動します。 既定では各アクションが [paprika] page.X(...) 形式でログに流れます(無効化は PAPRIKA_CLIENT_ACTION_LOG=0)。

PHP SDK (Phase 1)

PHP からも同じハブを叩けます。同期・外部依存なし (ext-curl のみ)・PHP 8.1+。 Composer パッケージ paprika/client。命名は Python 版を snake_case → camelCase に直したもの (例: job_imagesjobImages)。

現在の Phase 1Job API + Session ライフサイクル。 Page/Locator/walk は Phase 2 で対応予定です。

インストール

composer require paprika/client

例: fetch ジョブを投げて画像を集める

<?php
require 'vendor/autoload.php';

use Paprika\Client\Paprika;

$cli = Paprika::connect();   // PAPRIKA_HUB or http://localhost:8000
$job = $cli->fetch('https://en.wikipedia.org/wiki/Cat', scroll: true);
echo "status: {$job['status']}\n";

foreach ($cli->jobImages($job['job_id']) as $u) {
    echo $u, "\n";
}

例: ライブセッションを開く

use Paprika\Client\Paprika;
use Paprika\Client\Session;

$cli = Paprika::connect();
$cli->session('https://example.com', function (Session $sess) use ($cli) {
    echo "noVNC: ", $cli->baseUrl() . $sess->novncUrl, "\n";
    // Phase 2: $sess->goto(...), $sess->locator(...) ...
});

Phase 1 で使える $cli->* メソッド (Python 版と1:1)

PHP メソッド説明 / Python 版
$cli->health()疎通確認 / cli.health()
$cli->listWorkers() / listSessions()一覧 / list_workers / list_sessions
$cli->createJob($url, $opts)POST /jobs / create_job
$cli->fetch($url, $opts = [], wait: true, ...)fetch 投入+完了待ち / fetch
$cli->getJob($id) / listJobs() / jobResult($id)状態 / get_job / list_jobs / job_result
$cli->waitJob($id, pollInterval: 2.0, timeout: 600.0)終端まで待機 / wait_job
$cli->cancelJob($id) / deleteJob($id)中止 / 削除
$cli->jobAssets($id, kind: null, absolute: true, details: false)asset 一覧 / job_assets
$cli->jobImages($id)画像ショートカット / job_images
$cli->downloadJobAssets($id, $destDir, kind: 'image')ローカル保存 / download_job_assets
$cli->openSession(initialUrl: null, ...) → Sessionセッション確保 / open_session
$cli->session($url, $closure, $kwargs = [])クロージャ自動 close 形 / Python の async with cli.session(...)

Session の Phase 1 サーフェス

例外

クラス用途
Paprika\Client\PaprikaErrorHTTP/トランスポート系エラー。$e->statusCode で HTTP コード取得 (transport なら null)
Paprika\Client\PaprikaActionErrorPage/Locator 系の失敗 (Phase 2 で本格使用)

PaprikaClient (cli.*)

メソッド説明
cli.health() → dict疎通確認
cli.list_workers() → list接続中ワーカー一覧
cli.list_sessions() → listセッション一覧
cli.session(url=None, **kw)セッションを開く(async with / await)。kw: parent_job_id / worker_id / lane_hint / idle_ttl_s / absolute_ttl_s / use_profile
cli.open_session(...) → Session手動でセッション確保(await page.close() で解放)

Job ライフサイクル

メソッド説明
cli.create_job(url, **opts) → dictPOST /jobs。投入のみ。opts は JobOptions(mode / scroll / goal / use_profile / cookies_from …)
cli.fetch(url, *, wait=True, poll_interval=2.0, timeout=600.0, scroll=True, **opts) → dictfetch 投入 + 完了待ち。wait=False で投げっぱなし
cli.get_job(id) → dict現在の状態(status / progress …)
cli.list_jobs() → list全ジョブ(新しい順)
cli.wait_job(id, *, poll_interval=2.0, timeout=600.0) → dict終了状態まで待つ
cli.job_result(id) → dict最終結果(assets / links / 最終URL)
cli.cancel_job(id) / delete_job(id) → dict中止 / 削除

asset(画像・動画)取得

メソッド説明
cli.job_assets(id, *, kind=None, absolute=True, details=False) → listキャプチャ済み asset 一覧。kind=image/video/audio/other/None、details=メタ付き dict
cli.job_images(id, **kw) → listjob_assets(kind="image") のショートカット
cli.download_job_assets(id, dest_dir, *, kind="image") → list[str]ディスクに保存。保存パス一覧を返す

プロパティ(I/O なし): page.url / session_id / worker_id / lane_idx / novnc_url / page_id

メソッド説明
page.goto(url) → dictページ遷移
page.back() / forward() / history_first() / reload()履歴移動・再読み込み(境界で安全)
page.click(selector) → dictクリック。[@N][data-paprika-id="N"] に展開
page.fill(selector, value) → dictinput/textarea に値セット(input/change 発火)
page.press(key, *, count=1, modifiers=None) → dictキー押下("Enter" / modifiers=["Ctrl"]
page.type(text) → dictフォーカス要素に文字挿入
page.scroll(direction="down", pixels=800) → dictスクロール
page.hover / dblclick / focus / scroll_into_view_if_needed (selector, *, index=0) → bool入力デバイス(合成イベント)
page.select_option(selector, value, *, index=0) → bool<select> を選択
page.check / uncheck (selector, *, index=0) → boolチェック ON/OFF
page.set_input_files(selector, files) → dictファイルアップロード(CDP)。files はパス or リスト
await page.goto("https://example.com")
await page.fill("#email", "user@example.com")
await page.press("Enter")
await page.set_input_files("input[type=file]", ["a.jpg", "b.jpg"])
page.goto("https://example.com")
page.fill("#email", "user@example.com")
page.press("Enter")
page.set_input_files("input[type=file]", ["a.jpg", "b.jpg"])
PHP は Phase 2 で対応予定です(現在の Phase 1 は Job API + Session ライフサイクルのみ)。

Page — 取得・待機・状態

メソッド説明
page.text_content / inner_text / inner_html / input_value (selector, *, index=0)テキスト・HTML・値
page.get_attribute(selector, name, *, index=0)属性値
page.count(selector) → int一致要素数
page.is_visible / is_checked / is_enabled / is_disabled / is_editable (selector, *, index=0) → bool状態判定
page.exists(selector) → bool存在チェック(確定的・LLM不要)
page.wait_for_selector(selector, *, state="visible", timeout=30.0) → bool出現/消失待ち。state=attached/detached/visible/hidden
page.wait_for(*, seconds=None, ms=None) → None単純待機
page.state() → dict{url, title, lane_idx, visited_count}
page.title() → str / page.outline() → strタイトル / 要素一覧([@N] 付き)
page.links(*, urls_only=False) → list<a href> 絶対URL
page.visited_urls() → list[str]踏んだURL
page.screenshot(*, path=None) → bytesビューポート PNG

Page — JS 実行・ロケータ生成

page.evaluate(expression, *, await_promise=False) → 値

任意 JS を実行し評価値を返す(JSON 化可能な値のみ)。取得・待機・入力系はこれが土台。

title = await page.evaluate("document.title")
data  = await page.evaluate("fetch('/api').then(r=>r.json())", await_promise=True)
title = page.evaluate("document.title")
data  = page.evaluate("fetch('/api').then(r=>r.json())", await_promise=True)
PHP は Phase 2 で対応予定です(evaluatePage サーフェスの一部として Phase 2 に含まれます)。
ロケータ生成意味
page.locator(selector) → LocatorCSS セレクタ
page.get_by_text(text) → Locator可視テキスト一致
page.get_by_role(role, *, name=None) → Locator[role=]
page.get_by_test_id / get_by_placeholder / get_by_title / get_by_alt_text (text) → Locator属性セレクタ

Page — 収集・Cookie・LLM・永続状態

メソッド説明
page.capture(label="capture") → dictHTML + スクショ + outline を保存
page.assets(*, kind="image", absolute=True, refresh=True, details=False) → listこのセッションでキャプチャ済みの asset(要 parent_job_id
page.save_assets(dest_dir, *, kind="image", refresh=True) → list[str]↑をディスク保存
page.download_video(url=None, *, referer=None, timeout_s=1800) → dictyt-dlp で動画取得
page.cookies(*, host=None, all_cookies=False) → dict現在の Cookie
page.save_cookies_to_host(*, host=None, notes=None, all_cookies=False) → dictCookie を Host レジストリへ保存
page.network(*, since=0.0) → dictメディアのネットワークログ
page.ask(question, *, engine="auto") → boolLLM に yes/no 質問
page.agent(goal, *, max_steps=5, engine="auto") → dictvision/LLM エージェントに委譲
page.get_state(key) / set_state(key, value)親 job に紐づく永続データ(要 parent_job_id
page.solve_cloudflare(*, timeout_s=25.0) → dictCloudflare チャレンジを待つ/通す
page.resize_window(width, height) → dictウィンドウサイズ変更

Page — タブ・ライフサイクル

メソッド説明
page.new_page(url) / open(url) → Page新規タブ(switch=True で既定に)
page.pages() → list[Page]全タブ
page.switch() → dictこのタブを前面に
page.close() → Noneタブを閉じる(最後の1枚ならセッション終了)
page.keepalive(*, idle_ttl_s=120, absolute_ttl_s=86400) → HandoffInfoスクリプト終了後も残し noVNC で人手に引き継ぐ(別名 detach

Session 固有

SessionPage + 複数タブ操作の拡張:

注意 popup を閉じるのに await sess[-1].close() は使わないこと(セッション全体を殺すことがある)。sess.close_popups() を使う。

Locator

page.locator(sel) / get_by_*() が返す。解決はアクション時

メソッド説明
loc.click() / fill(v) / press(k) / type(t)操作
loc.hover() / dblclick() / focus() / check() / uncheck() / select_option(v) / set_input_files(f) / scroll_into_view_if_needed()入力デバイス
loc.text_content() / inner_text() / inner_html() / input_value() / get_attribute(name)取得
loc.is_visible() / is_checked() / is_enabled() / is_disabled() / is_editable() → bool状態
loc.nth(i) / first / last / count() / all()チェーン
loc.wait_for(*, state="visible", timeout=30.0) → boolこの要素が state になるまで待つ
rows = page.locator(".item")
for r in await rows.all():
    print(await r.get_attribute("data-id"))
await rows.first.click()
rows = page.locator(".item")
for r in rows.all():
    print(r.get_attribute("data-id"))
rows.first.click()
PHP の Locator は Phase 2 で対応予定です(チェーン API $page->locator(...)->first()->click() を実装予定)。

サイト巡回(walk / Walker)

「サイト X のページを N 件巡回」のようなクロールを、キュー・重複除去・ドメイン/パスのフィルタ・ オフスコープ redirect 対応まで込みで回す高レベルヘルパー。手書きのループより堅牢です。 walk(page, **opts)Visit を yield する非同期イテレータ(クラス版は Walker)。

from paprika_client import async_paprika, walk

async with async_paprika.connect() as cli:
    async with cli.session("https://example.com", parent_job_id="crawl") as page:
        async for visit in walk(page, target_pages=50, same_domain=True):
            print(visit.n, visit.depth, visit.url)
            await page.save_assets("out/images")   # 各ページで画像保存など
walk は現状 async API のみ sync ファサードからは未公開です。同期スクリプトの中で使う場合は、asyncio.run() で 上の async 例をラップしてください(または walk 部分だけ async で書き、結果を集めてから同期処理に戻す)。
PHP の walk は Phase 3 で対応予定です(Walker / Visit クラスを Python 版と同シェイプで移植)。

Visitn / url / requested_url / depth / outline / page を持ちます(page はそのページに居る Page)。

主なオプション既定説明
start_url現在地巡回の起点
target_pages100訪問ページ数の上限
same_domain / allowed_domainsTrue / —ドメイン制限
allow_paths / deny_paths / deny_defaults— / — / Trueパスの許可・除外(既定の除外パターンあり)
order"bfs"探索順(bfs / dfs)
max_depthリンク深さの上限
per_page_timeout_s30.01 ページあたりの上限秒
persist_stateTrue進捗を parent job に永続化(attempt 跨ぎ再開)
host_dedupFalseホスト横断の既訪 URL 重複除去

ワンショットヘルパー

1 動作だけしてセッションを閉じる糖衣です。インポートは from paprika_client import snapshot, outline, state, run です。

関数説明
await snapshot(url, *, wait=2.0, full_page=False, path=None) → bytes開いて PNG
await outline(url, *, wait=2.0) → stroutline 文字列
await state(url, *, wait=2.0) → dicturl/title…
await run(actions, *, initial_url=None) → dictact.* のアクション列を実行

例外

例外発生条件
PaprikaErrorHTTP レベルのエラー(404 / 5xx / ネットワーク)
PaprikaActionError200 だが action が NO_MATCH / ERR: を返した(.status に生文字列)