キャプチャオプション
capture-ledger 自身は何も撮りませんし、CLI が消えた今は BrowserHive とも話しません (投げるのは Windmill の flow です)。ここに残っているのは 1 つの判断 —— どの形式を要求するか、署名を必須にするか —— だけで、capture-ledger はそれを環境変数から 決め、投げるたびに載せます。
線の引き方はクロールの API と同じです。呼ぶ側が「いつ」を決め、capture-ledger が 「何を」決める。 形式はリクエストの性質ではなく配備の性質なので、呼び出し元から 受け取らないようにしてあります。
フォーマット
Section titled “フォーマット”CAPTURE_LEDGER_CAPTURE_FORMATS にカンマ区切りで書きます。既定は wacz ——
このパイプラインが作るのは再生できるアーカイブで、他の形式はその付随物だからです。
CAPTURE_LEDGER_CAPTURE_FORMATS=wacz # png, webp, html, links, mhtml, waczCAPTURE_LEDGER_CAPTURE_SIGNING=1 # wacz-auth 署名を要求する。wacz が要る| 値 | captureFormats のキー |
|---|---|
png |
png |
webp |
webp |
html |
html |
links |
links |
mhtml |
mhtml |
wacz |
wacz |
6 つのキーは毎回全部を明示して送ります —— BrowserHive にとって「未設定」と
false は別物です。最低 1 つが true でないとサーバがリクエストを拒みます。
読むのは起動時の 1 回だけ
Section titled “読むのは起動時の 1 回だけ”CAPTURE_LEDGER_CAPTURE_FORMATS はクロールのたびではなく、API の起動時に解釈します。
綴りを間違えていれば、その値を名指しでサーバが落ちます。毎回解釈する形にすると、
waxz のような打ち間違いは夜中の定期クロールが「形式が 1 つも有効でない」で
失敗して初めて表に出ます —— 原因の設定名を一言も含まないメッセージで。
リンクを辿るクロールには links が足される
Section titled “リンクを辿るクロールには links が足される”maxDepth が 1 以上のクロールには、環境変数が何であれ links: true が付きます。
無いと 1 段目で必ず止まり、しかも「そのページにリンクが 1 本も無かった」ように
見えます —— 設定の誤りが、サイトの事実と区別できなくなります。
深さ 0 のクロールには足しません。辿らないリンクを取り出させても、相手と bucket に 無駄が出るだけです。
署名は落ちず、取り込みが落ちる
Section titled “署名は落ちず、取り込みが落ちる”CAPTURE_LEDGER_CAPTURE_SIGNING=1 は形式に wacz があることを要求します。サーバに後から
INVALID_ARGUMENT を言わせるのではなく、capture-ledger が起動時に拒みます。
署名が得られなければ、その取り込みは失敗します。 BrowserHive は zip を書く前に 落とすので、署名済みのはずのものが未署名で出ることはありません。これは意図した 挙動ですが、運用上の帰結を明記しておきます —— 署名サービスの設定されていない配備で 署名を有効にすると、全件が失敗します。
無効のままにすれば、判断はサーバの --signing-policy に委ねられます。required で
動いている配備なら、capture-ledger が何も言わなくても署名されます。
結果は台帳に残ります。archives.signed は署名が付けば true、そもそも求めて
いなければ null —— 「このクロールは証拠として使える形のアーカイブを作ったか」に、
zip を 1 つも開かずに答えられます。
ページの中で走らせるもの
Section titled “ページの中で走らせるもの”BrowserHive v11.0.0 から、サーバは走らせるものの顔ぶれを持ちません。組み込みの behavior も、サイト別の behavior もありません。送らなければページの中では何も走らず、 受け皿すら注入されません。それでも取り込みは成功し、アーカイブも出ます —— スクロールも遅延読み込みも起きていない、というだけです。
だからスクリプトがここに在ります。 既定を持てるのは「このクロールは何を走らせるか」を
決める側だけなので、capture-ledger が scripts 表を持ち、解決した結果をクロールの行に
固定します。
ソースの出どころは capture-scripts で、
.upstream/capture-scripts の submodule として固定しています。あちらの catalog.json が、
ソースが自分では言えないこと —— id と phase、サイト用のスクリプトなら sites、既定に入るか(default)—— を持ちます。
# スクリプト(catalog.json)と受け皿の型を入れる。何度流しても同じ(同じバイト列は同じ版)pnpm run scripts import .upstream/capture-scriptspnpm run scripts list # 各 id の最新版(札つき)pnpm run scripts list --seed https://laws.e-gov.go.jp/ # その起点のクロールが、scripts を書かないと走らせるもの(capture-scripts の egov-law-search も入る)pnpm run scripts list autoscroll --all # 1 つの id の版の並びpnpm run scripts show autoscroll --version 1 # その版の source(無効な版も)pnpm run scripts types # 受け皿(__bh)の型。import が写した物
# 1 本だけ試す・設定を変えるのは、いまも手でpnpm run scripts add autoscroll --file ./autoscroll.js --options '{"maxSteps":60}'pnpm run scripts add my-search --file ./my-search.ts --site www.example.com # サイト用のスクリプトpnpm run scripts disable autoscroll # 既定から外す。名指しすれば走る(次の import でカタログに戻る)import は options について意見を持ちません。同じ source なら options が何であれ同じ版
として扱うので、手で調整した版を黙って置き換えることがありません。--options を渡すのは
意見なので、そちらは版を分けます。
既定に入るかは、カタログが決めます。 "default": false の項目は既定に入りません。import はその id の
全版を無効にします(最新版だけを無効にすると、古い版が既定に出てくるため)。default を省いた(true の)
項目は、取り込んだ版を有効にします。enable・disable で手で替えた物は、次の import まで効きます。
いま既定に入らないのは autofetch だけです(capture-scripts v0.5.0)。走らせるには scripts で名指しします。
import は、同じ置き場所の types/host.d.ts(受け皿 __bh の型)も host_types に写します。
こちらも中身が変わったときだけ版を足します。スクリプトを読む人に見せる写しで、クロールの変換が使う型は
ts-compile-service の pin です(compiledWith.hostTypes に出る)。ファイルの無い置き場所は、型を
入れずにスクリプトだけを入れ、そう言います。
sha256 は生成列です。Postgres が source から数え、手で書き込むことはできません。
BrowserHive は受け取った両者を照合し、食い違えば INVALID_ARGUMENT で拒みます ——
生成列にしてあるので、あの照合が capture-ledger の数え間違いに答えていることはありえません。
phase は BrowserHive の 2 つの注入口のどちらを使うかです。behavior は読み込みの後・
主フレーム・1 回で、受け皿を通して報告できます。preload は遷移の前・iframe を含む
全フレーム・遷移のたびに走り、報告する手段を持ちません。
サイト用のスクリプト(sites)
Section titled “サイト用のスクリプト(sites)”スクリプトは 1 本ずつ sites(札)を持てます。小文字のホスト名の列で、IDN は punycode で書き、ポート・
scheme・* は書けません。札のあるスクリプトはサイト用のスクリプトで、クロールの起点のどれかがそのホストに
あるときだけ走ります。照らすのは起点のホスト名との完全一致で、ポートは見ません。example.com と
www.example.com は別のホストです。札の無いスクリプトは、今までどおりどこでも走ります。札は版の一部で、
options と同じく、変えたら版が足されます。import が読む catalog.json の形は capture-scripts/3
(capture-scripts v0.5.0 で default が入った)で、import はそれより前の形を断ります。形の悪いホスト名も、DB に
触る前に断ります。
capture-scripts のサイト用のスクリプトの見本は egov-law-search(札 laws.e-gov.go.jp・v0.4.0 から)です。
e-Gov 法令検索の頁の中で法令名を「セキュリティ」で引き、件数と法令名を報告します。
起点が e-Gov 法令検索のクロールだけが既定で走らせ、ほかの起点では選ばれません。
決まりはクロールの単位で、起点で決まります。選ばれたサイト用のスクリプトは、そのクロールの全部の頁で
走ります。リンクを辿って別のホストへ出た頁でもです。だからサイト用のスクリプトは、冒頭で
location.hostname を見て、ほかの頁では何もせずに終わります(capture-scripts の check が、札の
ホスト名が source に出てくることを見ます)。
クロールが固定するもの
Section titled “クロールが固定するもの”POST /api/crawls はスクリプトを始めるときに 1 度だけ解決し、その結果 —— id・版・phase・
source・sha256・options・札 —— をクロールの行に書きます。以後の段はそれをそのまま使い、
台帳のスクリプトを引き直しません。長いクロールの途中で版を足しても、後半のページで走るものは
変わりません。
scripts |
走るもの |
|---|---|
| 省く | 有効な各 id の最新版のうち、札の無い物と、札が起点のホスト名を含む物を、id 順で |
[{"catalog": "b"}, {"catalog": "a"}] |
そのとおり、その並びで —— 並びは指示の一部 |
[{"inline": {"name": "x", "phase": "behavior", "source": "…"}}] |
書いた JS を inline-x・版 1 で。台帳には登録されない(下記) |
[] |
何も走らない。「既定でよい」と「何も走らせない」は別の意思 |
| 台帳に無い id・同じ id の重ね | 400 で名指し(ids)。クロールは立たない |
| 札が起点のどのホスト名も含まないサイト用のスクリプト | 400 site scripts need a seed on their site で名指し(ids、札は hint)。クロールは立たない |
| 省いたのに、有効なスクリプトが全部ほかのホスト用 | 400 no default scripts for these seeds(hint に並べる)。「スクリプトが無い」とは言わない |
要素は、鍵が 1 つの object です(catalog か inline のどちらか)。
GET /api/crawls/:id が返すのは、台帳のスクリプトは身元 —— id・版・phase・sha256 —— と札だけで、
source は返しません。走ったバイト列はアーカイブ(behaviors/custom.jsonl と
preload/scripts.jsonl)と台帳(版を読む)に在ります。その場の JS には inline(name・phase・
source の UTF-8 の大きさ bytes)も返しますが、ここでも source は返しません。dashboard は走行中の
クロールを数秒ごとに引き直し、source は 1 MiB まであり得るからです。source は
GET /api/crawls/:id/inline/:name が { name, phase, source, sha256 } で返します。台帳に登録されず、
アーカイブに在るのは変換後の JS なので、書いた物を取り戻せるのはこの口だけです。台帳のスクリプトには 404 を
返します。
最初の段の報告が来ると、各要素に jsSha256 と compiledWith({ typescript, hostTypes })も
付きます。その段が走らせた JavaScript の sha256 と、何で・何に向けて変換したか ——
ts-compile-service が答え、flow が報告(POST /api/crawls/:id/pages の compiled)で
運んだ物です。台帳のスクリプトの sha256 は TypeScript に打たれ、アーカイブに残るのは JavaScript。
その間を継ぐのがこの値で、台帳が報告から写します。段ごとに同じ hash が来なければ 409 ——
走行中のクロールの下で変換サービスが替わったということです。報告が来る前はどちらも
null です。
スクリプトの source は、クロールを始められる人が HTTP で読めます。
| 口 | 返すもの |
|---|---|
GET /api/scripts |
各 id に 1 行(サイト用のスクリプトも、既定に入らない物も): 既定で走る版(有効な版の中の最新)か、無ければ最新版を enabled: false で。id・version・phase・sha256・sites・enabled。scripts を書かないクロールが走らせるのは、enabled の物のうち札の無い物と、起点のホストに合う物 |
GET /api/scripts/:id/versions |
1 つの id の版の並び(新しい順): version・phase・sha256・sites・enabled・bytes・createdAt。source は返さない |
GET /api/scripts/:id/versions/:version |
1 版を丸ごと: 上に id・source・options を足した物。無効な版も返す(過去のクロールが走らせた物) |
GET /api/host-types |
import が写した、いちばん新しい受け皿の型: version・sha256・createdAt・source・bytes |
4 本ともクロールの口と同じ問い(呼び出し元の組織のどれかに can_submit)を訊きます。名乗りが
無ければ 401、許可が無ければ 404 で、在らない id や版と同じ答えです。版が 1 以上の整数でなければ、
何より先に 400 です。bytes は UTF-8 の大きさです。pnpm run scripts show --version は 1 版の口と
同じ関数で読みます。
版の番号は使い回されます。 add は最新の版 + 1 を採るので、最新の版を消して足し直すと、同じ番号が
別の中身になります(capture-scheduler の e2e は毎回これをします)。ある版がクロールの走らせた物かを
確かめるには、その sha256 をクロールの物と比べます。
その場の JS
Section titled “その場の JS”scripts の要素には、台帳のスクリプトの名指しのほかに、その場で書いた JS を置けます。
{ "inline": { "name": "close-banner", "phase": "behavior", "source": "(() => {\n …\n})();\n" } }- 台帳には登録されません。 台帳はクロールの行の写しにだけ、
inline-<name>・版 1・options 空で 固定します。sha256 は台帳がsourceから打ちます(scriptsの生成列と同じ値)。写しの形は台帳のスクリプトと 同じなので、flow も変換も BrowserHive も区別しません。 inline-は、その場の JS に取ってあります。 台帳のスクリプトの id には使えません(CLI のaddとimportが断り、DB の CHECK が最後に断ります)。アーカイブに残るのは id と JS だけなので、 id の頭で、台帳のスクリプトかその場の物かが分かります。nameは^[a-z][a-z0-9-]*$で、inline-と合わせて 64 字まで。 ts-compile-service の id と 同じ綴りで、合わなければPOSTが 400 で断ります。- 書けるのは、strict の TypeScript として型が通る JS です。 段の最初に ts-compile-service が
台帳のスクリプトと一緒に型を検査し、1 本でも誤りがあれば段ごと落ちます(
errorに診断が残ります)。 IIFE で包んでください。同じ段の JS は 1 つの program で検査されるので、top-level の名前は ほかの JS や DOM の大域(nameなど)とぶつかります。exportを書くと型は通りますが、 ページでは構文エラーになり、何も走りません。型の検査を外すなら、1 行目に// @ts-nocheck(構文は見ます)。 POST /api/crawlsの本文は、全体で 1 MiB までです。 超えると、何かを検査する前に 413 で断ります。preloadには受け皿(__bh)がありません。 型の上では見えますが、ページには在りません。
capture-ledger がいまも決めないもの
Section titled “capture-ledger がいまも決めないもの”以前の CLI は BrowserHive の CaptureRequest のフィールドそれぞれに旗を対応させていました
(--device-pixel-ratios / --operation-delay-ms / --dismiss-banners /
--accept-language / --session)。これらはもう存在しません。 captureFormats・
signing・上のスクリプトを除けば、capture-ledger はページの描き方について何も送りません
—— 送らないものはすべて、その BrowserHive サーバの設定どおりになります(意味は
BrowserHive 自身のドキュメントが定義します)。
呼び出し元がクロールごとに渡せるもの
Section titled “呼び出し元がクロールごとに渡せるもの”相手への当たり方と範囲を、POST /api/crawls のボディで渡せます
(アーカイブ台帳を参照)。
| フィールド | 既定 | 意味 |
|---|---|---|
rules |
[{ "follow": "same-origin" }] |
どのリンクを撮って辿り、撮るだけにし、落とすか |
maxDepth |
2。fromTargets のときは 0 |
どこまで辿るか |
maxPages |
30。ただし起点の数は下回らない | 総ページ数 |
perHostDelayMs |
2000 | 同じホストのページ間の間隔 |
hostParallelism |
4 | 同時に触るホストの数 |
scripts |
有効な各 id の最新版(ほかのホスト用のサイト用のスクリプトを除く) | ページの中で走らせるもの(上記) |
知らないキーは黙って落とさず 400 で返します。