Voltar ao blogue
Guias
Raluca PenciucLast updated on May 8, 202614 min read

Como fazer scraping do Realtor.com: Um guia prático para 2026

Como fazer scraping do Realtor.com: Um guia prático para 2026
Resumo: Se está a tentar descobrir como extrair dados do Realtor.com de forma eficaz, há três aspetos fundamentais: seletores estáveis que resistam aos nomes de classe com hash, uma camada de pedidos capaz de contornar o sistema anti-bot do Realtor e código que percorra tanto as páginas de listagem como as de detalhes. Este guia apresenta a implementação completa em Python, incluindo táticas anti-bloqueio e exportações preparadas para LLM.

Se precisas de dados imobiliários em grande escala, aprender a fazer scraping do Realtor.com é uma das competências de maior impacto que podes adquirir. O Realtor.com é um importante mercado imobiliário dos EUA, com listagens de casas para venda, arrendamento e informações em tempo real sobre o mercado imobiliário, e a maior parte desses dados é apresentada em HTML que podes analisar com Python.

O problema é que o Realtor.com é um alvo de alto valor com uma pilha anti-bot reforçada. Chamadas requests.get() retornam HTML CAPTCHA, nomes de classes com hash mudam sem aviso prévio e os campos mais ricos ficam escondidos dentro de blobs JSON incorporados. A cadeia de ferramentas errada pode levar uma semana antes de produzir uma única linha limpa.

Este guia percorre todo o processo de construção em Python de ponta a ponta: quais os campos que pode realmente extrair, os seletores que sobrevivem à renderização React do Realtor.com, como encaminhar pedidos através de uma API de scraping que gere proxies e CAPTCHAs por si, e como extrair dados da página de detalhes, como contactos de agentes, comodidades e latitude/longitude. Abordaremos a limitação de tráfego, o tratamento de erros, os limites legais e como alimentar listagens num LLM para análise a jusante.

Vais sair daqui com um scraper funcional, não com um snippet copiado e colado que avaria na próxima vez que o front-end for lançado.

Porquê fazer scraping do Realtor.com e para que servem os dados às equipas

Saber como fazer scraping do Realtor.com abre uma longa lista de casos de uso práticos. Equipas de investimento extraem anúncios para análises de propriedades comparáveis e treino de AVM. Corretoras buscam a geração de leads, identificando propriedades expiradas ou relistadas antes dos concorrentes. Os investigadores de mercado acompanham as tendências de inventário e preços, código postal a código postal. Os engenheiros de Proptech introduzem anúncios em pipelines de LLM para enriquecimento. O fio condutor: os anúncios do Realtor.com são atualizados constantemente, pelo que a recolha manual falha após um punhado de imóveis, e o scraping estruturado é a única forma sensata de acompanhar o ritmo.

Campos de dados do Realtor.com que pode extrair de forma realista

A maioria dos tutoriais limita-se a seis campos. É possível extrair muito mais percorrendo tanto os resultados de pesquisa como as páginas de detalhes. A partir de um cartão de resultados de pesquisa, os campos fiáveis são o preço de venda, a morada completa, o número de quartos, o número de casas de banho, a área útil, a dimensão do lote, o estado do anúncio e o URL canónico da página de detalhes.

Siga cada URL de detalhes e poderá extrair:

  • Informações sobre o imóvel: ano de construção, tipo de imóvel, taxas de condomínio, estacionamento, dimensões do lote
  • Comodidades: aquecimento, arrefecimento, pavimentos, eletrodomésticos, características exteriores
  • Geografia: latitude e longitude (útil para mapeamento e junções ao nível do código postal)
  • Multimédia: URLs de imagens da galeria de fotos do anúncio
  • Agente: nome do agente, número de telefone e agência imobiliária
  • Metadados do anúncio: ID MLS, dias no mercado, histórico de preços

Este é o conjunto de dados que alimenta comparações, listas de leads e AVMs, não apenas um conjunto de preços e endereços.

O panorama anti-bot do Realtor.com: o que irá realmente encontrar

Antes de escrever código de scraper, compreenda o que vai enfrentar. O Realtor.com utiliza uma pilha anti-bot comportamental que vai muito além do bloqueio de IP. Relatórios de engenharia reversa atribuem a proteção a uma pilha de impressão digital do tipo Kasada; quer a Kasada seja ou não o fornecedor atual, os sinais de deteção estão bem documentados no espaço da proteção contra bots.

Três camadas são importantes ao aprender a fazer scraping do Realtor.com em volume significativo:

  1. Identificação de impressão digital TLS e JS. O Python simples requests envia um handshake TLS e uma ordem de cabeçalhos que não correspondem aos navegadores reais, o que a borda do Realtor.com pode sinalizar logo à primeira visita.
  2. Correlação comportamental. Proxies de entropia do rato, padrões de deslocamento e sinais de interação DOM são avaliados em relação às distribuições humanas. Um scraper a martelar páginas a partir de um único IP não se parece em nada com um humano.
  3. Páginas CAPTCHA. Quando a sua pontuação ultrapassa o limiar, o corpo da página transforma-se numa página de desafio em vez de listagens, frequentemente com um código de estado 200, pelo que um scraper ingênuo nem sequer percebe que falhou.

Planeie para as três situações desde o primeiro dia, em vez de as adicionar à pressa após o primeiro lote de linhas vazias.

Escolher a abordagem de scraping certa para o seu projeto

Não existe uma resposta única e correta sobre como fazer scraping do Realtor.com, mas vale a pena conhecer três abordagens, e cada uma se adequa a um caso de uso diferente.

Abordagem

Ideal para

Vantagens e desvantagens

requests + uma API de scraping

Pipelines de backend, tarefas de dados de produção

Mais rápido e mais barato se a sua API suportar renderização JS e proxies

Selenium com undetected-chromedriver

Páginas que requerem interação real com o navegador ou fluxos de login

Custo mais elevado por página, mais difícil de escalar, continua a encontrar CAPTCHAs ao longo do tempo

Scrapers visuais sem código

Analistas a extrair algumas centenas de listagens de forma pontual

Frágil quando os nomes das classes mudam; não é ideal para pipelines programados

Recomendação rápida: se é uma equipa de Python a construir um feed de dados recorrente, utilize requests além de uma API de scraping e analise o HTML com o BeautifulSoup, que é o que este guia faz. Recorra a um navegador headless apenas quando precisar genuinamente de interagir com uma visualização que exija login ou seja fortemente orientada a JS, e trate os scrapers visuais sem código como auxiliares pontuais, em vez de infraestrutura de produção.

Pré-requisitos e configuração do projeto

Antes de entrarmos em como fazer scraping do Realtor.com de ponta a ponta, configure um ambiente limpo. Vai precisar do Python 3.9 ou mais recente, um virtualenv novo e quatro pacotes:

python -m venv .venv && source .venv/bin/activate
pip install requests beautifulsoup4 lxml pandas

Também vai precisar de uma chave API de scraping. Vamos usar o WebScrapingAPI como camada de pedidos neste guia; registe-se, copie a sua chave do painel de controlo e guarde-a como uma variável de ambiente para que nunca vá parar ao git:

export WSA_KEY="your_key_here"

E é tudo. Sem drivers de navegador, sem listas de proxy para gerir.

Como fazer scraping do Realtor.com com Python, passo a passo

Agora vamos construir o scraper propriamente dito em cinco passos específicos: inspecionar o DOM e identificar seletores estáveis, buscar páginas de pesquisa através da API de scraping, analisar cartões de listagem com o BeautifulSoup, percorrer resultados paginados e exportar para JSON, CSV ou um DataFrame do pandas. Os blocos de código abaixo pressupõem a configuração da secção anterior.

Inspecione os anúncios e mapeie os seus seletores CSS

Abra os resultados de pesquisa do Realtor.com no Chrome, clique com o botão direito do rato num cartão de anúncio e selecione Inspecionar. Cada cartão está envolvido num <li> com data-testid="result-card". O preço, a morada e os campos meta encontram-se dentro de <div>s e <li>s, cada um com os seus próprios data-label atributos (pc-price, pc-address, pc-meta-beds, e assim por diante).

O Realtor.com também associa cada cartão a uma classe com hash, como BasePropertyCard_propertyCardWrap__abc123. Não selecione com base no hash. Esses sufixos são regenerados em cada compilação do front-end e irão danificar o seu scraper sem aviso prévio. Ancore em data-testid e data-label sempre que possível. Estão lá explicitamente para os próprios testes do front-end, o que os torna os ganchos mais estáveis de que dispõe.

Recupere páginas de pesquisa através da WebScrapingAPI

Com os seletores mapeados, encaminhe o pedido real através da API de scraping. A API trata da rotação de proxies residenciais, da renderização de JS e do tratamento de CAPTCHA, para que o seu código se mantenha focado na análise.

import os, requests

WSA_KEY = os.environ["WSA_KEY"]
SEARCH_URL = "https://www.realtor.com/realestateandhomes-search/Cincinnati_OH"

def fetch(url: str) -> str:
    r = requests.get(
        "https://api.webscrapingapi.com/v2",
        params={
            "api_key": WSA_KEY,
            "url": url,
            "render_js": "1",
            "country": "us",
        },
        timeout=60,
    )
    r.raise_for_status()
    return r.text

html = fetch(SEARCH_URL)

Porquê encaminhar através de uma API no Realtor.com especificamente? Um requests.get vai encontrar uma página de CAPTCHA após algumas chamadas, porque a impressão digital TLS e a ordem dos cabeçalhos não correspondem a um navegador real. A API normaliza ambos para si e alterna o IP residencial por pedido.

Analise os cartões de listagem com o BeautifulSoup

Com o HTML em mãos, o BeautifulSoup transforma-o em algo que pode consultar. Seja cauteloso: nem todos os cartões contêm todos os campos, por isso proteja cada pesquisa para que a falta de um único campo de área do lote não comprometa toda a linha.

from bs4 import BeautifulSoup

def parse_cards(html: str) -> list[dict]:
    soup = BeautifulSoup(html, "lxml")
    cards = soup.select('li[data-testid="result-card"]')
    listings = []
    for card in cards:
        def text(sel):
            el = card.select_one(sel)
            return el.get_text(strip=True) if el else None
        link = card.select_one("a[data-testid='card-link']")
        listings.append({
            "price":    text('[data-label="pc-price"]'),
            "address":  text('[data-label="pc-address"]'),
            "beds":     text('[data-label="pc-meta-beds"] span'),
            "baths":    text('[data-label="pc-meta-baths"] span'),
            "sqft":     text('[data-label="pc-meta-sqft"] span'),
            "lot_size": text('[data-label="pc-meta-sqftlot"] span'),
            "url": link["href"] if link and link.has_attr("href") else None,
        })
    return listings

Usaremos o url campo em breve para seguir cada anúncio até à sua página de detalhes. Se preferir usar o BeautifulSoup de forma mais aprofundada, o nosso guia de análise do BeautifulSoup em Python é uma leitura complementar sólida.

Percorra os resultados paginados

O Realtor.com pagina com um /pg-N padrão de URL, e cada página de resultados devolve cerca de 42 cartões (o número exato varia, por isso não o considere como uma condição de paragem). A estratégia mais robusta combina um contador de páginas com uma verificação de resultados vazios:

def scrape_search(base_url: str, max_pages: int = 10) -> list[dict]:
    all_listings = []
    for page in range(1, max_pages + 1):
        page_url = base_url if page == 1 else f"{base_url}/pg-{page}"
        cards = parse_cards(fetch(page_url))
        if not cards:
            break
        all_listings.extend(cards)
    return all_listings

Parar quando uma página devolve zero cartões é muito mais seguro do que confiar em qualquer contagem fixa por página.

Exportar resultados para JSON, CSV ou um DataFrame

Depois de recolher os anúncios, processe-os através do pandas para eliminar duplicados e exporte-os em qualquer formato que necessite. O URL da página de detalhes é a chave mais estável por anúncio.

import pandas as pd

df = pd.DataFrame(scrape_search(SEARCH_URL))
df = df.drop_duplicates(subset="url").reset_index(drop=True)

df.to_json("realtor_listings.json", orient="records", indent=2)
df.to_csv("realtor_listings.csv", index=False)

O CSV é o caminho mais simples para o Excel e ferramentas de BI. O JSON funciona melhor se o código a jusante esperar objetos aninhados, especialmente depois de adicionarmos campos da página de detalhes. Seja como for, elimine duplicados antes de exportar, uma vez que o Realtor.com por vezes apresenta o mesmo anúncio em páginas de pesquisa adjacentes.

Extraia páginas de detalhes de propriedades individuais

As páginas de detalhes contêm o conjunto de dados mais rico: ano de construção, comodidades, contacto do agente, latitude/longitude, fotos. O Realtor.com incorpora duas cargas estruturadas:

  1. Um <script type="application/ld+json"> bloco que segue o vocabulário RealEstateListing do schema.org.
  2. Uma <script id="__NEXT_DATA__"> payload (o blob de hidratação do Next.js) com o registo completo do imóvel.

Ambos são JSON:

import json
from bs4 import BeautifulSoup

def parse_detail(html: str) -> dict:
    soup = BeautifulSoup(html, "lxml")
    raw  = soup.find("script", id="__NEXT_DATA__").string
    prop = json.loads(raw)["props"]["pageProps"]["initialReduxState"]["propertyDetails"]
    coord = (prop.get("location", {}).get("address", {}).get("coordinate") or {})
    adv   = (prop.get("advertisers") or [{}])[0]
    return {
        "year_built": prop.get("description", {}).get("year_built"),
        "lat": coord.get("lat"), "lon": coord.get("lon"),
        "amenities": prop.get("description", {}).get("features", []),
        "agent_name":  adv.get("name"),
        "agent_phone": (adv.get("phones") or [{}])[0].get("number"),
        "brokered_by": adv.get("office", {}).get("name"),
        "photos": [p["href"] for p in (prop.get("photos") or [])],
    }

Esse caminho da chave varia; registe a carga útil bruta durante o desenvolvimento e volte a fixá-la quando vir um KeyError. O JSON-LD é mais estável, mas expõe menos campos.

Transforme anúncios imobiliários em dados prontos para LLM

Assim que tiver um JSON de anúncios limpo, um LLM é a forma mais rápida de o enriquecer. Ignore o padrão «resumir esta página»; divida por anúncio e utilize prompts estruturados.

Dois fluxos de trabalho que valem a pena:

  • Análise comparativa. Introduza cinco a dez anúncios do mesmo código postal num único prompt com um esquema JSON a solicitar o preço ajustado por m², correspondências de tipo de habitação e indicadores de valores atípicos. Obterá um relatório comparativo numa única iteração.
  • Enriquecimento de leads. Passe o nome do agente, a corretora e o URL do anúncio para um modelo que devolve um cartão de contacto normalizado com uma pontuação de confiança.

Recolher páginas como Markdown em vez de HTML através da sua API de scraping reduz o custo dos tokens para cerca de metade.

Evite bloqueios: proxies, cabeçalhos e limitação de tráfego

Faça o scraping do Realtor.com a partir de um IP de datacenter com cabeçalhos padrão e será bloqueado. Para além do que uma API de scraping trata por si, as medidas de mitigação que fazem a diferença são:

  • Proxies residenciais. Os IPs de centros de dados são sinalizados em massa; a rotação residencial faz com que o tráfego pareça proveniente de visitantes reais.
  • Rotação de cabeçalhos. Aleatorize User-Agent, Accept-Languagee Sec-Ch-Ua por pedido, e mantê-los consistentes (um UA de iPhone com um cabeçalho de plataforma Windows é uma indicação imediata).
  • Limitação de tráfego. Cerca de três a seis segundos de variação entre pedidos mantêm-no abaixo da maioria dos padrões de comportamento.
  • Retrocesso exponencial. Em 403 ou 429, espera 2 ** attempt + random.random() e alterne a sessão; nunca tente novamente na mesma ligação.

Construir tudo isso por conta própria é um projeto; a maioria das equipas delega essa tarefa.

Considerações legais e éticas

As páginas de listagem do Realtor.com são públicas, pelo que a recolha de campos relativos a preço, morada e estrutura para investigação interna é geralmente justificável, mas não é um passe livre. Leia os Termos de Utilização do Realtor.com e o ficheiro robots.txt antes de criar um pipeline recorrente. Trate os nomes dos agentes, números de telefone e e-mails como dados pessoais ao abrigo da CCPA da Califórnia e de regimes análogos; a sua recolha para revenda ou contacto não solicitado leva-o a entrar em território regulamentado.

Resolver erros comuns de scrapers do Realtor

Cinco tipos de falhas são responsáveis pela maioria dos erros de scrapers do Realtor:

  • Lista de anúncios vazia. Está a ver uma página CAPTCHA que devolveu 200; verifique o título da página e, em seguida, ative a renderização JS na API.
  • Desvio de classe com hash. Substitua qualquer BasePropertyCard_propertyCardWrap__* seletor por um data-testid ou data-label lookup.
  • Picos de 403 / 429. Aumente o intervalo de espera, alterne a sessão e só aumente a simultaneidade quando a sua taxa de erro se estabilizar.
  • Campos de detalhes em falta. O __NEXT_DATA__ caminho da chave mudou; registe a carga útil bruta e reatribua as chaves.
  • Linhas duplicadas. Faça sempre a deduplicação na URL da lista antes da exportação.

Pontos-chave

  • Seletores primeiro, pedidos depois. Baseie-se em data-testid e data-label , nunca em nomes de classes com hash como BasePropertyCard_propertyCardWrap__*, que são regenerados em cada compilação do front-end.
  • Roteie através de uma API de scraping para produção. O requests acederá a páginas com CAPTCHA no Realtor.com com apenas algumas chamadas; uma camada de API lida com proxies, renderização JS e identificação TLS num único passo.
  • As páginas de detalhes multiplicam por 10 o seu conjunto de dados. Ano de construção, comodidades, contactos do agente e latitude/longitude residem no __NEXT_DATA__ blob e JSON-LD em cada página de propriedade, não no cartão de resultados de pesquisa.
  • Limite e recue, mesmo com uma boa API. Aproximadamente três a seis segundos de jitter, rotação residencial e recuo exponencial em 403/429 mantêm os pipelines de longa duração estáveis.
  • Respeite o enquadramento legal. Os dados dos anúncios são públicos; os contactos dos agentes são dados pessoais. Leia os termos antes de escalar e evite a revenda de campos regulamentados.

Perguntas frequentes

O Realtor.com oferece uma API oficial que eu possa usar em vez de fazer scraping?

Não existe nenhuma API pública de uso geral para navegar pelas listagens. A empresa-mãe da Realtor.com tem historicamente oferecido acesso às APIs Web RETS e RESO através de feeds de dados MLS, mas estes estão restritos a acordos com corretores ou parceiros, em vez de inscrições abertas para programadores. Para a maioria dos programadores e analistas independentes, o scraping estruturado de páginas de listagens públicas continua a ser a única via prática para obter dados em massa.

O Realtor.com bloqueará pedidos provenientes da AWS, GCP ou outros IPs de centros de dados?

Sim, quase imediatamente. A pilha anti-bot da Realtor.com mantém listas dos principais ASNs de nuvem e limita a taxa de pedidos ou desafia-os agressivamente. Um scraper a funcionar numa instância EC2 ou Cloud Run padrão irá deparar-se com páginas CAPTCHA após algumas chamadas. É necessário utilizar proxies residenciais ou móveis, ou uma API de scraping que lide com a rotação de IP de forma transparente.

Em que medida o scraping do Realtor.com difere do scraping do Zillow ou do Redfin?

Todos os três são renderizados em React, paginados e protegidos por pilhas anti-bot comportamentais, mas os detalhes de implementação diferem. O Zillow baseia-se fortemente na sua __NEXT_DATA__ carga útil e é agressivo nas verificações de impressão digital móvel. O Redfin expõe uma API JSON interna mais rica, utilizada pelo seu frontend. O Realtor.com situa-se entre os dois: data-testid ganchos em cartões mais um __NEXT_DATA__ blob nas páginas de detalhes.

Como faço para manter o scraper a funcionar quando o Realtor.com altera os nomes das suas classes com hash?

Não dependa de classes com hash, para começar. Ancore cada seletor em data-testid e data-label , que fazem parte do próprio contrato de teste do front-end e raramente mudam. Adicione um teste de fumaça que busque um anúncio conhecido todas as manhãs e verifique se o preço não está vazio; em seguida, alerte quando falhar para que possa fixar novamente os seletores antes que o pipeline esvazie silenciosamente.

Qual é uma taxa de pedidos segura para um scraper do Realtor.com de longa duração?

Uma faixa inicial útil é de aproximadamente três a seis segundos de atraso variável entre pedidos por sessão, com uma a três sessões simultâneas, cada uma num IP residencial diferente. Fique atento à sua taxa de 403/429; se subir acima de um ou dois por cento numa hora, abrande ainda mais ou alterne proxies de forma mais agressiva. O tráfego em rajadas é sinalizado mais rapidamente do que o volume constante.

Conclusão

Saber como fazer scraping do Realtor.com de ponta a ponta tem principalmente a ver com organizar as peças certas na ordem certa: fixar seletores estáveis, encaminhar pedidos através de algo que lide com a pilha anti-bot por si, seguir URLs de listagens para páginas de detalhes para o resto do conjunto de dados e deduplicar antes de exportar. Acertar nisso e terá um pipeline que sobrevive à próxima refatoração do front-end em vez de falhar com ela.

As partes difíceis — rotação residencial, renderização de JS, tratamento de CAPTCHA — são exatamente o que atrasa as equipas durante semanas se forem desenvolvidas internamente. São também as partes que mais beneficiam de serem delegadas a uma camada de pedidos gerida, para que os seus engenheiros possam manter-se focados na análise, modelação e análise a jusante.

Se preferir não gerir uma frota de proxies, um gerador de cabeçalhos e um solucionador de CAPTCHA, a nossa API Scraper na WebScrapingAPI foi concebida exatamente para este tipo de tarefa: devolve HTML renderizado para qualquer URL que lhe indicar, lida com tentativas de repetição em 403/429 e alterna IPs residenciais em 195 países, para que o seu scraper pareça 200 pessoas diferentes a navegar nos anúncios de Cincinnati. Integre-a na construção acima e o único código que terá de manter é a camada de análise.

Sobre o autor
Raluca Penciuc, Desenvolvedor Full-Stack @ WebScrapingAPI
Raluca PenciucDesenvolvedor Full-Stack

Raluca Penciuc é programadora Full Stack na WebScrapingAPI, onde desenvolve scrapers, aperfeiçoa estratégias de evasão e procura formas fiáveis de reduzir a deteção nos sites-alvo.

Comece a construir

Pronto para expandir a sua recolha de dados?

Junte-se a mais de 2.000 empresas que utilizam a WebScrapingAPI para extrair dados da Web à escala empresarial, sem quaisquer custos de infraestrutura.