De volta ao blog

Grok X Search API: Captura Dados de Postagens do X (Twitter) como JSON Estruturado

Emily Chen
Emily Chen

Advanced Data Extraction Specialist

11-Aug-2026

TL;DR:

  • As respostas do Grok mencionam X posts, e o ator Scrapeless scraper.grok retorna esses posts como um array estruturado separado. x_search_results fica ao lado de web_search_results na mesma carga, então uma solicitação gera tanto as citações da web aberta quanto as citações do X (Twitter) sem qualquer análise HTML.
  • Cada citação do X contém onze chaves, sete das quais chegaram preenchidas em cada captura. post_id, user_name, name, text, create_time, view_count, e profile_image_url estavam não vazias em todas as 167 entradas de post coletadas para este guia; citation_id, community_note, parent, e quote estavam vazias em todas elas.
  • O prompt é a superfície de controle, não um parâmetro de pesquisa. Uma simples pergunta definicional retornou zero chamadas de ferramenta e dois painéis vazios. Prompts que direcionam o Grok para o X retornaram entre 3 e 35 posts.
  • tool_usages expõe a consulta literal X que o Grok executou. O array registra o nome da ferramenta e seus argumentos, para que você possa ler de volta a string de pesquisa exata — incluindo os operadores from:, since:, until:, e min_faves: — que produziu os posts que você recebeu.
  • O painel não é garantido como deduplicado. Chamadas de ferramentas sobrepostas podem repetir posts, e quão frequentemente varia por captura: ao longo de sete capturas a participação de duplicados variou de 0% (18 entradas, 18 valores post_id distintos) a 48% (25 entradas, 13 distintos). Deduplice antes de contar qualquer coisa: duas das sete capturas chegaram sem repetições, e nada na resposta diz qual tipo você recebeu.
  • O modo de raciocínio não controlou a profundidade da fonte X. Dois pares MODEL_MODE_FAST / MODEL_MODE_EXPERT em um prompt idêntico inverteram, então trate o modo como uma configuração de raciocínio em vez de um dial de volume.
  • Gratuito para começar. Novas contas Scrapeless incluem créditos de teste gratuitos — inscreva-se em app.scrapeless.com.

Pergunte ao Grok o que as pessoas estão postando sobre um lançamento de telescópio, e a resposta chega com uma lista de posts do X abaixo. Esses posts são a evidência que o modelo selecionou, e o ator Scrapeless scraper.grok os entrega de volta como linhas JSON com tags de autor, timestamps, contagens de visualizações e IDs de post já separados em campos.

Isso faz do Grok uma rota diferente para dados do X do que a habitual. A abordagem comum puxa posts diretamente da plataforma e visa a completude. Este guia cobre a direção oposta: capturando os posts que um mecanismo de resposta escolheu citar, que é uma fatia menor e já filtrada, além da consulta que o modelo usou para encontrá-los.

Este guia cobre a forma da solicitação, o exato esquema de campo de uma citação do X, como fazer o painel se preencher em vez de chegar vazio, e o array tool_usages que mostra o que Grok realmente pesquisou. Para o contrato de ator geral — envelope, modos, atores acompanhantes — veja o guia da API do scraper Grok.


O que a API de Pesquisa Grok X Oferece

Uma solicitação retorna a resposta do Grok além de seus dois painéis de citação como arrays discretos. O painel do X é a parte sobre a qual este guia se debruça.

  • Linhas em nível de post, não um feed renderizado. Cada entrada é um objeto com um post_id estável, a tag do autor e nome de exibição, o texto do post, um timestamp RFC 3339, e uma contagem de visualizações como um inteiro.
  • A consulta do próprio modelo, registrada. tool_usages preserva a pesquisa emitida pelo Grok, então uma captura é reproduzível e auditável, em vez de ser uma caixa preta.
  • Ambos os painéis de uma chamada. Um prompt que abrange reação social e documentação oficial retorna posts do X e páginas da web aberta na mesma carga, já separadas.
  • Fatias limitadas no tempo. Porque o Grok compõe operadores de data em suas pesquisas do X, prompts que nomeiam uma janela produzem posts dentro dessa janela.
  • Capturas com escopo de conta. Um prompt que nomeia uma conta passa por uma busca de usuário do X e retorna os posts recentes daquela conta.

O painel é um conjunto de citações em vez de um arquivo completo. Ele reflete o que uma resposta se baseou, o que é mais adequado para rastreamento de citações e amostragem de sentimento do que para uma coleção exaustiva.


Endpoint, Ator e Parâmetros

  • Endpoint síncrono: POST https://api.scrapeless.com/api/v2/scraper/execute — bloqueia e retorna o resultado final.
  • Endpoint assíncrono: POST https://api.scrapeless.com/api/v2/scraper/request retorna um task_id; GET https://api.scrapeless.com/api/v2/scraper/result/{task_id} retorna o resultado uma vez que está pronto.
  • Ator: scraper.grok
  • Cabeçalho de autenticação: x-api-token: $SCRAPELESS_API_KEY
campo de entrada necessário descrição
prompt sim a pergunta enviada ao Grok; isso determina se o painel do X se preenche
country sim código de país de duas letras para a saída residencial da execução, por exemplo US
mode sim profundidade de raciocínio — MODEL_MODE_FAST ou MODEL_MODE_EXPERT

As capturas para este guia terminaram em aproximadamente 16 a 60 segundos. O endpoint síncrono é adequado para uma verificação rápida a partir da linha de comando. Para qualquer coisa scriptada, prefira o par assíncrono: ele responde à chamada de envio com HTTP 201 e um task_id, depois retorna o status 202 Accepted definido na especificação de semântica HTTP enquanto a tarefa ainda está em execução e 200 com status: "success" assim que o resultado estiver pronto. A polling para essa transição é o que torna um cliente determinístico, independentemente de quanto tempo um prompt leva.

Mantenha a chave no ambiente em vez de no código:

bash Copy
export SCRAPELESS_API_KEY="your_api_token_here"

Sua Primeira Captura

Esta solicitação nomeia uma conta, que é a maneira mais confiável de obter um painel X populado na primeira tentativa. O filtro jq imprime os dois tamanhos de painel e as ferramentas invocadas pelo 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]
  }'

Uma captura dessa solicitação retornou {"x_posts": 20, "web_pages": 0, "tools": ["x_keyword_search", "x_keyword_search"]} — vinte postagens X, sem páginas da web abertas, e duas pesquisas por palavras-chave. As contagens variam entre as execuções, então trate a forma como o contrato e os números como uma amostra. Se x_posts é 0 e tools está vazio, o Grok respondeu com base em seu próprio conhecimento e não pesquisou nada — veja como fazer o painel X se preencher abaixo.


O Esquema do Post X, Campo por Campo

Cada entrada em x_search_results é um objeto plano com as mesmas onze chaves. Esta é uma captura real da solicitação @NASA acima:

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
}

Ao longo de 167 entradas de postagens capturadas para este guia, os campos se dividiram limpidamente em dois grupos:

campo tipo populado o que contém
post_id string sempre o identificador numérico da postagem, como uma string; a chave primária natural
user_name string sempre o nome do autor — o nome @, sem o @
name string sempre o nome de exibição do autor, que muitas vezes difere do nome de usuário
text string sempre o corpo da postagem, incluindo quebras de linha, menções e t.co links curtos
create_time string sempre timestamp da postagem em o formato de data e hora RFC 3339, UTC, Z-sufixado
view_count integer sempre contagem de visualizações como um número; a faixa observada entre as capturas foi de 0 a 6.937.545
profile_image_url string sempre o avatar do autor, no CDN de imagem da plataforma
citation_id string nunca string vazia em todas as 167 entradas
community_note string nunca string vazia em todas as 167 entradas
parent null nunca null em todas as 167 entradas
quote null nunca null em todas as 167 entradas

Os quatro campos nunca populados merecem uma ressalva. Eles estão presentes no esquema em cada entrada, então o código que os lê não levantará exceções, mas nada neste conjunto de capturas os preencheu. Construa a partir dos sete que chegam populados e trate os outros quatro como reservados, em vez de um recurso de threading de resposta ou Community Notes do qual você pode depender.

user_name e post_id juntos reconstróem uma URL canônica de post como https://x.com/<user_name>/status/<post_id>, o que é útil para armazenar um link de volta à fonte.

Obtenha sua chave de API no plano gratuito: app.scrapeless.com


Lendo a Consulta que o Grok Realmente Executou

tool_usages é o campo que separa esta rota de captura de uma simples busca X. Cada entrada nomeia uma ferramenta e carrega seus argumentos como uma string JSON, então você pode ler exatamente o que foi pesquisado.

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 [])}")

Esse prompt incorpora dois operadores de busca X, e eles sobrevivem na chamada da ferramenta de forma literal:

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

Os operadores que você escreve no prompt se tornam os operadores da consulta. Nas capturas, o Grok compos from:, since:, until:, lang:, e min_faves: em suas pesquisas, junto com uma mode de Top ou Latest. Alguns desses correspondem a a referência de operadores de busca publicada pela plataforma, que lista from: e lang: juntamente com filtros de engajamento; as formas de data-limite since: e until: vêm da interface de busca, em vez daquela referência. Três ferramentas de X distintas apareceram:

| ferramenta | argumentos observados | o que faz |
| x_keyword_search | query, limit, mode | pesquisa de palavras-chave dirigida por operador; mode seleciona Top ou Latest |
| x_semantic_search | query, limit, from_date, to_date, min_score_threshold | pesquisa baseada em significado em uma janela de datas |
| x_user_search | query, count | pesquisa de conta, usada quando um prompt nomeia um identificador |

Duas ferramentas não-X compartilham a matriz: web_search com query e num_results, e open_page com url e start_line, que preenche web_search_results em vez disso.

Registrar tool_usages junto a cada captura transforma um resultado armazenado em algo que você pode explicar depois — as postagens que você manteve, e a consulta que as encontrou.


Um x_search_results vazio não é uma condição de erro. Isso significa que o Grok respondeu sem pesquisar X. A distinção é visível na mesma carga útil: quando o painel está vazio porque nada foi pesquisado, tool_usages também está vazio.

Um prompt definicional simples — "O que é um navegador sem cabeçalho?" — retornou zero chamadas de ferramenta, zero postagens no X e zero páginas da web. Todo prompt que apontou para o X retornou postagens. Medido nas capturas para este guia:

formato do prompt postagens X páginas da web ferramentas invocadas
pergunta definicional simples 0 0 nenhuma
"o que as pessoas estão dizendo no X sobre …" 15 0 palavra-chave × 2, semântico
"o que @account postou recentemente no X" 10 0 palavra-chave, usuário
"o que está em alta no X em …" 10 10 web, semântico, palavra-chave
operadores explícitos, "pesquisar X de:… desde:…" 3 0 palavra-chave
reação social mais fonte oficial 35 16 web × 2, semântico × 3, palavra-chave × 4, open_page

Três padrões de prompt povoaram o painel de forma confiável:

  1. Nomeie a plataforma. "no X" no prompt é o sinal único mais forte.
  2. Nomeie uma conta. Um identificador roteia através de x_user_search e retorna as postagens daquela conta.
  3. Peça por reação, sentimento ou discussão. Esses puxam postagens onde uma pergunta factual seria resolvida pela web aberta.

A última linha faz algo que as outras não fazem. Um prompt que pede tanto a reação social quanto a fonte oficial popula ambos os painéis, então uma chamada retorna o que as pessoas estão postando junto com o que a fonte primária diz.


Manipulação de Saída Estruturada em Python

O painel precisa de uma transformação antes de ser utilizável: desduplicação. Chamadas de ferramenta sobrepostas podem retornar a mesma postagem mais de uma vez, então o comprimento da matriz é um limite superior ao número de postagens distintas, em vez de uma contagem delas. Algumas capturas retornam sem repetições; outras repetem quase metade de suas entradas. Como você não pode saber qual recebeu sem verificar, desduplica incondicionalmente.

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 retorna exatamente a forma que um conjunto de tabela ou coluna de armazém deseja: uma linha por postagem distinta, uma URL resolvível e uma contagem de visualizações em formato inteiro pela qual você pode classificar. A lista é composta por dicionários serializáveis em JSON simples, então cai direto em um DataFrame ou uma instrução de inserção.

Classificar por views antes de amostrar é geralmente o movimento certo, porque o painel mistura contas muito grandes com muito pequenas — a faixa observada em um conjunto de captura variou de 0 a quase 7 milhões de visualizações no mesmo prompt.


Problemas Comuns de Formato de Dados

  • O comprimento da matriz não é a contagem de postagens. Desduplica em post_id antes de contar ou criar gráficos. Medido em sete capturas: 15 entradas / 13 únicas, 35 / 29, 34 / 31, 25 / 13, 15 / 14, e duas capturas que não repetiram nada (10 / 10 e 18 / 18). A parte duplicada não é estável o suficiente para prever — construa a etapa de desduplicação independentemente, porque um número de participação construído com base no comprimento bruto exagera cada conta que duas chamadas de ferramentas destacaram.
  • Quatro campos estão estruturalmente presentes, mas estavam sempre vazios. citation_id, community_note, parent, e quote apareceram em cada entrada e estavam vazios em todos os 167. Não desenhe um recurso de thread de resposta ou Community Notes com base neles sem confirmar se eles se populam para seus prompts.
  • view_count é um inteiro, post_id é uma string. Identificadores de postagens observados aqui ultrapassam 2×10^18, além do intervalo que um float de precisão dupla representa exatamente — por isso a orientação da especificação JSON sobre interoperabilidade numérica adverte contra confiar na precisão numérica entre implementações. Mantenha post_id como texto de ponta a ponta; convertê-lo para um float é como os IDs de postagens silenciosamente mudam de valor.
  • O modo não é um botão de volume. Dois pares de FAST / EXPERT em um mesmo prompt idêntico retornaram 15 contra 20 posts, depois 25 contra 15 — a ordem inverteu. O tamanho do painel variou mais entre duas execuções da mesma configuração do que entre configurações. Mantenha o modo constante por uma série rastreada para consistência metodológica, não porque garante fontes mais profundas.
  • O mesmo prompt retorna um painel diferente a cada execução. Grok recompõe sua consulta a cada execução, então a redação varia e o conjunto de resultados também. Leia uma série em vez de uma única captura e armazene tool_usages para que você possa ver quais execuções fizeram perguntas diferentes.
  • Os painéis se preenchem de forma independente. Um prompt pode preencher o painel X e deixar web_search_results vazio, ou preencher ambos. Verifique o comprimento de cada array separadamente em vez de assumir que um implica o outro.

Conclusão

O painel X em uma captura do Grok é um pequeno conjunto de dados bem tipados que está dentro de uma carga de resposta. Um POST para scraper.grok com um prompt que nomeia X retorna IDs de postagens, handles, nomes de exibição, texto postado, timestamps UTC e contagens de visualizações como JSON simples — sete campos que chegaram preenchidos em cada entrada capturada para este guia. Deduplicate em post_id, mantenha o identificador como uma string e registre tool_usages para que cada linha armazenada carregue a consulta que a encontrou. O resultado cobre uma fatia estreita da plataforma em vez de um arquivo dela: as postagens que um mecanismo de resposta julgou dignas de citação, com a busca que as trouxe à tona anexada.

Comece a Capturar Citações X das Respostas do Grok

Junte-se à nossa comunidade para reivindicar um plano gratuito e comparar notas com desenvolvedores que estão construindo pipelines de mecanismo de resposta: Discord · Telegram.

Inscreva-se em app.scrapeless.com para créditos de teste grátis, em seguida, aponte scraper.grok para as contas, tópicos e janelas que seu programa de monitoramento rastreia. A página do Universal Scraping API cobre a família de atores mais ampla, e os níveis de uso atuais estão na página de preços.

FAQ

Q: Por que x_search_results está vazio na minha solicitação?

Porque o Grok respondeu sem pesquisar X. Verifique tool_usages na mesma carga: se também estiver vazio, nenhuma busca foi realizada. Prompts que nomeiam a plataforma ("no X"), nomeiam uma conta ou perguntam sobre reação e discussão preencheram o painel em cada captura deste guia, enquanto uma simples pergunta definicional retornou zero ferramentas e zero posts.

Q: Quais campos cada post X realmente contém?

Onze chaves, presentes em cada entrada. Sete foram preenchidas em todas as 167 entradas capturadas aqui: post_id, user_name, name, text, create_time, view_count e profile_image_url. Os quatro restantes — citation_id, community_note, parent e quote — estavam vazios em cada um deles.

Q: Posso controlar quais posts X o Grok pesquisa?

Sim, através do prompt. Operadores de busca escritos no prompt se propagam para a consulta que o Grok emite: um prompt contendo from:NASA e since:2026-07-01 produziu a chamada de ferramenta query: from:NASA Artemis since:2026-07-01. Leia tool_usages após cada execução para confirmar o que foi pesquisado.

Q: Como faço para reconstruir um link para o post original?

Combine dois campos sempre preenchidos: https://x.com/<user_name>/status/<post_id>. Mantenha post_id como uma string — é longo o suficiente para perder precisão se um parser JSON o ler como um número de ponto flutuante.

Q: MODEL_MODE_EXPERT retorna mais posts X do que MODEL_MODE_FAST?

Não de forma confiável. Duas execuções pareadas em um prompt idêntico retornaram 15 posts sob FAST e 20 sob EXPERT, então 25 sob FAST e 15 sob EXPERT. A variação de execução para execução foi maior do que a diferença entre modos. Escolha um modo e mantenha-o constante para que uma série rastreada permaneça comparável.

Q: Como isso é diferente de coletar posts diretamente da plataforma?

Escopo e seleção. Essa rota retorna os posts que uma resposta citou — uma amostra editorialmente filtrada, tipicamente de 3 a 35 posts, com a consulta do modelo anexada. A coleta direta almeja a completude. Use isso quando a pergunta for o que um mecanismo de resposta trouxe à tona e creditou; use uma rota de coleta dedicada quando você precisar de uma cobertura exaustiva de uma hashtag ou conta.

Q: O que devo ter em mente sobre os dados do post em si?
O texto das postagens e os nomes dos autores são conteúdos públicos escritos por pessoas reais, portanto, trate uma captura armazenada como um conjunto de dados sobre indivíduos. Mantenha a coleção limitada e com propósito, retenha apenas os campos que sua análise precisa e verifique se o Regulamento Geral sobre a Proteção de Dados da UE ou um regime comparável se aplica ao seu uso, especialmente antes de republicar o texto das postagens ou imagens de perfil. Os termos da plataforma governam o reuso independentemente da lei de proteção de dados; reveja ambos e consulte um advogado para o seu caso específico.

P: Preciso de um proxy?

Não. A saída residencial fixada por país está incorporada ao ator, e a entrada necessária country é toda a configuração.

Na Scorretless, acessamos apenas dados disponíveis ao público, enquanto cumprem estritamente as leis, regulamentos e políticas de privacidade do site aplicáveis. O conteúdo deste blog é apenas para fins de demonstração e não envolve atividades ilegais ou infratoras. Não temos garantias e negamos toda a responsabilidade pelo uso de informações deste blog ou links de terceiros. Antes de se envolver em qualquer atividade de raspagem, consulte seu consultor jurídico e revise os termos de serviço do site de destino ou obtenha as permissões necessárias.

Artigos mais populares

Catálogo