概要
InitDataExtractorは、指定したウェブページのHTMLからScratchがページに埋め込む Scratch.INIT_DATA(PROFILE / CLASSROOM 等)を抽出し、Scratch拡張のブロックでアクセスできるようにします。
従来の「scriptタグ全文を手入力」方式をやめ、URLを渡すだけで /html/head/script[7](7番目の<script>)を自動抽出して解析します。
- URLを指定するだけでHTMLを取得して解析します。
- 抽出対象はデフォルトで
/html/head/script[7](7番目の<script>)です。変更可能。 - 取得したデータは
PROFILE/CLASSROOMとして保存され、ブロックから参照できます。 - JSONパスはドット区切りではなく、スラッシュ区切り(例:
model/username)を採用。配列インデックスは1ベース表記から0ベースへ自動変換されます(例:array[1]→array/0)。
導入方法
拡張機能ファイル(例: initdata-extractor.js)を用意し、Scratch拡張の読み込み方法に従って登録してください。開発時はブラウザのコンソールで動作確認してください。
// 例: 拡張の登録(簡略)
Scratch.extensions.register(new InitDataExtractor());
ブロック一覧
| ブロック | 種類 | 説明 |
|---|---|---|
URL [URL] からINIT_DATAを読み込む | コマンド | 指定したURLをfetchして、/html/head/script[7] を抽出、解析して内部ストアに保存します。 |
[SECTION] 全体をJSONで取得 | レポーター | PROFILE または CLASSROOM の全データをJSON文字列で返します。 |
[SECTION] の [PATH] を取得 | レポーター | スラッシュ区切りパスで指定したフィールドを返します(例: model/username)。配列は0ベースでアクセスされます。 |
使い方(例)
以下は典型的な手順です。
- ブロックで URL を指定して読み込む。
- PROFILE 全体をJSONで取得するか、個別フィールドを参照する。
// Scratch ブロック的な擬似コード
URL に "https://scratch.mit.edu/users/griffpatch/" を指定して実行
PROFILE 全体をJSONで取得 -> { model: {...}, related_counts: {...}, featuredProject: {...} }
PROFILE の model/username を取得 -> "griffpatch"
HTML生データの例(解析対象のスクリプト断片):
<script>
Scratch.INIT_DATA.PROFILE = {
model: { username: 'griffpatch', id: 12345 },
related_counts: { followers: 10000 },
featuredProject: { id: 999, title: 'Cool' },
featuredProjectLabel: 'Featured Project'
};
</script>
JSONPath(スラッシュ記法)
当拡張ではドット区切りではなく、以下のような スラッシュ区切り を使用します。
model/username→model.usernameと同じ- 配列の指定は元のHTMLが
array[1]のように1ベースで表記されている場合、内部参照は0ベースへ自動変換されます。例:test.array[1].id→test/array/0/id
// 元のドット表記(HTML内表記)
test.array[1].id
// 当拡張でのスラッシュ表記
test/array/0/id
注意: スラッシュ区切りのパーツに角括弧 [n] を含める必要はありません。配列を指定する場合は、変換後の数値インデックスを直接書きます。
スクリプト選択ルール
デフォルトでは、HTMLドキュメントから全ての<script>タグを順に列挙し、7番目(XPath 的には /html/head/script[7])を抽出対象とします。
実装上は正規表現で<script>タグを列挙し、インデックス 6(0始まり)を使います。見つからない場合はエラーになります。
例外とカスタマイズ:
- ページ構造が変わる可能性があるため、拡張側で"スクリプト番号"を指定できるオプションを提供することを推奨します。
- 将来的には、特定のスクリプト内にある
Scratch.INIT_DATAを検出するためのより堅牢なロジック(例: 正規表現でScratch\.INIT_DATAの有無を確認)が望ましいです。
エラーハンドリング
主なエラーと対処法:
| エラー | 原因 | 対処 |
|---|---|---|
| 7番目の<script>が見つからない | ページにスクリプトが少ないか構造が違う | スクリプト番号を変更する、もしくはより一般的な検出ロジックを使う |
| Scratch.INIT_DATA.SECTION が見つからない | 対象ページに当該セクションが無い | 対象ページを確認、SECTION名を誤っていないかチェック |
| fetch による取得失敗 | ネットワークエラー、CORS制限など | CORS対策が必要。開発はローカルプロキシかサーバー経由で行うと良い |
拡張方法・設定
改良ポイントと実装メモ:
- スクリプト番号をブロック引数で指定できるようにする(推奨)。
- 抽出対象の検出を、
Scratch.INIT_DATAの存在でフィルタする。正規表現/Scratch\.INIT_DATA\./を使う。 - より厳密にJavaScriptオブジェクトをパースしたい場合は、安全な JS パーサ(AST)を導入することを検討する。純正の
evalはセキュリティリスクがあるため避ける。
// 例: スクリプト番号を指定するブロック
// setSourceFromUrl(url, scriptIndex = 7)
FAQ
Q. なぜ script[7] を使うの?
A. 実装当初の観察で、ScratchサイトのINIT_DATAは7番目のスクリプトに配置されることが多かったため。だがこれは確約ではなく、将来的な壊れやすさがあるため設定可能にするのが望ましい。
Q. CORSの問題が出る場合は?
A. ブラウザの直接fetchではCORSでブロックされる可能性が高い。開発時は自前のプロキシを使うか、サーバーサイドで取得してからクライアントに渡す形が現実的。