M
masaki.work

書き出し機能がないGeneLifeの遺伝子検査結果を、Claude Code + Claude in Chromeで構造化データにする

ai claude-code workflow browser-automation

この記事の全文をコピーして、AIに「この通りに設定をガイドして」と渡すと便利です

📊この記事の図解版があります。内容を視覚的にまとめたページで、全体像をサッと把握できます

図解を見る

書き出し機能がないGeneLifeの遺伝子検査結果を、Claude Code + Claude in Chromeで構造化データにする

想定読者: Claude CodeとClaude in Chrome(ブラウザを操作できる拡張機能)を使える人 所要時間: 準備30分+自動巡回1〜2時間(項目数による) 前提: GeneLifeのマイページにログイン済みのChrome、Claude in Chrome拡張が有効な状態 すぐ試したい人へ: 末尾の「付録: Claude Codeに渡す実行用プロンプト」に、順番に貼るだけのプロンプトを4本用意しています。ただし「始める前に必ず読む注意」だけは先に目を通してください。巡回中、ブラウザのタブをクリックして前面にする操作が数回あります

はじめに ── GeneLifeのマイページには書き出し機能がなかった

GeneLife(Genesis 2.0)のマイページを開いたとき、まず困ったのは「まとめて書き出すボタンがない」ことでした。用意されているのは「印刷」と「PDFダウンロード」だけで、しかもどちらも検査項目ごとの個別操作です。

検査項目は、僕の場合で347件ありました。1件ずつ印刷やPDF化を手作業でやるのは現実的ではありません。

比較として、海外の同種サービス「23andMe」には、自分の生データ(検査で得られた情報の元データ)をテキストで書き出す機能があります。GeneLifeには、僕が調べた範囲(2026-08-31時点の公開情報ベース)では同等の機能は見当たらず、公式FAQ等でも機能追加の予告は確認できませんでした。

そこで、Claude Code(ターミナルで動くAIコーディングエージェント)とClaude in Chrome(ブラウザを操作できる拡張機能)を組み合わせて、マイページの構造を読み取りながら全項目を自動巡回し、手元のファイルに構造化データとして落とす作業をしました。この記事はその手順の記録です。

やってみて分かったのは、この手法がGeneLife固有のものではないことです。「書き出しボタンがないけれど、画面には自分のデータが全部表示されている」サービスなら、同じ考え方で取り出せる可能性があります。まずはGeneLifeでの具体的な手順を書き、最後にその応用の話をします。

この記事では検査結果の中身(数値・判定・個人の型)は一切扱いません。 扱うのは「どうやって取得の仕組みを組み立てたか」という手法だけです。

全体の流れ ── 「一覧」と「詳細」の2段構え

GeneLifeのマイページは、カテゴリごとの「一覧ページ」と、項目ごとの「詳細ページ」に分かれています。この2つは取得のコストがまったく違うので、最初から分けて考えました。

[一覧ページ]                      [詳細ページ]
カテゴリ単位で開く                 項目ごとに1件ずつ開く
  │                                  │
  │ 全項目の「項目名」               │ 判定の根拠になった
  │ 「総合判定ラベル」                │ より詳しいデータ
  │ 「詳細へのリンク」を              │ (自分の型を示す
  │ 一括で読み取れる                  │ ハイライトつき)
  │                                  │
  ▼                                  ▼
軽い・1回の巡回で済む            重い・項目数ぶん繰り返しが必要

まず軽い方(一覧)を確保してから重い方(詳細巡回)に進む順番にしたことで、途中で失敗しても手戻りが小さく済みました。

実際にやった手順

一覧ページから全項目を一括で取る

一覧ページは、ページの内部構造(DOM)を直接読み取るだけで、スクロール操作すら不要でした。ページ内に全項目の情報がすでに並んでいたためです。ここで「項目名」「総合判定ラベル」「詳細ページへのリンク」の3点セットを、カテゴリぶんまとめて取得します。

詳細ページを1件ずつ巡回する

詳細ページは1件ずつしか開けないので、次の4ステップを項目数ぶん繰り返す形にしました。

  1. 一覧ページ上のリンク要素をクリックして詳細ページへ遷移する
  2. 遷移先の内容が描画されるまで待つ
  3. 必要なデータをページの内部構造から抽出する
  4. ブラウザの「戻る」操作で一覧ページに戻り、一覧が再び描画されるまで待つ

この繰り返しを、僕の場合は347項目ぶん行いました。

バッチごとにクリップボード経由でファイルに落とす

集めたデータは、30件程度のバッチ(ひとまとまり)ごとにブラウザ側のメモリ(JavaScriptの変数)に貯め、バッチが終わるたびにローカルのファイルへ受け渡しました。この受け渡しには、ブラウザの「クリップボードへコピー」機能を使っています。理由は次の「ハマりどころ」の(d)で説明します。

保存先は、Gitなどの版管理下には一切置かず、個人PC内の専用フォルダにのみ限定しました(詳しくは「始める前に必ず読む注意」)。

ハマりどころ6選と解決

(a) マイページ自体の遷移が不安定

症状: 初回アクセス時、「まだ読み込み中」というタイムアウトが3回連続で発生しました。

原因: 特定できませんでした。ページ遷移やスクリプトの読み込みに何らかの理由で時間がかかっていたと思われます。

解決: 直後に人間(僕自身)が同じ画面を手動で開き直したところ、問題なく解消しました。

教訓: 自動操作が3回連続で詰まったら、粘らず止まって報告する運用にしています。人が一度手を入れた方が早いことがあります。

(b) 詳細ページへの直接URLアクセスが拒否される

症状: 詳細ページのURL(/detail/{id} のようなパス)が分かっていたので、直接そのURLへ遷移する方式を試したところ、アクセス拒否のエラーになりました。

原因: サイトが静的ファイルホスティングの仕組みの上にSPA(1ページで完結する作りのWebアプリ)を乗せている構成のためと考えられます。直リンクだと、サーバー側がその名前のファイルを探しに行き、見つからず拒否を返す、という仕組み上の理由です。

解決: 一覧ページ上のリンク要素を実際に「クリック」してページ内遷移させる方式に統一しました。これなら常に正しく遷移できました。

教訓: URLが分かっていても直リンクが通るとは限りません。SPAでは、実際にリンクをクリックする方式の方が確実な場合があります。

(c) 「あなたの型」がテキストだけでは分からない

症状: 詳細ページの表データをテキストだけで抜き出すと、どれが自分自身の結果なのかが分かりませんでした。

原因: 「自分の型」は文字色や背景色のハイライトでしか示されておらず、テキストの情報だけでは判別できない作りになっていました。

解決: まずスクリーンショットで見た目を確認し、ハイライトされたセルが特定のCSSクラス名(ページの部品に付けられた識別名)を持っていることを突き止めました。以降は、そのクラス名を持つセルだけを機械的に抽出する処理に切り替えました。

教訓: 「見た目の色」に頼らず、裏側の構造(クラス名)を掴んでから自動化するのが確実です。

(d) JS実行の戻り値が長い文字列だと切り詰められる(最大のハマりどころ)

症状: ブラウザ側で収集したデータを取り出そうとすると、日本語混じりの文字列は900文字前後で出力が切り詰められることが分かりました。英数字だけなら数千文字通ることもありました。347項目ぶんのデータは数万文字に達するため、このままでは非現実的でした。

原因: 恐らく、ツール側の出力サイズにバイト数の上限があります。日本語はUTF-8という文字コードで多くの文字が1文字あたり3バイトを消費するため、文字数換算で見ると閾値が低く見える、と推測しています。

解決: ブラウザの「クリップボードへコピー」機能を使い、いったんクリップボードにデータを書き込み、ローカル側でクリップボードの中身をそのままファイルに書き出す経路に切り替えました。この方法なら数万文字でも一発で欠損なく受け渡せました。

制約: クリップボードへの書き込みは、対象のタブが前面にあり、フォーカスされている時にしか成功しません。裏で別のタブやアプリを触っていると書き込みが失敗し、そのバッチのデータを取りこぼします。書き込みの直前にブラウザ側でフォーカスの有無を確認し、前面になるまで待ってから書き込む運用が必要です。このとき、ターミナルで返事をするとフォーカスがターミナル側へ移ってしまうので、人間はブラウザをクリックするだけにします。また、クリップボードを通すということは、クリップボード履歴ツールに中身が残るということでもあります(「始める前に必ず読む注意」参照)。

教訓: エージェント経由の「戻り値」でデータを受け渡そうとすると、ツールごとの出力サイズ制限に引っかかることがあります。大きなデータは、OSのクリップボードのような「別の受け渡しレーン」を使うと安定します。

(e) 長時間のJS実行はタイムアウト表示が出るが、裏側の処理は止まっていない

症状: 1回の処理で30〜40項目をまとめて巡回させると、エージェントとブラウザの通信が45秒でタイムアウト表示になることがありました。

原因: これは「通信の待ち受け」がタイムアウトしただけで、ブラウザ内で走らせた処理自体はバックグラウンドで最後まで完走していました。

解決: 完了件数をブラウザ側の変数に持たせておき、タイムアウトが出ても慌てず、少し待ってから「今何件終わっているか」だけを返す軽い問い合わせで確認します。処理が続いていれば同じバッチは再実行せず、次のバッチに進みます。

教訓: タイムアウト表示イコール処理停止、とは限りません。裏側の状態を確認する一手間を挟むと安全です。

(f) 特定の項目で処理がブロックされることがある

症状: ある1件のデータ取得で、処理そのものが「分類器(自動でリスクを判定する仕組み)によりブロック」されました。

原因: 詳細な開示はありませんでしたが、その項目が健康・感染症に関連する内容だったことが関係していそうです。

解決: 僕の場合は、通常のテキスト抽出とスクリーンショットでの目視確認に切り替えて対応しました。ただし、これは1件だけだったからできたことです。自動巡回の中でブロックされた項目は、別の手段で取り直そうとせず、いったん止まって件数と位置を報告させ、人間が確認する運用にしておくのが安全です。

教訓: 安全機構が止めた操作を、自動で押し通そうとしない。1件なら人が見た方が早く、確実です。

取得データの構造 ── 1項目 = 1レコード

大きく2つの「カテゴリ一覧ページ」があり、それぞれの一覧ページ自体が全項目のインデックス(目次)になっている構造でした。このインデックス構造をそのままデータ設計の土台にしています。

1レコード(=1検査項目)につき、以下のフィールドを持たせました。

フィールド内容由来
識別子詳細ページを一意に指すリンクのパス一覧ページ
項目名表示名一覧ページ
総合判定5段階程度のラベル一覧ページ
判定根拠のリスト「体の設計図の場所を指すコード」「関連する要素の名前」「本人の型」の組を複数個詳細ページ

JSONにすると、こういう形です(値はすべてダミーです)。

{
  "id": "detail/example-001",
  "name": "項目名の例",
  "category": "カテゴリ名の例",
  "overallLabel": "判定ラベルの例",
  "details": [
    {
      "locusCode": "コードの例",
      "relatedFactor": "関連要素の名前の例",
      "yourType": "本人の型の例"
    }
  ]
}

保存は「カテゴリ単位で1ファイル」に分割しました。1つの巨大ファイルにまとめるより、後から特定カテゴリだけ見返す際にも扱いやすいためです。

なお、一覧の分類にだけ現れて詳細ページへのリンクが通常パターンと異なる特殊項目が1件だけ存在しました。自動巡回の対象パターンに合致しなかったため、個別に検出して手動相当の手順で拾い、同じスキーマ(データの型定義)に正規化して合流させました。全件が同じURLパターン・同じページ構造とは限らないので、巡回後に「取れたはずの件数」と「一覧に表示されている件数」を突き合わせる確認は必須だと感じました。

始める前に必ず読む注意

  • 認証: マイページはログイン必須です。ブラウザ操作エージェントは、人間が既にログイン済みのブラウザセッションを使う想定で動かしました。ログインIDやパスワードの入力自体をエージェントにやらせるのは避けるべきです。
  • 利用規約の確認: サイトによっては、自動的なアクセス・データ収集(いわゆるスクレイピング)を利用規約で制限している場合があります。自分自身のデータを個人利用の範囲でローカルに保存する行為であっても、始める前に対象サービスの利用規約は確認しておくべきです。
  • 保存先: 遺伝子検査の結果は極めて機微な個人情報です。取得したデータは外部サービス・クラウド共有・公開リポジトリには絶対に置かず、個人のローカル環境の、Gitなどのバージョン管理からも除外された場所にのみ保存してください。
  • クリップボード履歴に注意: 受け渡しにOSのクリップボードを使うため、クリップボード履歴ツール(Raycast、Alfred、Windowsのクリップボード履歴など)が常駐していると、検査結果の全文がその履歴に残ります。ツールによっては履歴がクラウド同期されます。作業前に履歴ツールを一時停止し、作業後にクリップボードを空にしてください(macOSなら pbcopy < /dev/null)。
  • 他人の代理での取得は避ける: 今回はマイページの本人自身が、自分自身のデータを自分のために取得する作業でした。家族など他人の検査結果を代理で取得する場合は、本人の同意の取り方や保存・共有範囲について、より慎重な検討が必要になります。
  • AIへの入力に検査結果そのものを含めない: 作業の過程で、検査結果の数値や本人の型そのものをチャットのやり取りに書き出さない運用にしました。最終的な報告も「何件取得できたか」「どんな分類があったか」に留め、中身の値は一切チャットログに残さないようにしています。

他のサービスでも同じ考え方でできる ── AIに任せてみよう

今回はGeneLifeでの作業でしたが、押さえるべき考え方は3つに絞れます。

  • 「書き出しボタンがない」=「取り出せない」ではない。画面に表示されているなら、ページの内部構造を読み取ることで機械的に取得できることがあります。
  • 見た目ではなく裏側の構造を掴んでから自動化する。色で区別されている情報も、クラス名のような機械的に判別できる手掛かりに落とし込みます。
  • 大きなデータは別の受け渡しレーンを使い、機微なデータは経路のすべてに中身を残さない。戻り値のサイズ制限、クリップボード履歴、チャットログ。データが通る場所を一つずつ点検します。

「このサービスにも書き出し機能があったらいいのに」と思ったときは、まずAIに構造を調べさせてみてください。次の付録にあるプロンプトは、僕が実際に自分のデータで試して動いた手順をもとにしています。対象サービス名と保存先を書き換えれば、多くの場合そのまま応用できるはずです。

付録: Claude Codeに渡す実行用プロンプト

GeneLifeにログイン済みのChromeを開き、Claude in Chrome拡張を有効にした状態で、Claude Codeに以下を順番に貼ってください。各プロンプトは、実行後に結果を見せてから次へ進む設計です。中身を全部読み込まなくても、そのまま貼れば動くように書いてあります。1本目で作るルールファイルを2本目以降が読み直すので、会話が長くなってもルールが抜けません。

プロンプト1: 構造を調べる(まだ取得しない)

これから、GeneLifeのマイページから私自身の検査結果を
手元のファイルに取り出す作業を手伝ってください。
Claude in Chrome で、すでにログイン済みのタブを使います。

まず ~/genelife-private/ フォルダを作り、その中に
RULES.md として次のルールを保存してください。
以降のすべての作業でこのルールを守ります。

【RULES.md の内容】
1. 検査結果の値・本人の型・判定内容をチャットに書かない。
   報告は件数・分類名・ファイル名のみ
2. ログイン操作はしない。ログイン済みのタブを使う
3. URLをアドレスバーに直接入力して遷移しない。
   必ず画面上のリンクをクリックして遷移する
4. 同じ操作で3回連続で詰まったら、粘らず止まって報告する
5. 取得データは ~/genelife-private/ にのみ保存する。
   Git管理下・クラウド同期フォルダ・外部サービスに置かない
6. 安全機構(分類器)によるブロックが出た項目は、別の
   手段で取り直そうとせず、件数と位置だけ報告して止まる。
   描画待ちのタイムアウトはブロックではないので、
   スキップとして記録して次へ進む(止まらない)
7. クリップボード履歴ツール(Raycast、Alfred など)は
   作業前に停止する。作業後にクリップボードを空にする

その上で、次を調べてください。まだデータは保存しません。

1. マイページのトップから、検査項目が一覧表示されている
   画面まで、リンクをクリックして辿ってください。
   一覧画面はカテゴリごとに複数あるはずです。
   各一覧画面の見分け方(見出し・件数表示など)と、
   おおよその項目数を報告してください
2. 一覧画面のDOM(ページの内部構造)から「項目名」
   「総合判定ラベル」「詳細ページへのリンク」の3点が
   読み取れるか確認してください
3. 詳細ページを1件だけ、リンクをクリックして開き、
   本人の型を示すセルがどのCSSクラス名で
   ハイライトされているかを突き止めてください。
   確認したらブラウザの「戻る」で一覧に戻ってください
4. 調べた結果(一覧画面の見分け方・件数・DOMの構造・
   クラス名)を ~/genelife-private/STRUCTURE.md に
   保存し、要点を報告してください

プロンプト2: 一覧を一括取得する

まず ~/genelife-private/RULES.md と STRUCTURE.md を読み、
ルールを守って作業してください。最初に1度だけ、
クリップボード履歴ツールを停止したか私に確認してください。

プロンプト1で確認したすべてのカテゴリの一覧画面から、
全項目の「項目名」「総合判定ラベル」「詳細ページへの
リンク」を取得し、カテゴリごとに1ファイルのJSONとして
~/genelife-private/ に保存してください。

データの受け渡しは次の経路を使ってください。
・ブラウザ側で navigator.clipboard.writeText を使い、
  JSON文字列をクリップボードへ書き込む
・ローカル側でOSに応じたクリップボード読み出し
  コマンド(macOSなら pbpaste)でファイルへ書き出す
・JS実行の戻り値では長い文字列が切り詰められるため、
  戻り値経由では受け渡さない

クリップボード書き込みは、ブラウザのタブが前面で
フォーカスされている時しか成功しません。書き込みの
手順は次のとおりにしてください。
1. 「これからクリップボードへ書き込みます。ブラウザの
   タブをクリックして前面にしてください」と表示する
   (私はターミナルで返事をせず、ブラウザをクリック
   するだけです。返事をするとフォーカスがターミナルへ
   移ってしまうため)
2. document.hasFocus() の値だけを返す軽いJSを数秒おきに
   実行して確認する(最大60秒)。true を確認してから、
   書き込みは別のJS実行として行う(待ちと書き込みを
   1つのJS実行にまとめると45秒でタイムアウトし、
   書き込めたか分からなくなるため)
3. 60秒待っても true にならない、または書き込みが
   NotAllowedError で失敗した場合は、収集済みデータを
   ブラウザ側の変数に保持したまま報告して止まる
   (捨てない)

保存後、カテゴリごとのファイル名と件数だけ報告して
ください。

プロンプト3: 詳細を巡回する

まず ~/genelife-private/RULES.md と STRUCTURE.md を読み、
ルールを守って作業してください。

プロンプト2で保存した一覧JSONを読み込み、詳細ページを
1件ずつ巡回して「判定根拠のデータ」を取得してください。

巡回の設計:
・1バッチ = 30件程度。バッチの先頭で、未取得のリンクの
  パス配列を、実行するJSコードの中に直接埋め込んで
  ブラウザ側へ渡す(ページ遷移でブラウザ側の変数は
  消えるため毎バッチ渡し直す。クリップボードからの
  読み取りは使わない)
・取得済みの項目は、保存済みのバッチファイル群を
  読み込んで突き合わせ、スキップする(中断しても、
  ここから再開できる)
・詳細ページへは、一覧上のリンク要素をクリックして
  遷移する。リンク要素は毎回DOMから取り直し、前の
  周回で取得した参照は使わない
・詳細ページへ遷移した後と、「戻る」で一覧に戻った後の
  両方で、目印になる要素が現れるまで待つ(固定秒数
  ではなく出現待ち、最大10秒)。出なければその項目の
  リンクを ~/genelife-private/skipped.json に記録し、
  次へ進む(RULES.md の6のとおり、これは止まる対象
  ではない)。ただしスキップが3件連続したら RULES.md
  の4を適用していったん止まり、ログイン状態が切れて
  いないかを私に確認してから再開する
・本人の型を示すセルは、STRUCTURE.md のCSSクラス名で
  機械的に抽出する
・進捗(完了件数)はブラウザ側のグローバル変数に持つ。
  JS実行が45秒でタイムアウト表示になっても、裏側の
  処理は続いていることがある。少し待ってから件数だけ
  返す軽いJSで進捗を確認し、同じバッチを再実行しない
・バッチが終わるごとに、プロンプト2と同じ手順
  (フォーカス確認つきのクリップボード経由)で
  ~/genelife-private/details-<カテゴリ>-<連番>.json
  としてバッチ単位の新規ファイルに保存する。既存
  ファイルへの追記はしない(JSONが壊れるため)。
  統合はプロンプト4で行う
・安全機構によるブロックが出た項目は RULES.md の6の
  とおり、件数と位置だけ報告して止まる

バッチごとに、完了件数・スキップ件数だけ報告して
ください。

プロンプト4: 検証する

まず ~/genelife-private/RULES.md を読み、ルールを守って
作業してください。

1. ~/genelife-private/skipped.json に記録された項目が
   あれば、プロンプト3と同じ手順でまず自動で再巡回し、
   details-<カテゴリ>-retry.json として保存してください。
   取得できた項目は skipped.json から取り除き、それでも
   取れないものだけ報告してください
2. バッチ単位のファイル群(details-*.json)を、
   カテゴリごとに1つのJSONへ統合してください
   (元のバッチファイルは残す)
3. 一覧画面に表示されている総件数と、統合後の件数を、
   カテゴリごとに突き合わせてください

差分がある場合は、該当する項目のリンクだけを個別に
確認し、理由を報告してください(詳細ページへのリンクの
形が通常と異なる特殊な項目がある可能性があります)。
手動で確認したほうが早い項目は、その旨だけ報告して
止まってください。

最後に、保存したファイルの一覧と、それぞれの件数だけを
報告してください。中身の値は書き出さないでください。

作業が終わったら、クリップボードを空にすることを忘れずに(macOSなら pbcopy < /dev/null)。