Web Scraping pour l'immobilier : Comment extraire les données de Realtor.com comme un pro
Raluca Penciuc le 07 avril 2023

La collecte de données précises et actualisées est essentielle pour les entreprises et les particuliers dans de nombreux secteurs, et l'immobilier ne fait pas exception à la règle. Realtor.com est un site web populaire pour trouver des appartements et des maisons à vendre ou à louer, car il contient une mine d'informations qui peuvent être précieuses pour les professionnels de l'immobilier, les investisseurs et les acheteurs.
Dans ce tutoriel, je vais vous montrer comment scraper realtor.com afin que vous ayez à votre disposition les données dont vous avez besoin pour démarrer votre projet. Je vous expliquerai comment configurer un projet, naviguer sur realtor.com et extraire les données souhaitées.
J'aborderai également les moyens d'améliorer la fiabilité et l'efficacité du scraper, et j'expliquerai pourquoi le recours à un service de scraper professionnel peut s'avérer une meilleure option dans certains cas d'utilisation.
À la fin de ce tutoriel, vous devriez avoir une bonne compréhension de la manière de scraper realtor.com, quelle que soit votre profession : un professionnel de l'immobilier à la recherche d'un avantage concurrentiel, un investisseur à la recherche de nouvelles opportunités, ou un acheteur à la recherche de la propriété idéale.
Configuration de l'environnement
Avant de commencer le scraping, vous devez installer Node.js sur votre ordinateur. Vous pouvez télécharger la dernière version sur le site officiel et suivre les instructions en fonction de votre système d'exploitation.
Ensuite, créez un nouveau répertoire pour votre projet et accédez-y dans votre terminal ou votre invite de commande. Exécutez la commande suivante pour initialiser un nouveau projet Node.js :
npm init -y
Cela créera un fichier package.json dans le répertoire de votre projet, qui contiendra des informations sur votre projet et ses dépendances.
Pour installer TypeScript, exécutez la commande suivante :
npm install typescript -save-dev
TypeScript est un surensemble de JavaScript qui ajoute un typage statique optionnel et d'autres fonctionnalités. Il est utile pour les projets de plus grande envergure et permet de détecter plus facilement les erreurs dès le début. TypeScript utilise un fichier de configuration appelé tsconfig.json pour stocker les options du compilateur et d'autres paramètres. Pour créer ce fichier dans votre projet, exécutez la commande suivante :
npx tsc -init
Assurez-vous que la valeur de "outDir" est fixée à "dist". De cette manière, nous séparerons les fichiers TypeScript des fichiers compilés.
Maintenant, créez un répertoire "src" dans votre projet, et un nouveau fichier "index.ts". C'est ici que nous conserverons le code de scraping. Pour exécuter du code TypeScript, il faut d'abord le compiler, donc pour être sûr de ne pas oublier cette étape supplémentaire, nous pouvons utiliser une commande personnalisée.
Allez dans le fichier "package.json", et éditez la section "scripts" comme ceci :
"scripts": {
"test": "npx tsc && node dist/index.js"
}
Ainsi, lorsque vous exécuterez le script, il vous suffira de taper "npm run test" dans votre terminal.
Enfin, lancez la commande suivante pour ajouter Puppeteer aux dépendances de votre projet :
npm install puppeteer
Puppeteer est une bibliothèque Node.js qui fournit une API de haut niveau pour contrôler un navigateur Chrome sans tête, qui peut être utilisé pour des tâches de web scraping et d'automatisation. Elle est fortement recommandée lorsque vous souhaitez vous assurer de l'exhaustivité de vos données, car de nombreux sites web contiennent aujourd'hui du contenu généré de manière dynamique.
Sélection des données
Maintenant que votre environnement est configuré, nous pouvons commencer à extraire les données. Pour cet article, j'ai choisi de récupérer la liste des studios à louer à Plano, TX : https://www.realtor.com/apartments/Plano_TX/beds-studio.
Nous allons extraire les données suivantes de chaque liste de la page :
- l'URL ;
- les prix ;
- le nombre de bains ;
- les surfaces (mesurées en pieds carrés) ;
- les adresses physiques
Toutes ces informations sont mises en évidence dans la capture d'écran ci-dessous :

Extraction des données
Pour extraire toutes ces données, nous devons d'abord les localiser. Cliquez avec le bouton droit de la souris sur les sections en surbrillance, puis choisissez "Inspecter" pour ouvrir les outils de développement et voir le document HTML. En déplaçant le curseur de la souris, vous pouvez facilement voir quelle partie correspond à chaque section :

Pour ce tutoriel, j'utiliserai des sélecteurs CSS, car c'est l'option la plus simple. Si vous ne connaissez pas encore cette méthode, n'hésitez pas à consulter d'abord ce guide explicite.
Pour commencer à écrire notre script, vérifions que l'installation de Puppeteer s'est bien déroulée :
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")
Ici, nous ouvrons une fenêtre de navigateur, créons une nouvelle page, naviguons jusqu'à notre URL cible, puis fermons le navigateur. Pour des raisons de simplicité et de débogage visuel, j'ouvre le navigateur en mode maximisé et non sans tête.
Étant donné que chaque liste possède la même structure et les mêmes données, notre algorithme extraira toutes les informations de la liste complète des propriétés. À la fin du script, nous itérerons tous les résultats et les centraliserons dans une seule liste.
Vous avez peut-être remarqué que l'URL de l'annonce n'était pas visible dans la première capture d'écran, mais qu'elle était mentionnée et mise en évidence dans la seconde. C'est parce que vous êtes redirigé vers l'URL du bien lorsque vous cliquez dessus.
// 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(listings_location)
Nous localisons l'URL en choisissant les éléments d'ancrage qui ont l'attribut "data-testid" avec la valeur "card-link". Nous convertissons ensuite le résultat en un tableau JavaScript et faisons correspondre chaque élément à la valeur de l'attribut "href".
Cependant, la liste résultante contiendra chaque URL deux fois. C'est parce que chaque annonce a le même élément d'ancrage pour 2 sections : les photos de la propriété et les détails de la location. Nous pouvons facilement résoudre ce problème en utilisant la structure de données Set :
const unique_listings_location = [...new Set(listings_location)]
console.log(unique_listings_location)
Pour le prix de la propriété, nous extrairons les éléments "div" qui ont l'attribut "data-testid" avec la valeur "card-price". Cet élément doit être converti en tableau, puis mis en correspondance avec son contenu textuel.
// 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)
Pour obtenir le nombre de bains et la surface de la propriété, nous utiliserons l'opérateur pour les éléments enfants directs. Cela signifie que l'élément parent est identifié de manière unique, tandis que l'élément enfant a un identifiant ou un nom de classe plus générique. À part cela, la logique est la même que précédemment :
// 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)
Enfin, pour les adresses des inscriptions, nous sélectionnons les éléments "div" dont l'attribut "data-testid" est défini sur la valeur "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)
Vous devriez maintenant avoir 5 listes, une pour chaque donnée que nous avons récupérée. Comme je l'ai mentionné précédemment, nous devrions les centraliser en une seule. De cette façon, les informations que nous avons recueillies seront beaucoup plus faciles à traiter.
// 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)
Le résultat final devrait ressembler à ceci :
[
{
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'
}
]
Éviter la détection des robots
Si le scraping de Realtor peut sembler facile au début, le processus peut devenir plus complexe et difficile au fur et à mesure que vous développez votre projet. Le site immobilier met en œuvre diverses techniques pour détecter et empêcher le trafic automatisé, de sorte que votre scraper à grande échelle commence à être bloqué.
Realtor utilise le modèle "Press & Hold" de CAPTCHA, proposé par PerimeterX, qui est connu pour être presque impossible à résoudre à partir de votre code. En outre, le site web recueille également les données de plusieurs navigateurs afin de générer et d'associer une empreinte digitale unique à votre nom.
Parmi les données collectées sur les navigateurs, nous trouvons
- propriétés de l'objet Navigator (deviceMemory, hardwareConcurrency, languages, platform, userAgent, webdriver, etc.)
- le calendrier et les contrôles de performance
- WebGL
- WebRTC IP sniffing
- et bien d'autres encore
L'une des façons de surmonter ces difficultés et de poursuivre le scraping à grande échelle consiste à utiliser une API de scraping. Ce type de service offre un moyen simple et fiable d'accéder aux données de sites web tels que Realtor.com, sans avoir besoin de construire et d'entretenir son propre scraper.
WebScrapingAPI est un exemple de ce type de produit. Son mécanisme de rotation de proxy évite complètement les CAPTCHA, et sa base de connaissances étendue permet de randomiser les données du navigateur afin qu'il ressemble à un utilisateur réel.
L'installation est simple et rapide. Il vous suffit d'ouvrir un compte pour recevoir votre clé API. Elle est accessible depuis votre tableau de bord et sert à authentifier les demandes que vous envoyez.

Comme vous avez déjà configuré votre environnement Node.js, nous pouvons utiliser le SDK correspondant. Exécutez la commande suivante pour l'ajouter aux dépendances de votre projet :
npm install webscrapingapi
Il ne reste plus qu'à adapter les sélecteurs CSS précédents à l'API. La puissante fonctionnalité des règles d'extraction permet d'analyser les données sans modifications significatives.
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();
Conclusion
Dans ce tutoriel, nous avons fourni un guide étape par étape sur la façon de scraper realtor.com en utilisant Node.js et Puppeteer. Nous avons également discuté des moyens d'améliorer la fiabilité et l'efficacité du scraper, et des raisons pour lesquelles l'utilisation d'un service de scraper professionnel peut être une meilleure option pour certains cas d'utilisation.
Realtor.com est une source populaire et précieuse de données immobilières, et avec les compétences et les connaissances que vous avez acquises dans ce tutoriel, vous devriez maintenant être en mesure d'utiliser le web scraping pour extraire ces données et les utiliser dans vos propres projets.
Que vous soyez un professionnel de l'immobilier à la recherche d'un avantage concurrentiel, un investisseur à la recherche de nouvelles opportunités ou un acheteur à la recherche de la propriété idéale, le web scraping peut vous fournir des informations et des données précieuses provenant de realtor.com. Nous espérons que ce tutoriel vous a été utile et que vous êtes maintenant prêt à élever votre jeu immobilier avec l'aide du web scraping de realtor.com.
Nouvelles et mises à jour
Restez au courant des derniers guides et nouvelles sur le web scraping en vous inscrivant à notre lettre d'information.
We care about the protection of your data. Read our <l>Privacy Policy</l>.Privacy Policy.

Articles connexes

Explorez les complexités du scraping des données de produits Amazon avec notre guide approfondi. Des meilleures pratiques aux outils tels que l'API Amazon Scraper, en passant par les considérations juridiques, apprenez à relever les défis, à contourner les CAPTCHA et à extraire efficacement des informations précieuses.


Découvrez une comparaison détaillée entre Scrapy et Beautiful Soup, deux outils de scraping web de premier plan. Comprenez leurs caractéristiques, leurs avantages et leurs inconvénients, et découvrez comment ils peuvent être utilisés ensemble pour répondre aux besoins de différents projets.


Découvrez comment extraire et organiser efficacement des données pour le web scraping et l'analyse de données grâce à l'analyse de données, aux bibliothèques d'analyse HTML et aux métadonnées schema.org.
