🎯 カスタマイズ可能で検出回避型のクラウドブラウザ。自社開発のChromiumを搭載し、ウェブクローラーAIエージェント向けに設計されています。👉今すぐ試す
ブログに戻ります

ChatGPT ウェブスクレイピング: 実用ガイド

Alex Johnson
Alex Johnson

Senior Web Scraping Engineer

17-Jul-2026

TL;DR:

  • ChatGPTはウェブページを取得しません — あなたが渡すテキストを解析します。 モデルにはブラウザもJavaScriptエンジンもなく、アクセスチャレンジを通過する方法もないため、「ChatGPTウェブスクレイピング」のすべての作業セットアップは二層構造です:何かがページを取得し、モデルがフィールドを抽出します。
  • 抽出層は本当に優れています。 OpenAI Python SDKの構造化出力を使用すると、Pydanticスキーマを定義し、chat.completions.parseは検証済みのオブジェクトを返します — ページレイアウトが変わってもセレクターのメンテナンスは不要です。
  • 限界は測定可能です。 JavaScriptでレンダリングされたデモページでのプレーンHTTP GETは0の引用要素を返しますが、js_renderが有効な状態でScrapeless Universal Scraping APIを介して取得した同じURLはすべての10を返します。そのギャップが、モデルが自力では越えられないものです。
  • スキーマ設計はプロンプトの巧妙さに勝ります。 Nullableフィールド、明示的な型、および1ページにつき1回の呼び出しは、信頼できる抽出を生み出します;曖昧なプロンプトは自信満々の発明を生み出します。
  • どのツールを持っているかを知ってください。 「ChatGPTウェブスクレイピング」(このガイド — モデルをパーサーとして利用する)は、ChatGPT自身の回答をデータとしてキャプチャするChatGPTスクレイパーとは正反対です。
  • 無料で始められます。 このガイドの取得層は無料プランで実行されます — app.scrapeless.com でAPIキーを作成してください。

ChatGPTはウェブサイトをスクレイプできますか?

自力ではできません。ChatGPTは言語モデルです:テキストを読み生産し、スクレイパーの取得層が行うこと(リクエストの発行、JavaScriptの実行、セッションの保持、またはボット対策への回答など)を一切行いません。ページのテキストを貼り付けると、フィールドを印象的に抽出しますが、URLを指定すると、その日モデルをラップする取得ツールに依存しており、レンダリングされたページや保護されたページでは静かに失敗します。

したがって、ChatGPTウェブスクレイピングの実際のアーキテクチャは常に同じ二層です。取得層はページの忠実なコピーを取得します。抽出層 — スキーマを持つOpenAI API — はそのコピーを構造化されたレコードに変換します。このガイドでは抽出層を最初に構築します。なぜなら、そこがChatGPTがその地位を獲得する場所であり、その後、取得層の失敗モードとその修正をライブで再現可能な例で示します。

コードの前に一つの明確化があります。キーワードは本当にあいまいです:このガイドはChatGPTを「スクレイパーの脳」として使用します。逆の仕事 — ChatGPT自身の回答とその引用をデータとしてキャプチャすること — はまったく異なるツールであり、ChatGPTスクレイパーAPIガイドと広範なLLMスクレイパーの説明で扱われています。

インストール

2つのパッケージが両方の層をカバーします — 抽出用のOpenAI SDKとHTTP用のrequests。ここでのバージョンはこのガイドに書かれたものです(openai 2.34.0):

bash Copy
pip install "openai==2.34.0" requests

設定

両方の層は環境から認証されるため、ソースコードにキーが保存されることはありません:

bash Copy
export OPENAI_API_KEY="sk-your_openai_key"
export SCRAPELESS_API_KEY="sk_your_scrapeless_key"

基本的な実装:スキーマファーストの抽出

現在のOpenAI SDKは、1回の呼び出しで構造化抽出を行います:Pydanticモデルとしてレコードを定義し、それをresponse_formatとして渡すと、chat.completions.parseはそのインスタンスを返します。スキーマは信頼性を持っています。モデルは、宣言したフィールド名と型に制約されています — 同じ契約スタイルがJSONスキーマ仕様として形式化しているため、出力の質はプロンプトでどれだけ丁寧に頼んだかに依存しなくなります。

注:このブロックにはAPIクレジットを持つOPENAI_API_KEYが必要です — このガイドが前提としない唯一の前提条件であり、抽出呼び出しはキャプチャされた出力なしで示され、その結果の形状については以下で説明されます。次に続く取得層は、Scrapelessキーのみで本当に実行されます。

python Copy
# extract.py — ChatGPTを抽出層として使用(OPENAI_API_KEYが必要)
from openai import OpenAI
from pydantic import BaseModel


class Quote(BaseModel):
    text: str
    author: str
    tags: list[str]


class QuotePage(BaseModel):
    quotes: list[Quote]


client = OpenAI()  # 環境からOPENAI_API_KEYを読み取る
page_html = open("page.html", encoding="utf-8").read()

completion = client.chat.completions.parse(
    model="gpt-4.1-mini-2025-04-14",
    messages=[
        {
            "role": "system",
            "content": "ページからすべての引用を抽出してください。"
            "何もない場合はnullを使用し、フィールドを発明するのではなく引用を完全に省略してください。",
        },

{"role": "user", "content": page_html},
],
response_format=QuotePage,
)

page = completion.choices[0].message.parsed
print(f"{len(page.quotes)} の引用を抽出しました")

Copy
解析されたページでは、これは1つの検証済みの `Quote` を持つ `QuotePage` を返します — 型付きのPythonオブジェクトであり、まだ `json.loads` して防御する必要がある文字列ではありません。現在のパラメータとスキーマルールは<a href="https://developers.openai.com/api/docs/guides/structured-outputs" rel="nofollow"><strong>OpenAI構造化出力ガイド</strong></a>にあります。

## 高度なパターン

信頼できるエクストラクタとデモを分ける3つの習慣:

- **欠落を表現可能にする。** フィールドが実際のページで欠ける可能性がある場合は、`str | None` として型付けし、システムメッセージでそう言います。必須の文字列だけのスキーマはモデルにギャップを埋めさせることになり、そうなります。
- **モデルにページを少なく提供する。** HTMLチャームはトークンを消費し、注意を散らします。コンテンツコンテナを分離できる場合 — またはページをHTMLではなくマークダウンとして取得する場合 — 抽出が安価でより正確になります。
- **1ページごとに呼び出す。** 10ページを1つのプロンプトにバッチ処理すると、リクエストを節約し、正確性を損ないます:レコードがページ境界を越えて漏れます。ループはPythonに属し、プロンプトには属しません。

ChatGPTをスクレイピングのために使用する古い方法もあります:セレクターベースのスクリプトを書かせて、それを各ページで実行させることです。これは安定したレイアウトでの大量作業には適した呼び出しであり — 生成されたコードは最初のページの後は無料で実行され — 自分が書かなかったコードのようにレビューします。また、次のセクションのすべてのフェッチレイヤー制限を受け継ぎます。

## 正直な限界:ChatGPTはページを取得できません

上記のすべては `page.html` が存在し、忠実であると仮定しました。この仮定が、ChatGPTのみでのスクレイピングが破綻する理由であり、その破綻は再現可能です。単純なHTTP GETはサーバーが送信するバイトを返します — <a href="https://datatracker.ietf.org/doc/html/rfc9110" rel="nofollow"><strong>HTTPセマンティクス仕様</strong></a>によれば、リソースの表現であり、ブラウザがそこから構築するページではありません。JavaScriptでレンダリングされたページでは、非常に異なるドキュメントになります:

```python
# plain_fetch.py — 単純なGETがJSレンダリングされたページで実際に見るもの
import requests

url = "https://quotes.toscrape.com/js/"
resp = requests.get(url, timeout=60)
html = resp.text
print(f"ステータス {resp.status_code} | {len(html):,} 文字")
print("HTML内の引用要素:", html.count('<span class="text"'))

実行結果は ステータス 200 — 完全に成功したリクエスト — で、0 の引用要素です。このデモページでは、引用はJavaScriptエンジンがDOMを構築するまでスクリプト変数の内側にのみ存在します。このHTMLを上記のエクストラクタに渡すと、最良のモデルでも何も抽出できず、あるいは悪化して推測します。

修正は抽出する前にレンダリングすることです。Universal Scraping APIは、同じURLを1つのPOSTで受け取り、js_render を有効にしてサーバー側でページを実行し、リーダーが見るDOMを返します — アンロックとプロキシルーティングが含まれ、ローカルで実行するものはありません:

python Copy
# rendered_fetch.py — 抽出前にサーバー側でレンダリングされた同じURL
import os

import requests

resp = requests.post(
    "https://api.scrapeless.com/api/v1/unlocker/request",
    headers={
        "Content-Type": "application/json",
        "x-api-token": os.environ["SCRAPELESS_API_KEY"],
    },
    json={
        "actor": "unlocker.webunlocker",
        "input": {"url": "https://quotes.toscrape.com/js/", "method": "GET", "js_render": True},
    },
    timeout=120,
)
resp.raise_for_status()
html = resp.json().get("data", "")
print(f"レンダリングされたページ: {len(html):,} 文字")
print("HTML内の引用要素:", html.count('<span class="text"'))

with open("page.html", "w", encoding="utf-8") as f:
    f.write(html)

同じURLで、実行結果は10 の引用要素を8,940文字のレンダリングされたHTML内で出力します — 抽出層がずっと必要としていたファイルです。2つの出力を並べて見ると、単純なフェッチでは0の引用要素、レンダリングされたページでは10の引用要素が得られます。2つのスクリプトを連携させれば、機能するパターンが得られます:Scrapelessを通じてレンダリングし、ChatGPTで抽出します。

無料プランのAPIキーを取得: app.scrapeless.com

トラブルシューティング

  • モデルがJSONではなく散文を返す。 単純な create 呼び出しにいます — response_format モデルで chat.completions.parse に切り替え、出力をAPIレベルで制約します。
  • フィールドが空であるべきところに値が埋まって帰ってくる。 スキーマでフィールドをオプションにし、システムメッセージでnullルールを記述してください。失敗は契約にあり、モデルの気分ではありません。
  • 抽出は一部のページで正しく、他のページでは空です。 ブラウザが表示するものではなく、実際に取得したものを比較してください — プレーンフェッチスクリプトのように取得したHTML内の既知の要素を数えます。ゼロマッチはレンダリングまたはアクセスの問題を意味し、それをプロンプトではなくフェッチレイヤー(js_renderや別の出口国)で修正します。
  • トークンコストはボリュームに比例して上昇します。 呼び出しの前にページをコンテナに絞り込むか、生のHTMLではなくMarkdownから抽出してください。安定した高ボリュームのレイアウトの場合、モデルにセレクタースクリプトを書くようにさせ、レイアウトが変わるときだけトークンを消費させます。

結論

ChatGPTは、スクレイピングのどちらの半分が難しいかを変えました。抽出 — かつて脆弱なセレクターを意味していた部分 — は今やスキーマと1つのSDKコールとなりました。フェッチ — モデルができない部分 — は依然として実際に抽出すべき何かがあるかどうかを決定し、上記の0対10のデモはその境界が実際にどうなるかを示しています。2つのレイヤーを別々に構築し、抽出の前にフェッチを確認し、組み合わせることで再設計に耐えるスクレーパーが完成します。

実際のページを抽出器に供給する準備はできましたか?

このガイドのフェッチレイヤーは、Universal Scraping APIのページごとの1つのPOSTです — プランとリクエストボリュームは価格ページで確認でき、開発者ドキュメントunlocker.webunlockerが受け入れるすべてのパラメータを網羅しています。app.scrapeless.comで無料プランのキーを作成し、自分で2つのフェッチスクリプトを再実行してください。

よくある質問

Q: ChatGPTはウェブサイトを直接スクレイピングできますか?

いいえ。モデルはHTTPリクエストを発行したり、JavaScriptを実行したり、ボット対策を通過したりすることができません — 何か別のもので取得されたテキストから抽出します。消費者向けのチャット製品は、モデルをブラウジングツールでラップすることがありますが、そのツールは小規模で多くのサイトによってブロックされているため、プロダクションセットアップはモデルを専用のフェッチレイヤーとペアにします。

Q: ChatGPTを使ったスクレイピングは合法ですか?

抽出レイヤーはコレクションレイヤーのルールを変更しません。公開ページのみをスクレイピングし、サイトの利用規約やロボット排除プロトコルで定義されたロボットの指令を尊重し、ボリュームを制限し、プライバシー法が適用される範囲内で個人データを扱ってください — これは他のスクレーパーと同じ義務であり、プラスあなたのモデルプロバイダーの利用条件です。

Q: 従来のセレクタースクレーパーがなお良い選択であるのはいつですか?

安定したレイアウトでの高ボリュームの場合です。LLMコールは各ページごとにトークンを消費しますが、セレクタースクリプトは書かれた後は何もコストがかかりません。実際的な分け方: レイアウトが変わる場合や頻繁に変更される場合はモデルを使用し、1つのレイアウトが何千回も繰り返される場合は生成後にレビューしたセレクターコードを使用します。

Q: これは「ChatGPTスクレーパー」とどのように異なりますか?

方向性です。このガイドはモデルをウェブに向けます — ChatGPTはパーサーです。ChatGPTスクレーパーはスクレーパーをChatGPTに向けます — アシスタントの回答、引用、製品結果を構造化データとしてキャッチします。Scrapelessはそれをアクターとして出荷し、導入部でリンクされたChatGPTスクレイパーAPIガイドがそれをカバーしています。

Q: 抽出にはどのOpenAIモデルを使用すればよいですか?

小さくて最新のモデルから始め、抽出品質が要求する場合のみ上位のモデルに移行してください。構造化出力はモデルサイズに関わらず応答の形を制約するため、小さな層はクリーンな入力に対する明確に定義されたスキーマをうまく処理します — 節約した分を使ってさらに多くのページをフェッチしてください。

Scrapelessでは、適用される法律、規制、およびWebサイトのプライバシーポリシーを厳密に遵守しながら、公開されているデータのみにアクセスします。 このブログのコンテンツは、デモンストレーションのみを目的としており、違法または侵害の活動は含まれません。 このブログまたはサードパーティのリンクからの情報の使用に対するすべての責任を保証せず、放棄します。 スクレイピング活動に従事する前に、法律顧問に相談し、ターゲットウェブサイトの利用規約を確認するか、必要な許可を取得してください。

最も人気のある記事

カタログ