Web Scraping para o sector imobiliário: Como extrair dados do Realtor.com como um profissional
Raluca Penciuc em Abr 07 2023

A recolha de dados precisos e actualizados é crucial para empresas e indivíduos em muitos sectores, e o sector imobiliário não é exceção. O Realtor.com é um site popular para encontrar apartamentos e casas para venda ou aluguer, pois contém uma grande quantidade de informações que podem ser valiosas para profissionais do sector imobiliário, investidores e compradores de casas.
Neste tutorial, mostrarei como raspar o site realtor.com para que você tenha disponíveis os dados necessários para iniciar seu projeto. Vou percorrer o processo de configuração de um projeto, navegar para realtor.com e extrair os dados desejados.
Discutirei também formas de melhorar a fiabilidade e a eficiência do raspador e por que razão a utilização de um serviço de raspagem profissional pode ser uma melhor opção para alguns casos de utilização.
No final deste tutorial, deve ter uma boa compreensão de como fazer scrape do realtor.com, independentemente da sua profissão: um profissional do sector imobiliário à procura de uma vantagem competitiva, um investidor à procura de novas oportunidades ou um comprador de casa à procura da propriedade perfeita.
Configuração do ambiente
Antes de começar a fazer scraping, é necessário instalar o Node.js no seu computador. Pode descarregar a versão mais recente a partir do sítio Web oficial e seguir as instruções de acordo com o seu sistema operativo.
Em seguida, crie um novo diretório para o seu projeto e navegue até ele no terminal ou no prompt de comando. Execute o seguinte comando para inicializar um novo projeto Node.js:
npm init -y
Isto criará um ficheiro package.json no seu diretório de projeto, que armazenará informações sobre o seu projeto e as suas dependências.
Para instalar o TypeScript, execute o seguinte comando:
npm install typescript -save-dev
O TypeScript é um superconjunto do JavaScript que adiciona tipagem estática opcional e outros recursos. É útil para projetos maiores e pode facilitar a deteção de erros logo no início. O TypeScript usa um arquivo de configuração chamado tsconfig.json para armazenar opções do compilador e outras configurações. Para criar esse arquivo no seu projeto, execute o seguinte comando:
npx tsc -init
Certifique-se de que o valor de "outDir" esteja definido como "dist". Dessa forma, separaremos os arquivos TypeScript dos arquivos compilados.
Agora, crie um diretório "src" no seu projeto e um novo ficheiro "index.ts". É aqui que vamos manter o código de raspagem. Para executar o código TypeScript, é necessário compilá-lo primeiro, portanto, para garantir que não nos esqueçamos dessa etapa extra, podemos usar um comando definido de forma personalizada.
Vá ao ficheiro "package. json" e edite a secção "scripts" desta forma:
"scripts": {
"test": "npx tsc && node dist/index.js"
}
Desta forma, quando for executar o script, basta digitar "npm run test" no seu terminal.
E por último, mas não menos importante, execute o seguinte comando para adicionar o Puppeteer às dependências do seu projeto:
npm install puppeteer
O Puppeteer é uma biblioteca Node.js que fornece uma API de alto nível para controlar um navegador Chrome sem cabeça, que pode ser utilizado para tarefas de raspagem e automação da Web. É altamente recomendada quando se pretende garantir a integridade dos dados, uma vez que muitos sítios Web actuais contêm conteúdos gerados de forma dinâmica.
Seleção de dados
Agora que o ambiente está configurado, podemos começar a analisar a extração dos dados. Para este artigo, optei por extrair a lista de apartamentos estúdio disponíveis para aluguer em Plano, TX: https://www.realtor.com/apartments/Plano_TX/beds-studio.
Vamos extrair os seguintes dados de cada anúncio na página:
- o URL;
- os preços;
- o número de banhos;
- as superfícies (medidas em pés quadrados);
- os endereços físicos
Pode ver todas estas informações destacadas na imagem de ecrã abaixo:

Extração de dados
Para extrair todos estes dados, temos de os localizar primeiro. Clique com o botão direito do rato nas secções destacadas e, em seguida, escolha "Inspecionar" para abrir as Ferramentas de Desenvolvimento e ver o documento HTML. Movendo o cursor do rato sobre ele, pode ver facilmente que parte corresponde a cada secção:

Para este tutorial, vou utilizar selectores CSS, uma vez que são a opção mais simples. Se é novo neste método, não hesite em consultar primeiro este guia auto-explicativo.
Para começar a escrever o nosso script, vamos verificar se a instalação do Puppeteer correu bem:
import puppeteer from 'puppeteer';
async function scrapeRealtorData(realtor_url: string): Promise<void> {
// Launch Puppeteer
const browser = await puppeteer.launch({
headless: false,
args: ['--start-maximized'],
defaultViewport: null
})
const page = await browser.newPage()
// Navigate to the channel URL
await page.goto(realtor_url)
// Close the browser
await browser.close()
}
scrapeRealtorData("https://www.realtor.com/apartments/Plano_TX/beds-studio")
Aqui, abrimos uma janela do navegador, criamos uma nova página, navegamos até o URL de destino e fechamos o navegador. Por uma questão de simplicidade e depuração visual, abro o navegador maximizado no modo sem cabeça.
Como cada listagem tem a mesma estrutura e os mesmos dados, no nosso algoritmo vamos extrair todas as informações de toda a lista de propriedades. No final do script, vamos iterar todos os resultados e centralizá-los numa única lista.
Deve ter reparado que o URL do anúncio não era visível na primeira imagem de ecrã, mas foi mencionado e destacado na segunda. Isso deve-se ao facto de ser redireccionado para o URL do imóvel quando clica nele.
// Extract listings location
const listings_location = await page.evaluate(() => {
const locations = document.querySelectorAll('a[data-testid="card-link"]')
const locations_array = Array.from(locations)
return locations ? locations_array.map(a => a.getAttribute('href')) : []
})
console.log(localização_das_listas)
Localizamos o URL escolhendo os elementos âncora que têm o atributo "data-testid" com o valor "card-link". Em seguida, convertemos o resultado em uma matriz JavaScript e mapeamos cada elemento para o valor do atributo "href".
No entanto, a lista resultante conterá cada URL duas vezes. Isto acontece porque cada anúncio tem o mesmo elemento âncora para duas secções: as imagens da propriedade e os detalhes do aluguer. Podemos resolver isto facilmente utilizando a estrutura de dados Set:
const unique_listings_location = [...new Set(listings_location)]
console.log(unique_listings_location)
Para o preço do imóvel, extrairemos os elementos "div" que têm o atributo "data-testid" com o valor "card-price". Também precisa de ser convertido numa matriz e depois mapeado para o seu conteúdo de texto.
// Extract listings price
const listings_price = await page.evaluate(() => {
const prices = document.querySelectorAll('div[data-testid="card-price"]')
const prices_array = Array.from(prices)
return prices ? prices_array.map(p => p.textContent) : []
})
console.log(listings_price)
Para obter o número de banhos e a superfície da propriedade, utilizaremos o operador para elementos filhos diretos. Isto significa que o elemento pai é identificado de forma única, enquanto o elemento filho tem um id ou nome de classe mais genérico. Para além disso, a lógica é a mesma que a anterior:
// Extract listings baths
const listings_baths = await page.evaluate(() => {
const baths = document.querySelectorAll('li[data-testid="property-meta-baths"] > span[data-testid="meta-value"]')
const baths_array = Array.from(baths)
return baths ? baths_array.map(b => b.textContent) : []
})
console.log(listings_baths)
// Extract listings sqft
const listings_sqft = await page.evaluate(() => {
const sqfts = document.querySelectorAll('li[data-testid="property-meta-sqft"] > span[data-testid="screen-reader-value"]')
const sqfts_array = Array.from(sqfts)
return sqfts ? sqfts_array.map(s => s.textContent) : []
})
console.log(listings_sqft)
Por fim, para os endereços das listagens, seleccionamos os elementos "div" que têm o atributo "data-testid" definido para o valor "card-address".
// Extract listings address
const listings_address = await page.evaluate(() => {
const addresses = document.querySelectorAll('div[data-testid="card-address"]')
const addresses_array = Array.from(addresses)
return addresses ? addresses_array.map(a => a.textContent) : []
})
console.log(listings_address)
Agora você deve ter 5 listas, uma para cada dado que extraímos. Como mencionei anteriormente, devemos centralizá-las numa única. Desta forma, a informação que recolhemos será muito mais fácil de processar.
// Group the lists
const listings = []
for (let i = 0; i < unique_listings_location.length; i++) {
listings.push({
url: unique_listings_location[i],
price: listings_price[i],
baths: listings_baths[i],
sqft: listings_sqft[i],
address: listings_address[i]
})
}
console.log(listings)
O resultado final deve ser mais ou menos assim:
[
{
url: '/realestateandhomes-detail/1009-14th-St-Apt-410_Plano_TX_75074_M92713-98757',
price: '$1,349',
baths: '1',
sqft: '602 square feet',
address: '1009 14th St Apt 410Plano, TX 75074'
},
{
url: '/realestateandhomes-detail/1009-14th-St-Apt-1_Plano_TX_75074_M95483-11211',
price: '$1,616',
baths: '1',
sqft: '604 square feet',
address: '1009 14th St Apt 1Plano, TX 75074'
},
{
url: '/realestateandhomes-detail/1009-14th-St_Plano_TX_75074_M87662-45547',
price: '$1,605 - $2,565',
baths: '1 - 2',
sqft: '602 - 1,297 square feet',
address: '1009 14th StPlano, TX 75074'
},
{
url: '/realestateandhomes-detail/5765-Bozeman-Dr_Plano_TX_75024_M70427-45476',
price: '$1,262 - $2,345',
baths: '1 - 2',
sqft: '352 - 1,588 square feet',
address: '5765 Bozeman DrPlano, TX 75024'
},
{
url: '/realestateandhomes-detail/1410-K-Ave-Ste-1105A_Plano_TX_75074_M97140-46163',
price: '$1,250 - $1,995',
baths: '1 - 2',
sqft: '497 - 1,324 square feet',
address: '1410 K Ave Ste 1105APlano, TX 75074'
}
]
Evitar a deteção de bots
Embora o scraping do Realtor possa parecer fácil no início, o processo pode tornar-se mais complexo e desafiante à medida que aumenta a escala do seu projeto. O sítio Web do sector imobiliário implementa várias técnicas para detetar e impedir o tráfego automatizado, pelo que o seu scraper em grande escala começa a ser bloqueado.
O Realtor utiliza o modelo "Press & Hold" de CAPTCHA, oferecido pela PerimeterX, que é conhecido por ser quase impossível de resolver a partir do seu código. Além disso, o sítio Web também recolhe vários dados do navegador para gerar e associá-lo a uma impressão digital única.
Entre os dados do navegador recolhidos, encontramos:
- propriedades do objeto Navigator (deviceMemory, hardwareConcurrency, idiomas, plataforma, userAgent, webdriver, etc.)
- controlos de prazos e de desempenho
- WebGL
- Deteção de IP WebRTC
- e muitos mais
Uma maneira de superar esses desafios e continuar a raspagem em grande escala é usar uma API de raspagem. Esses tipos de serviços fornecem uma maneira simples e confiável de acessar dados de sites como o Realtor.com, sem a necessidade de criar e manter seu próprio raspador.
O WebScrapingAPI é um exemplo de um produto deste género. O seu mecanismo de rotação de proxy evita completamente os CAPTCHAs, e a sua base de conhecimentos alargada permite aleatorizar os dados do browser para que se pareça com um utilizador real.
A configuração é rápida e fácil. Basta registar uma conta para receber a sua chave de API. Esta pode ser acedida a partir do seu painel de controlo e é utilizada para autenticar os pedidos que envia.

Como já configurou o seu ambiente Node.js, podemos utilizar o SDK correspondente. Execute o seguinte comando para o adicionar às dependências do seu projeto:
npm install webscrapingapi
Agora só falta ajustar os selectores CSS anteriores à API. A poderosa caraterística das regras de extração torna possível analisar dados sem modificações significativas.
import webScrapingApiClient from 'webscrapingapi';
const client = new webScrapingApiClient("YOUR_API_KEY");
async function exampleUsage() {
const api_params = {
'render_js': 1,
'proxy_type': 'datacenter',
'timeout': 60000,
'extract_rules': JSON.stringify({
locations: {
selector: 'a[data-testid="card-link"]',
output: '@href',
all: '1'
},
prices: {
selector: 'div[data-testid="card-price"]',
output: 'text',
all: '1'
},
baths: {
selector: 'li[data-testid="property-meta-baths"] > span[data-testid="meta-value"]',
output: 'text',
all: '1'
},
sqfts: {
selector: 'li[data-testid="property-meta-sqft"] > span[data-testid="screen-reader-value"]',
output: 'text',
all: '1'
},
addresses: {
selector: 'div[data-testid="card-address"]',
output: 'text',
all: '1'
}
})
}
const URL = "https://www.realtor.com/apartments/Plano_TX/beds-studio"
const response = await client.get(URL, api_params)
if (response.success) {
const unique_listings_location = [...new Set(response.response.data.locations)]
// Group the lists
const listings = []
for (let i = 0; i < unique_listings_location.length; i++) {
listings.push({
url: unique_listings_location[i],
price: response.response.data.prices[i],
baths: response.response.data.baths[i],
sqft: response.response.data.sqfts[i],
address: response.response.data.addresses[i]
})
}
console.log(listings)
} else {
console.log(response.error.response.data)
}
}
exampleUsage();
Conclusão
Neste tutorial, fornecemos um guia passo a passo sobre como raspar o realtor.com usando o Node.js e o Puppeteer. Também discutimos maneiras de melhorar a confiabilidade e a eficiência do scraper e por que usar um serviço de scraper profissional pode ser uma opção melhor para alguns casos de uso.
O Realtor.com é uma fonte popular e valiosa de dados imobiliários e, com as competências e os conhecimentos que adquiriu neste tutorial, deve agora ser capaz de utilizar a raspagem da Web para extrair estes dados e utilizá-los nos seus próprios projectos.
Quer seja um profissional do sector imobiliário à procura de uma vantagem competitiva, um investidor à procura de novas oportunidades ou um comprador de casa à procura da propriedade perfeita, o web scraping pode fornecer-lhe informações e dados valiosos do realtor.com. Esperamos que este tutorial tenha sido útil e que esteja agora pronto para elevar o seu jogo imobiliário com a ajuda do web scraping do realtor.com.
Notícias e actualizações
Mantenha-se atualizado com os mais recentes guias e notícias sobre raspagem da Web, subscrevendo a nossa newsletter.
We care about the protection of your data. Read our <l>Privacy Policy</l>.Privacy Policy.

Artigos relacionados

Explore as complexidades da extração de dados de produtos da Amazon com nosso guia detalhado. De práticas recomendadas e ferramentas como a API Amazon Scraper a considerações legais, saiba como enfrentar desafios, contornar CAPTCHAs e extrair insights valiosos com eficiência.


Explore uma comparação pormenorizada entre o Scrapy e o Beautiful Soup, duas ferramentas líderes de raspagem da Web. Compreenda as suas caraterísticas, prós e contras, e descubra como podem ser utilizadas em conjunto para satisfazer as várias necessidades do projeto.


Descubra como extrair e organizar eficientemente dados para raspagem da Web e análise de dados através de análise de dados, bibliotecas de análise de HTML e metadados schema.org.
