コンテンツにスキップ
hsblabs OSS

HTTP ランタイムは mode="http" のプログラムを実行する。 GET リクエストを 1 回送り、ボディをデコードし、HTML を内部 DOM に解析し、値を抽出する。 JavaScript は実行せず、ブラウザも起動しない。

compiler validation
-> runtime capability preflight
-> input and default resolution
-> validation of a required session
-> URL expansion
-> HTTP request
-> validation of the response size
-> charset decode
-> DOM parse
-> output extraction

ランタイムは、リクエストを送る前にセレクタ、外部トランスフォームの有無、ブラウザ専用の値ソース、fetch モードを検査する。 そのため、正しく動作し得ないプログラムが通信を発生させることはない。

項目
メソッド GET
受け入れるステータス 200 から 299
既定のタイムアウト 30 秒
既定のボディ上限 32 MiB
既定の User-Agent scrape-kdl/1.0
リダイレクト 渡された http.Client が制御する。

サイズ超過のレスポンスは E_HTTP_BODY_TOO_LARGE で失敗する。 受け入れ範囲外のステータスは E_HTTP_STATUS で失敗する。 これらの上限は勧告ではない。 ランタイムはボディ全体をメモリに読み込む前に上限を適用する。

ランタイムは文字コードを、まず HTTP ヘッダ Content-Type から、次に文書先頭付近の <meta charset> 宣言から選び、既定は UTF-8 とする。 UTF-8 または UTF-16 のバイト順マークを認識した場合は、宣言された文字コードより優先する。

UTF-8、ASCII、ISO-8859-1、Windows-1252、UTF-16LE、UTF-16BE は組み込みで扱う。 それ以外のラベルは WHATWG エンコーディングインデックスを通じて解決する。 そのため Shift_JIS や EUC-JP のような従来のエンコーディングも、設定なしでデコードできる。

エラーになる状態は二つある。

  • 不正なバイト列は E_HTML_DECODE で失敗する。この挙動は Go ランタイムと TypeScript ランタイムで一致している。
  • replacement エンコーディング、および WHATWG インデックス外のラベルは E_HTML_CHARSET_UNSUPPORTED で失敗する。

session ノードの policy プロパティが挙動を制御する。

ポリシー 挙動
none(既定) 明示的に渡されたセッションを無視する。
optional セッションが渡されていれば使う。
required セッションが得られなければ、fetch の前に抽出を停止する。

ランタイムがセッションのヘッダとクッキーを付けるのは、最初のリクエストだけである。 リダイレクト後のリクエストに再度付け直すことはしない。 そのため伝播を制御するのは、利用者側の http.Client のリダイレクト規則である。 既定のクライアントは、AuthorizationCookie のような機微なヘッダを、同一ドメインとそのサブドメインにしかコピーしない。 クッキージャーを設定した場合は、各クッキーのスコープが適用される。

none ポリシーは、ホスト側の周辺状態を消去しない。 利用者の http.Client とそのクッキージャーは動き続け、Set-Cookie レスポンスヘッダも効き続ける。 状態を持たない実行が必要なら、ジャーも周辺認証も持たない隔離されたクライアントを渡すこと。

Options.URLPolicy フックは、最初のリクエストの前と、HTTP リダイレクトのたびに実行される。 フックがエラーを返すと、抽出は E_URL_POLICY で停止する。

PublicInternetURLPolicy は用意済みのポリシーである。 HTTP でも HTTPS でもないスキーム、userinfo を含む URL、そして IANA の special-purpose レジストリがグローバル到達可能と示していないアドレスを拒否する。 ここにはループバック、プライベート、リンクローカル、CGN、ドキュメンテーション、ベンチマーク、マルチキャスト、未指定、予約の各範囲が含まれる。 レジストリ上でグローバル到達可能とされている例外は許可したままにする。

ポリシーの検査は接続の前に起きる。 そのためポリシー単独では DNS リバインディングを防げない。 このポリシーは NewPublicInternetHTTPClient と併用すること。 このクライアントのダイヤラは接続時にアドレスを再解決して再検査し、拒否を E_URL_POLICY として報告する。 この保護付きクライアントは直接接続を行い、環境のプロキシ設定を使わない。 プロキシを経由すると宛先の解決がプロキシ側で行われ、選ばれたアドレスをクライアントが検査できなくなるためである。

CLI は既定でポリシーと保護付きクライアントを両方適用する。 --allow-private-hosts オプションはこれを無効にする。 ライブラリの既定は異なり、設定するまでポリシーは適用されない。

利用者が独自に用意した CheckRedirect 関数は、Scraping KDL のポリシーの代わりではなく、その後に実行される。

このポリシーはネットワーク層の egress 制御の代替ではない。 層の一つである。

Go ランタイムは、上限付きのバイト列を UTF-8 にデコードしたうえで、ツリー構築に固定バージョンの golang.org/x/net/html を使う。 内部 DOM はドキュメント順を保持し、可搬セレクタ、デコード済みテキスト、決定的な innerHTML、属性、値の欠落時の挙動を提供する。

リポジトリ内の互換性マニフェストは、壊れたテーブルでの foster parenting、アクティブ整形要素、外来コンテンツの統合、raw text、RCDATA、省略可能な終了タグ、途中で切れた入力を網羅している。 承認済みの差異はない。

パーサはスクリプトを実行せず、レイアウトも計算しない。 スクリプトによる変更、レイアウト由来の値、実 DOM 特有の挙動が必要なら、ブラウザモードを使う。 詳細は ブラウザモード を参照。

セレクタや属性の欠落は、フィールドの requireddefault に従う。 on-error ノードはこの状態を制御しない。

on-error ノードが制御するのは、トランスフォームのエラー、セレクタの個数エラー、出力型のエラー、外部トランスフォームのエラーである。 on-row-error="skip" を指定したコレクションは、どのポリシーでも回復されなかったエラーを含む行だけを捨てる。 捨てた行ごとに警告 W_ROW_SKIPPED が追加され、partialtrue になる。

ランタイムは、HTML をメモリ上で解析する前と、出力メンバごと、コレクションの行ごとにコンテキストを検査する。 これらの境界でキャンセルされると E_EXECUTION_CANCELED になり、原因として context.Canceled または context.DeadlineExceeded が保持される。

キャンセルはフィールドポリシーでも行ポリシーでも回復できない。 実行中のパーサ呼び出しを途中で中断することはしない。 キャンセルは次の境界で検出される。 TypeScript ランタイムも AbortSignal で同じ境界を持つ。