ブログに戻ります

Grok X Search API: 構造化されたJSONとしてX(Twitter)投稿データをキャプチャする

Emily Chen
Emily Chen

Advanced Data Extraction Specialist

11-Aug-2026

TL;DR:

  • Grokの回答はXの投稿を引用し、Scrapeless scraper.grok アクターはそれらの投稿を別の構造化された配列として返します。 x_search_resultsweb_search_resultsの横に同じペイロードにあり、1回のリクエストでオープンウェブの引用とX(Twitter)の引用をHTML解析なしで提供します。
  • 各Xの引用は11のキーを持ち、そのうち7つはすべてのキャプチャで埋められています。 post_iduser_namenametextcreate_timeview_countprofile_image_urlは、このガイドのために収集された167の投稿エントリ全てで空でなく、citation_idcommunity_noteparentquoteはすべてにおいて空でした。
  • プロンプトは制御サーフェスであり、検索パラメータではありません。 単純な定義的な質問はツールコールと空のパネルをゼロで返しました。GrokをXに指向させるプロンプトは、3から35の投稿を返しました。
  • tool_usagesはGrokが実行したリテラルXクエリを公開します。 配列はツール名とその引数を記録しているので、受け取った投稿を生成した正確な検索文字列 — from:since:until:、およびmin_faves:オペレーターを含む — を読み取ることができます。
  • パネルは重複がないことが保証されていません。 重複するツールコールは投稿を繰り返す可能性があり、その頻度はキャプチャごとに異なります: 7回のキャプチャで重複率は0%(18エントリ、18の異なるpost_id値)から48%(25エントリ、13の異なる)まで変動しました。何かをカウントする前に重複を除去してください: 7回のキャプチャのうち2回は繰り返しがなく、応答内の情報はどの種類を受け取ったかを示しません。
  • 推論モードはXのソース深度を制御しませんでした。 同一プロンプトの2つの MODEL_MODE_FAST / MODEL_MODE_EXPERT ペアは逆転したため、モードは音量ノブではなく推論設定として扱ってください。
  • 無料で開始可能。 新しいScrapelessアカウントには無料トライアルクレジットが含まれています — app.scrapeless.com でサインアップしてください。

Grokに天体望遠鏡の打ち上げについて人々が何を投稿しているかを尋ねると、回答にはその下にXの投稿のリストが付いてきます。これらの投稿はモデルが選択した証拠であり、Scrapeless scraper.grok アクターはそれらを著者のハンドル、タイムスタンプ、ビューカウント、および投稿IDをすでにフィールドに分けたJSON行として返します。

これにより、Grokは通常とは異なるXデータへのルートを提供します。一般的なアプローチはプラットフォームから直接投稿を取得し、完全性を目指しています。このガイドでは、回答エンジンが引用する投稿をキャプチャする逆方向を扱っており、これは小型で既にフィルタリングされたスライスであり、さらに投稿を見つけるためにモデルが使用したクエリも含まれます。

このガイドでは、リクエストの形状、Xの引用の正確なフィールドスキーマ、パネルが空ではなくポピュレートされる方法、Grokが実際に検索した内容を示すtool_usages 配列について説明します。一般的なアクター契約 — エンベロープ、モード、コンパニオンアクター — については、GrokスクレイパーAPIガイドを参照してください。


1回のリクエストでGrokの回答とその2つの引用パネルが個別の配列として返されます。Xパネルはこのガイドが扱う部分です。

  • 投稿レベルの行、レンダリングされたフィードではない。 各エントリは安定したpost_idを持つオブジェクトであり、著者のハンドルと表示名、投稿テキスト、RFC 3339タイムスタンプ、および整数としてのビューカウントが含まれています。
  • モデル自身のクエリが記録されています。 tool_usagesはGrokが発行した検索を保持するため、収集は再現可能で監査可能であり、ブラックボックスではありません。
  • 1回のコールで両方のパネル。 社会的反応と公式文書を横断するプロンプトは、同じペイロード内でXの投稿とオープンウェブのページを返し、すでに分けられています。
  • 時間制限のあるスライス。 Grokが日付オペレーターをX検索に組み込むため、ウィンドウを指定したプロンプトはそのウィンドウ内の投稿を生成します。
  • アカウントスコープのキャプチャ。 アカウントを指定するプロンプトはXユーザーのルックアップを経て、そのアカウントの最近の投稿を返します。

パネルは完全なアーカイブではなく引用セットです。それは1つの回答が何に基づいているかを反映しており、引用の追跡や感情のサンプリングには、徹底的な収集よりも適しています。


エンドポイント、アクター、およびパラメータ

  • 同期エンドポイント: POST https://api.scrapeless.com/api/v2/scraper/execute — ブロックして終了した結果を返します。
  • 非同期エンドポイント: POST https://api.scrapeless.com/api/v2/scraper/requesttask_id を返します; GET https://api.scrapeless.com/api/v2/scraper/result/{task_id} は結果が準備でき次第返します。
  • アクター: scraper.grok
  • 認証ヘッダー: x-api-token: $SCRAPELESS_API_KEY
入力フィールド 必須 説明
prompt はい Grokに送信された質問; これがXパネルがポピュレートされるかどうかを決定します
country はい 実行の居住出口の2文字の国コード、例えばUS
mode はい 推論の深さ — MODEL_MODE_FAST または MODEL_MODE_EXPERT

このガイドのキャプチャは約16〜60秒で終了しました。同期待機はコマンドラインからのクイックチェックに適しています。スクリプト化されたものには非同期ペアを好んでください:これはHTTP 201とtask_idでサブミットコールに応答し、タスクがまだ実行中の間にHTTPセマンティクス仕様で定義された202 Acceptedステータスを返し、結果が準備できると200とstatus: "success"を返します。その遷移をポーリングすることが、クライアントを決定的にする要因です。

コード内ではなく環境内にキーを保持します:

bash Copy
export SCRAPELESS_API_KEY="your_api_token_here"

あなたの最初のキャプチャ

このリクエストはアカウントに名前を付け、初回に populated X パネルを取得する最も信頼できる方法です。jqフィルターは2つのパネルサイズとGrokが呼び出したツールを印刷します。

bash Copy
curl -sS -X POST https://api.scrapeless.com/api/v2/scraper/execute \
  -H "Content-Type: application/json" \
  -H "x-api-token: ${SCRAPELESS_API_KEY}" \
  -d '{
    "actor": "scraper.grok",
    "input": {
      "prompt": "What has @NASA posted on X recently?",
      "country": "US",
      "mode": "MODEL_MODE_FAST"
    }
  }' | jq '{
    x_posts: (.task_result.x_search_results | length),
    web_pages: (.task_result.web_search_results | length),
    tools: [.task_result.tool_usages[].tool_name]
  }'

そのリクエストの1回のキャプチャは{"x_posts": 20, "web_pages": 0, "tools": ["x_keyword_search", "x_keyword_search"]}を返しました — 20件のXポスト、オープンウェブページなし、2件のキーワード検索。カウントは実行ごとに変動するため、形状を契約と見なし、数字をサンプルとして扱います。もしx_posts0toolsが空の場合、Grokは自身の知識から応答し、何も検索しなかったということになります — 下記のmaking the X panel populateを参照してください。


Xポストスキーマ、フィールドごとに

x_search_resultsのすべてのエントリは、同じ11のキーを持つフラットなオブジェクトです。これは上記の@NASAリクエストからの1つの実際のキャプチャです:

json Copy
// captured from a live scraper.grok run; a single x_search_results entry
{
  "citation_id": "",
  "community_note": "",
  "create_time": "2026-08-06T11:00:59Z",
  "name": "NASA",
  "parent": null,
  "post_id": "2085320225776427457",
  "profile_image_url": "https://pbs.twimg.com/profile_images/1321163587679784960/0ZxKlEKB_normal.jpg",
  "quote": null,
  "text": "LIVE: Time for a spacewalk! Watch as @Astro_Jessica and @Astro_Anil step outside the @Space_Station to prepare the orbiting lab for a new solar array.",
  "user_name": "NASA",
  "view_count": 714862
}

このガイドのためにキャプチャされた167のポストエントリ全体で、フィールドは2つのグループにきれいに分かれます:

フィールド タイプ populated 保持しているもの
post_id 文字列 いつも 数字のポスト識別子(文字列として);自然な主キー
user_name 文字列 いつも 著者のハンドル — @名(@なし)
name 文字列 いつも 著者の表示名は、しばしばハンドルとは異なります
text 文字列 いつも 投稿本体、改行、メンション、t.coショートリンクを含む
create_time 文字列 いつも RFC 3339日付と時刻形式の投稿タイムスタンプ、UTC、Z-サフィックス
view_count 整数 いつも 数字としてのビューカウント;キャプチャ全体で観察された範囲は0から6,937,545まで
profile_image_url 文字列 いつも プラットフォームの画像CDN上の著者のアバター
citation_id 文字列 決して すべての167エントリで空の文字列
community_note 文字列 決して すべての167エントリで空の文字列
parent null 決して すべての167エントリでnull
quote null 決して すべての167エントリでnull

決して populated でない4つのフィールドは注意が必要です。これらはすべてのエントリのスキーマに存在しますので、それらを読み取るコードは例外を発生させませんが、このキャプチャセットでは何も埋まりませんでした。 populatedと到着する7つのフィールドを基に構築し、他の4つは信頼できる返信スレッドやコミュニティノート機能としてではなく予約済みと見なしてください。

user_namepost_idが一緒にhttps://x.com/<user_name>/status/<post_id>として標準のポストURLを再構成します。これはソースへのリンクを保存するのに役立ちます。

無料プランであなたのAPIキーを取得してください: app.scrapeless.com


Grokが実際に実行したクエリの読み取り

tool_usagesは、このキャプチャルートを通常のX検索から分けるフィールドです。各エントリはツールに名前を付け、その引数をJSON文字列として保持しますので、何が検索されたのか正確に読み返すことができます。

python Copy
import json
import os
import time

import requests

BASE = "https://api.scrapeless.com/api/v2/scraper"
HEADERS = {
    "Content-Type": "application/json",
    "x-api-token": os.environ["SCRAPELESS_API_KEY"],
}


def capture(prompt, country="US", mode="MODEL_MODE_FAST"):
    """Submit a Grok capture, then poll until the task_result is ready."""
    submit = requests.post(
        f"{BASE}/request",
        headers=HEADERS,
        json={
            "actor": "scraper.grok",
            "input": {"prompt": prompt, "country": country, "mode": mode},
        },
        timeout=60,
    )
    submit.raise_for_status()
    task_id = submit.json()["task_id"]

    for _ in range(120):
        poll = requests.get(f"{BASE}/result/{task_id}", headers=HEADERS, timeout=60)
        poll.raise_for_status()
        body = poll.json()
        if body.get("status") == "success":
            return body["task_result"]
        time.sleep(5)
    raise TimeoutError(f"task {task_id} did not finish in the allotted window")


result = capture("Search X for posts from:NASA about Artemis since:2026-07-01 and summarize them.")

for call in result.get("tool_usages") or []:
    print(call["tool_name"])
    for key, value in json.loads(call["tool_args"]).items():
        print(f"    {key}: {value}")

print(f"x_search_results: {len(result.get('x_search_results') or [])}")

そのプロンプトは2つのX検索オペレーターを埋め込んでおり、それらはツールコールにそのまま生き残ります:

text Copy
x_keyword_search
    query: from:NASA Artemis since:2026-07-01
    limit: 10
    mode: Latest
x_search_results: 3

あなたがプロンプトに書くオペレーターは、クエリのオペレーターになります。キャプチャ全体で、Grokはfrom:since:until:lang:min_faves:を検索に組み込みました。modeTopまたはLatestTopの組み合わせがあります。それらの一部はプラットフォームの公開された検索オペレーターリファレンスに合致し、from:lang:をエンゲージメントフィルターとともにリストします。日付境界since:until:形式は、そのリファレンスではなく検索インターフェースから来ています。3つの異なるXツールが登場しました:

ツール 観察された引数 何をするのか
x_keyword_search querylimitmode オペレータ主導のキーワード検索; modeTop または Latest を選択します
x_semantic_search querylimitfrom_dateto_datemin_score_threshold 日付ウィンドウを通じた意味ベースの検索
x_user_search querycount アカウント参照、プロンプトがハンドルを指定する場合に使用されます

二つの非Xツールは配列を共有しています: web_searchquery および num_results と、open_pageurl および start_line と、web_search_results を埋める別の役割を果たします。

tool_usages をすべてのキャプチャと共に記録することで、保存された結果が後に説明できるものになります — 保存した投稿と、それらを見つけたクエリです。


Xパネルを人口にする

空の x_search_results はエラー条件ではありません。それはGrokがXを検索せずに回答したことを意味します。その区別は同じペイロードに明確に表れます: パネルが何も検索されなかったために空である場合、tool_usages も空です。

単純な定義プロンプト — 「ヘッドレスブラウザーとは?」 — はツール呼び出しゼロ、X投稿ゼロ、ウェブページゼロを返しました。Xを指すすべてのプロンプトは投稿を返しました。このガイドのキャプチャにわたる測定結果は:

プロンプト形状 X投稿 ウェブページ 呼び出されたツール
単純な定義質問 0 0 なし
「Xで…について人々が何を言っているか」 15 0 キーワード × 2、意味論
「@accountが最近Xに投稿したものは何か」 10 0 キーワード、ユーザー
「Xで…のトレンドとは何か」 10 10 ウェブ、意味論、キーワード
明示的オペレーター、「from:… since:…でXを検索」 3 0 キーワード
社会的反応と公式ソース 35 16 ウェブ × 2、意味論 × 3、キーワード × 4、open_page

三つのプロンプトパターンがパネルを信頼性高く埋めました:

  1. プラットフォームを名付ける。 プロンプト中の「on X」 は最も強いシグナルです。
  2. アカウントを名付ける。 ハンドルは x_user_search を経由して、そのアカウントの投稿を返します。
  3. 反応、感情、または議論を求める。 これらは、事実に基づく質問がオープンウェブから解決される投稿を引き出します。

最後の行は他の行が行わないことをします。社会的反応と公式ソースの両方を求めるプロンプトは両方のパネルを埋めるので、一つの呼び出しで人々が投稿している内容と主要なソースが言っていることの両方を返します。


Pythonにおける構造化出力処理

パネルは使用可能になる前に一つの変換が必要です: 重複排除。重複するツール呼び出しは同じ投稿を複数回返す可能性があるため、配列の長さは異なる投稿の数の上限を示すものであって、数えたものとは異なります。一部のキャプチャは全く重複がない場合もありますし、他はほぼ半分を繰り返します。どちらを得たかわからないので、無条件に重複を排除します。

python Copy
import json
import os
import time

import requests

BASE = "https://api.scrapeless.com/api/v2/scraper"
HEADERS = {
    "Content-Type": "application/json",
    "x-api-token": os.environ["SCRAPELESS_API_KEY"],
}


def capture(prompt, country="US", mode="MODEL_MODE_FAST"):
    """Submit a Grok capture, then poll until the task_result is ready."""
    submit = requests.post(
        f"{BASE}/request",
        headers=HEADERS,
        json={
            "actor": "scraper.grok",
            "input": {"prompt": prompt, "country": country, "mode": mode},
        },
        timeout=60,
    )
    submit.raise_for_status()
    task_id = submit.json()["task_id"]
    print(f"submitted task_id={task_id}")

    for _ in range(120):
        poll = requests.get(f"{BASE}/result/{task_id}", headers=HEADERS, timeout=60)
        poll.raise_for_status()
        body = poll.json()
        if body.get("status") == "success":
            return body["task_result"]
        time.sleep(5)
    raise TimeoutError(f"task {task_id} did not finish in the allotted window")


def x_rows(task_result):
    """Flatten x_search_results into unique rows keyed by post_id."""
    seen, rows = set(), []
    for post in task_result.get("x_search_results") or []:
        post_id = post.get("post_id")
        if not post_id or post_id in seen:
            continue
        seen.add(post_id)
        handle = post.get("user_name") or ""
        rows.append(
            {
                "post_id": post_id,
                "handle": handle,
                "display_name": post.get("name") or "",
                "posted_at": post.get("create_time") or "",
                "views": post.get("view_count") or 0,
                "text": " ".join((post.get("text") or "").split()),
                "url": f"https://x.com/{handle}/status/{post_id}",
            }
        )
    return rows


result = capture("What are people saying on X about the James Webb Space Telescope this week?")
rows = x_rows(result)

raw_count = len(result.get("x_search_results") or [])
print(f"raw={raw_count} unique={len(rows)}")

for row in sorted(rows, key=lambda r: r["views"], reverse=True)[:3]:
    print(f"@{row['handle']} · {row['posted_at']} · {row['views']:,} views")
    print(f"  {row['text'][:100]}")
    print(f"  {row['url']}")

print(json.dumps(rows[:1], ensure_ascii=False, indent=2))

x_rows は、テーブルまたは倉庫列セットが欲しい正確な形状を返します: 異なる投稿ごとに一行、解決可能なURL、ソート可能な整数ビューカウントです。リストはプレーンなJSONシリアライズ可能な辞書なので、DataFrameまたは挿入ステートメントに直ちに入ることができます。

サンプリングの前に views でソートするのは通常正しい処置です。なぜなら、パネルは非常に大きなアカウントと非常に小さなアカウントを混在させるからです — 一つのキャプチャセットにおける観測された範囲は同じプロンプトに対して0からほぼ700万回のビューに及びます。


一般的なデータ形式の問題

  • 配列の長さは投稿数ではありません。 post_id で重複を排除してから数えたりチャートを作成したりしてください。七つのキャプチャにわたる測定結果: 15エントリー / 13ユニーク、35 / 29、34 / 31、25 / 13、15 / 14、何も繰り返さない二つのキャプチャ (10 / 10 と 18 / 18)。重複の割合は予測するには安定していないため — 重複排除のステップを組み込んでください。生の長さに基づく声のシェアは、二つのツール呼び出しの両方で取り上げられたアカウントを過大評価します。
  • 四つのフィールドが構造的に存在しますが、常に空でした。 citation_idcommunity_noteparent、および quote はすべてのエントリーに現れ、167すべてで空でした。これらに基づいて返信スレッドやコミュニティノート機能を設計しないでください、プロンプトに対してこれらが埋められることを確認しない限り。
  • view_count は整数、post_id は文字列です。 ここで観察された投稿識別子は 2×10^18 を超え、倍精度浮動小数点が正確に表現できる範囲を超えています — これは JSON仕様の数値相互運用性に関するガイダンス が実装間での数値精度に依存しないよう警告しています。post_id はテキストとして最初から最後まで保持してください; 浮動小数点にキャストすると投稿IDが静かに値を変えてしまいます。
  • モードは音量ダイヤルではありません。 同一のプロンプトでの二つの FAST / EXPERT ペアは、15対20の投稿数を返し、その後25対15になりました — 順序が逆転しました。同じ設定の二回の実行間でのパネルサイズの変動は、設定間の変動よりも大きかったです。方法論的一貫性のために追跡されたシリーズ全体でモードを一定に保ちます。これは、より深い情報ソースを保証するためではありません。
  • 同じプロンプトが毎回異なるパネルを返します。 Grokは実行ごとにクエリを再構成するため、言葉遣いが変わり、結果セットも変わります。単一のキャプチャではなく、一連のデータを読み取るようにし、どの実行が異なる質問をしたかを見るために tool_usages を保存してください。
  • パネルは独立して構成されます。 プロンプトがXパネルを埋めて web_search_results を空のままにすることも、両方を埋めることもできます。一方が他方を暗示することを仮定せず、各配列の長さを別々に確認してください。

結論

GrokキャプチャのXパネルは、回答ペイロード内にある小さく、型に合ったデータセットです。Xを名付けたプロンプトに POSTscraper.grok を渡すと、投稿ID、ハンドル、表示名、投稿テキスト、UTCタイムスタンプ、ビューカウントなどを含むフラットなJSONが返されます — このガイドでキャプチャされたすべてのエントリに満たされて到着した7つのフィールドです。 post_id で重複を排除し、識別子を文字列として保持し、tool_usages をログに記録して、各保存された行がそれを見つけたクエリを持つようにします。この結果は、プラットフォームの狭いスライスをカバーしており、アーカイブではありません:回答エンジンが引用する価値があると判断した投稿であり、それを引き出した検索が付随しています。

Grokの回答からX引用をキャプチャする開始

無料プランを主張し、回答エンジンパイプラインを構築している開発者とメモを比較するために、私たちのコミュニティに参加してください: Discord · Telegram

app.scrapeless.com に登録して無料トライアルクレジットを受け取り、その後あなたのモニタリングプログラムが追跡しているアカウント、トピック、ウィンドウに scraper.grok を向けてください。Universal Scraping API ページは広範なアクターファミリーをカバーしており、現在の使用ティアは pricing ページにあります。

FAQ

Q: なぜ x_search_results が私のリクエストで空ですか?

GrokがXを検索せずに回答したためです。同じペイロード内の tool_usages を確認してください: それも空であれば、検索はまったく実行されていません。プラットフォームを名付けるプロンプト(「X上で」)、アカウントを名付けるか、反応や議論について尋ねるプロンプトは、このガイドでのすべてのキャプチャでパネルを埋めましたが、単純な定義質問はゼロのツールとゼロの投稿を返しました。

Q: 各X投稿には実際にどのフィールドが含まれていますか?

11のキーがあり、すべてのエントリに存在します。167件のキャプチャされたエントリのすべてに満たされた7つのフィールドがありました: post_id, user_name, name, text, create_time, view_count, profile_image_url。残りの4つ — citation_id, community_note, parent, quote — はすべて空でした。

Q: Grokが検索するX投稿を制御できますか?

はい、プロンプトを通じて可能です。プロンプトに書かれた検索オペレーターはGrokが発行するクエリに伝播します: from:NASAsince:2026-07-01 を含むプロンプトは、ツール呼び出し query: from:NASA Artemis since:2026-07-01 を生成しました。検索された内容を確認するために、各実行後に tool_usages を読むことをお勧めします。

Q: 元の投稿へのリンクを再構築するにはどうすればよいですか?

常に満たされる2つのフィールドを組み合わせます: https://x.com/<user_name>/status/<post_id>post_id を文字列として保持します — それは浮動小数点数として読み取ると精度を失うほど長いです。

Q: MODEL_MODE_EXPERTMODEL_MODE_FAST よりも多くのX投稿を返しますか?

安定してはありません。同一のプロンプトでペアにした二つの実行は FAST の下で15投稿を、 EXPERT の下で20投稿を返し、その後 FAST の下で25投稿、 EXPERT の下で15投稿を返しました。実行間の変動は、モード間の違いよりも大きかったです。1つのモードを選択し、それを一定に保って追跡されたシリーズが比較可能であるようにします。

Q: これはプラットフォームから直接投稿を収集することとどう違いますか?

範囲と選択です。このルートは、回答が引用した投稿を返します — 編集によってフィルタリングされたサンプルで、通常は3から35投稿であり、モデルのクエリが添付されています。直接収集は、むしろ完全性を目指します。回答エンジンが表面化させた内容を尋ねるときにはこの方法を使用し、ハッシュタグやアカウントの徹底的なカバレッジが必要なときには専用の収集ルートを使用します。

Q: 投稿データ自体について何を考慮すべきですか?
投稿テキストと著者名は実在の人物によって著作された公的なコンテンツであるため、保存されたキャプチャを個人に関するデータセットとして扱います。収集は制約を持ち、目的に沿ったものであるべきで、分析に必要なフィールドだけを保持し、EU一般データ保護規則または同等の制度が使用に適用されるかどうかを確認してください。特に、投稿テキストやプロファイル画像を再発行する前に確認することが重要です。プラットフォームの利用規約はデータ保護法とは独立して再利用を規定します。両方を確認し、特定のケースについては法律顧問に相談してください。

Q: プロキシは必要ですか?

いいえ。国に固定された居住者の出口はアクターに組み込まれており、必要なcountry入力は全体の構成です。

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

最も人気のある記事

カタログ