{"id":44369,"date":"2026-05-13T21:04:47","date_gmt":"2026-05-13T21:04:47","guid":{"rendered":"https:\/\/floppydata.com\/non-categorise\/comment-extraire-des-donnees-de-zillow-un-guide-qui-fonctionne\/"},"modified":"2026-05-13T21:04:47","modified_gmt":"2026-05-13T21:04:47","slug":"how-to-scrape-zillow-a-guide-that-works","status":"publish","type":"post","link":"https:\/\/floppydata.com\/fr\/blog\/how-to-scrape-zillow-a-guide-that-works\/","title":{"rendered":"Comment extraire des donn\u00e9es de Zillow : Un guide qui fonctionne"},"content":{"rendered":"<h2><strong>Introduction<\/strong><\/h2>\n<p>Zillow \u00e9tant l&rsquo;une des principales plateformes immobili\u00e8res aux \u00c9tats-Unis, de nombreuses entreprises souhaitent y puiser des donn\u00e9es sur les biens immobiliers. La plateforme re\u00e7oit actuellement environ <a href=\"https:\/\/www.businessofapps.com\/data\/zillow-statistics\/\" target=\"_blank\" rel=\"noopener\">243 millions de visites par mois<\/a>, et contient donc naturellement une grande quantit\u00e9 de donn\u00e9es immobili\u00e8res utiles. <\/p>\n<p>Cependant, les d\u00e9veloppeurs partagent souvent sur Reddit leurs difficult\u00e9s \u00e0 contourner le pare-feu de Zillow ou \u00e0 \u00eatre bloqu\u00e9s de fa\u00e7on permanente lorsqu&rsquo;ils essaient de faire du scrape. Si vous venez d&rsquo;en faire l&rsquo;exp\u00e9rience et que vous recherchez un guide stable et efficace, lisez la suite. <\/p>\n<p>Dans ce guide, je vous montrerai comment extraire des donn\u00e9es cl\u00e9s de Zillow \u00e0 l&rsquo;aide de Python et d&rsquo;une simple API Web.<\/p>\n<h2><strong>Qu&rsquo;est-ce que le \u00ab\u00a0Zillow Scraping\u00a0\u00bb ?<\/strong><\/h2>\n<p>Le scraping de Zillow est le processus qui consiste \u00e0 collecter des donn\u00e9es immobili\u00e8res accessibles au public \u00e0 partir des pages de Zillow et \u00e0 les transformer en un format structur\u00e9, tel que CSV ou JSON, que vous pouvez utiliser \u00e0 des fins professionnelles ou personnelles.<\/p>\n<p>Au lieu d&rsquo;ouvrir les annonces une par une, vous pouvez utiliser un scraper pour extraire les d\u00e9tails cl\u00e9s des pages de recherche et des pages d\u00e9taill\u00e9es des annonces immobili\u00e8res.<\/p>\n<p><img fetchpriority=\"high\" decoding=\"async\" class=\"alignnone size-full wp-image-44250\" src=\"https:\/\/floppydata.com\/wp-content\/uploads\/2026\/05\/image3-3.png\" alt=\"Zillow Scraping\" width=\"1999\" height=\"1385\" srcset=\"https:\/\/floppydata.com\/wp-content\/uploads\/2026\/05\/image3-3.png 1999w, https:\/\/floppydata.com\/wp-content\/uploads\/2026\/05\/image3-3-300x208.png 300w, https:\/\/floppydata.com\/wp-content\/uploads\/2026\/05\/image3-3-1024x709.png 1024w, https:\/\/floppydata.com\/wp-content\/uploads\/2026\/05\/image3-3-768x532.png 768w, https:\/\/floppydata.com\/wp-content\/uploads\/2026\/05\/image3-3-1536x1064.png 1536w\" sizes=\"(max-width: 1999px) 100vw, 1999px\" \/><\/p>\n<p>Entre les deux pages, vous pouvez tirer :<\/p>\n<ul>\n<li>Prix, adresse, nombre de lits et de salles de bain, superficie, statut et nombre de jours sur le march\u00e9<\/li>\n<li>Estimation et estimation des loyers<\/li>\n<li>Photos de l&rsquo;annonce et nom du courtier<\/li>\n<li>Historique des prix et des taxes<\/li>\n<\/ul>\n<h3><strong>Pourquoi r\u00e9cup\u00e9rer les donn\u00e9es de Zillow ?<\/strong><\/h3>\n<p>Imaginez que vous puissiez acc\u00e9der \u00e0 des listes de propri\u00e9t\u00e9s, \u00e0 des d\u00e9tails de prix et \u00e0 des analyses de march\u00e9 \u00e0 la minute pr\u00e8s sans avoir \u00e0 ouvrir manuellement des centaines de pages Zillow.<\/p>\n<p>C&rsquo;est la valeur r\u00e9elle de la recherche sur Zillow.<\/p>\n<p>Si vous travaillez dans l&rsquo;immobilier, l&rsquo;investissement immobilier, l&rsquo;\u00e9tude de march\u00e9, la g\u00e9n\u00e9ration de leads ou l&rsquo;analyse des prix, Zillow dispose de donn\u00e9es publiques utiles qui peuvent vous aider \u00e0 rep\u00e9rer les tendances plus rapidement.<\/p>\n<h2><strong>Pourquoi Zillow est-il si difficile \u00e0 gratter ?<\/strong><\/h2>\n<p>Zillow ne va pas aussi loin que certaines plateformes lorsqu&rsquo;il s&rsquo;agit de bloquer les robots, mais il est tout de m\u00eame con\u00e7u pour bloquer le trafic qui n&rsquo;a pas l&rsquo;air humain.<\/p>\n<p>La plupart des scrapers \u00e9chouent pour deux raisons. Examinons les deux : <\/p>\n<h3><strong>Protection PerimeterX<\/strong><\/h3>\n<p>Zillow utilise PerimeterX pour d\u00e9tecter et bloquer le trafic des robots en temps r\u00e9el. Si votre scraper a les mauvais en-t\u00eates, s&rsquo;il provient d&rsquo;une adresse IP peu fiable ou s&rsquo;il envoie trop de requ\u00eates trop rapidement, il peut \u00eatre signal\u00e9. <\/p>\n<p>La plupart du temps, ce drapeau m\u00e8ne \u00e0 une \u00e9nigme CAPTCHA, qui mettrait hors d&rsquo;\u00e9tat de nuire la plupart des scrapers. PerimeterX v\u00e9rifie \u00e9galement de nombreux signaux, notamment les en-t\u00eates, le comportement du navigateur, les empreintes TLS, la vitesse des requ\u00eates et la r\u00e9putation de l&rsquo;IP. <\/p>\n<p>Si le trafic semble automatis\u00e9, le scraper peut ne jamais atteindre les donn\u00e9es r\u00e9elles de l&rsquo;annonce.<\/p>\n<p>Ainsi, m\u00eame si vous rendez la page dans un navigateur sans t\u00eate, cela ne garantit pas le succ\u00e8s. Vous avez toujours besoin de proxys de haute qualit\u00e9, de sessions propres et d&rsquo;un comportement r\u00e9aliste des requ\u00eates. <\/p>\n<p>C&rsquo;est pourquoi je pr\u00e9f\u00e8re utiliser le Web Unlocker de Floppydata pour scraper Zillow.<\/p>\n<h3><strong>HTML non structur\u00e9 et absence de s\u00e9lecteurs stables<\/strong><\/h3>\n<p>L&rsquo;analyse de Zillow peut \u00eatre aussi frustrante que le franchissement de ses d\u00e9fenses. Il n&rsquo;y a pratiquement pas de noms de classe, d&rsquo;ID ou d&rsquo;attributs de donn\u00e9es coh\u00e9rents dans la source de la page. <\/p>\n<p>Les \u00e9l\u00e9ments qui semblent simples, comme le prix ou l&rsquo;adresse, sont envelopp\u00e9s dans des balises g\u00e9n\u00e9riques &lt;div&gt; ou n&rsquo;ont pas d&rsquo;identifiant du tout.<\/p>\n<p>Pire encore, les noms des classes changent souvent et ne suivent aucun mod\u00e8le. Vous devez donc utiliser une correspondance flexible (comme find() bas\u00e9 sur des mots-cl\u00e9s ou m\u00eame des expressions rationnelles) pour extraire des donn\u00e9es de n\u0153uds de texte bruts. <\/p>\n<p>Cela fait de Zillow l&rsquo;un des sites les plus instables \u00e0 gratter si vous vous appuyez sur des s\u00e9lecteurs statiques.<\/p>\n<h2><strong>Extraire des informations de Zillow avec Python<\/strong><\/h2>\n<p>Pour ce guide, je vais cibler la <a href=\"https:\/\/www.zillow.com\/boston-ma\/\" target=\"_blank\" rel=\"noopener\">page de r\u00e9sultats de recherche de Zillow \u00e0 Boston<\/a>, qui contient plusieurs annonces immobili\u00e8res. \u00c0 partir de l\u00e0, nous pouvons extraire des champs tels que le prix, l&rsquo;adresse, le nombre de lits et de salles de bain, la superficie, le statut et les liens de l&rsquo;annonce. <\/p>\n<p><strong><em>Note :<\/em><\/strong><em>  Les pages de Zillow changent souvent. Si la page de Boston est diff\u00e9rente au moment o\u00f9 vous lisez ces lignes, allez sur Zillow, recherchez une ville ou un quartier, copiez l&rsquo;URL des r\u00e9sultats et remplacez-la dans le code. <\/em><\/p>\n<p>Commen\u00e7ons par l&rsquo;installation :<\/p>\n<h3><strong>Conditions pr\u00e9alables<\/strong><\/h3>\n<p>Vous aurez besoin de trois choses avant de commencer :<\/p>\n<ul>\n<li><strong>Python 3.10 ou sup\u00e9rieur<\/strong> install\u00e9 sur votre machine<\/li>\n<li><strong>Un compte Floppydata<\/strong> avec une cl\u00e9 API pour le Web Unlocker<\/li>\n<li>Deux biblioth\u00e8ques Python : <strong>requests<\/strong> pour les appels HTTP et <strong>beautifulsoup4<\/strong> pour l&rsquo;analyse HTML.<\/li>\n<\/ul>\n<p>Si vous n&rsquo;avez pas encore de compte Floppydata, inscrivez-vous sur floppydata.com et r\u00e9cup\u00e9rez votre<strong> cl\u00e9 API<\/strong> dans le<a href=\"https:\/\/app.floppydata.com\/tools\/scrape\"> tableau de bord Web Unlocker<\/a>.<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-44259\" src=\"https:\/\/floppydata.com\/wp-content\/uploads\/2026\/05\/image1-3.png\" alt=\"Cl\u00e9 API\" width=\"1336\" height=\"646\" srcset=\"https:\/\/floppydata.com\/wp-content\/uploads\/2026\/05\/image1-3.png 1336w, https:\/\/floppydata.com\/wp-content\/uploads\/2026\/05\/image1-3-300x145.png 300w, https:\/\/floppydata.com\/wp-content\/uploads\/2026\/05\/image1-3-1024x495.png 1024w, https:\/\/floppydata.com\/wp-content\/uploads\/2026\/05\/image1-3-768x371.png 768w\" sizes=\"(max-width: 1336px) 100vw, 1336px\" \/><\/p>\n<p>Les nouveaux comptes b\u00e9n\u00e9ficient de <strong>cinq grattages gratuits<\/strong>, ce qui vous permet de suivre l&rsquo;int\u00e9gralit\u00e9 de ce tutoriel sans rien payer.<\/p>\n<p>La biblioth\u00e8que de requ\u00eates est g\u00e9n\u00e9ralement pr\u00e9install\u00e9e, mais vous pouvez ex\u00e9cuter cette commande pour vous assurer qu&rsquo;elle est correctement install\u00e9e :<\/p>\n<div style=\"margin: 18px 0 26px 0;\">\n<pre style=\"background: #f8fafc; border: 1px solid #e5e7eb; border-radius: 10px; padding: 16px 18px; margin: 0; font-size: 14px; line-height: 1.7;\"><code><span style=\"color: #9333ea;\">pip<\/span> <span style=\"color: #16a34a;\">install<\/span> requests beautifulsoup4<\/code><\/pre>\n<\/div>\n<p>Une fois cela fait, cr\u00e9ez un nouveau dossier et un nouveau fichier de projet :<\/p>\n<div style=\"margin: 18px 0 26px 0;\">\n<pre style=\"background: #f8fafc; border: 1px solid #e5e7eb; border-radius: 10px; padding: 16px 18px; margin: 0; font-size: 14px; line-height: 1.7;\"><code><span style=\"color: #9333ea;\">mkdir<\/span> zillow-scraper\n<span style=\"color: #9333ea;\">cd<\/span> zillow-scraper\n<span style=\"color: #9333ea;\">touch<\/span> zillow_scraper.py<\/code><\/pre>\n<\/div>\n<p>Vous \u00eates maintenant pr\u00eat \u00e0 partir.<\/p>\n<h3><strong>Envoi de la premi\u00e8re demande<\/strong><\/h3>\n<p>La premi\u00e8re chose que la plupart des gens essaient de faire est une requ\u00eate Python normale. Cela ressemble g\u00e9n\u00e9ralement \u00e0 ceci : <\/p>\n<div style=\"margin: 20px 0 28px 0;\">\n<pre style=\"background: #f8fafc; border: 1px solid #e5e7eb; border-radius: 10px; padding: 18px; margin: 0; font-size: 13px; line-height: 1.6; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;\"><code><span style=\"color: #ea580c;\">import<\/span> requests\n\n<span style=\"color: #0891b2;\">url<\/span> = <span style=\"color: #dc2626;\">\"https:\/\/www.zillow.com\/boston-ma\/\"<\/span>\n<span style=\"color: #0891b2;\">response<\/span> = <span style=\"color: #9333ea;\">requests.get<\/span>(<span style=\"color: #0891b2;\">url<\/span>)\n\n<span style=\"color: #9333ea;\">print<\/span>(<span style=\"color: #0891b2;\">response<\/span>.status_code)\n<span style=\"color: #9333ea;\">print<\/span>(<span style=\"color: #0891b2;\">response<\/span>.text)<\/code><\/pre>\n<\/div>\n<p>Mais lorsque j&rsquo;ai test\u00e9 cela, il n&rsquo;a m\u00eame pas fallu deux essais, car ma toute premi\u00e8re demande est revenue bloqu\u00e9e. J&rsquo;ai obtenu une r\u00e9ponse 403 avec une page de blocage PerimeterX : <\/p>\n<div style=\"margin: 20px 0 28px 0;\">\n<pre style=\"background: #f8fafc; border: 1px solid #e5e7eb; border-radius: 10px; padding: 18px; margin: 0; font-size: 13px; line-height: 1.6; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;\"><code><span style=\"color: #16a34a;\">403<\/span>\n<span style=\"color: #9333ea;\">&lt;!DOCTYPE<\/span> <span style=\"color: #16a34a;\">html<\/span><span style=\"color: #9333ea;\">&gt;<\/span>\n<span style=\"color: #9333ea;\">&lt;html<\/span> <span style=\"color: #16a34a;\">lang=<\/span><span style=\"color: #dc2626;\">\"en\"<\/span><span style=\"color: #9333ea;\">&gt;<\/span>\n<span style=\"color: #9333ea;\">&lt;head&gt;<\/span>\n  <span style=\"color: #9333ea;\">&lt;meta<\/span> <span style=\"color: #16a34a;\">charset=<\/span><span style=\"color: #dc2626;\">\"utf-8\"<\/span><span style=\"color: #9333ea;\">&gt;<\/span>\n  <span style=\"color: #9333ea;\">&lt;meta<\/span> <span style=\"color: #16a34a;\">name=<\/span><span style=\"color: #dc2626;\">\"viewport\"<\/span> <span style=\"color: #16a34a;\">content=<\/span><span style=\"color: #dc2626;\">\"width=device-width, initial-scale=1\"<\/span><span style=\"color: #9333ea;\">&gt;<\/span>\n  <span style=\"color: #9333ea;\">&lt;meta<\/span> <span style=\"color: #16a34a;\">name=<\/span><span style=\"color: #dc2626;\">\"description\"<\/span> <span style=\"color: #16a34a;\">content=<\/span><span style=\"color: #dc2626;\">\"px-captcha\"<\/span><span style=\"color: #9333ea;\">&gt;<\/span>\n  <span style=\"color: #9333ea;\">&lt;title&gt;<\/span>Access to this page has been denied<span style=\"color: #9333ea;\">&lt;\/title&gt;<\/span>\n<span style=\"color: #9333ea;\">&lt;\/head&gt;<\/span><\/code><\/pre>\n<\/div>\n<p>C&rsquo;est le probl\u00e8me avec le scraping direct de Zillow. Une requ\u00eate Python normale ne se comporte pas comme une v\u00e9ritable session de navigation. Elle n&rsquo;a pas non plus l&#8217;empreinte digitale du navigateur, la qualit\u00e9 IP ou le rendu JavaScript qui permettent \u00e0 Zillow de la rep\u00e9rer imm\u00e9diatement et de bloquer la requ\u00eate.  <\/p>\n<p>C&rsquo;est pourquoi je ne construis pas le scraper principal autour d&rsquo;appels directs <strong>requests() <\/strong>\u00e0 Zillow. Au lieu de cela, j&rsquo;envoie mes requ\u00eates via le Web Unlocker de Floppydata et je le laisse s&rsquo;occuper des parties difficiles. <\/p>\n<h2><strong>Scraping Zillow avec Floppydata Web Unlocker<\/strong><\/h2>\n<p>Envoyons une requ\u00eate \u00e0 la page de recherche \u00e0 l&rsquo;aide du Web Unlocker. Zillow n&rsquo;est pas la cible la plus difficile \u00e0 gratter, mais elle se soucie de la r\u00e9putation de l&rsquo;IP et du comportement du navigateur. <\/p>\n<p>C&rsquo;est l\u00e0 que le Web Unlocker entre en jeu. Il fait passer votre demande par une adresse IP r\u00e9sidentielle de confiance, applique une empreinte digitale r\u00e9elle du navigateur et renvoie le code HTML enti\u00e8rement rendu. <\/p>\n<p>Ce que j&rsquo;appr\u00e9cie particuli\u00e8rement chez Floppydata, c&rsquo;est que vous ne payez que pour les requ\u00eates r\u00e9ussies. Si un scrape \u00e9choue, il n&rsquo;est pas pris en compte dans votre consommation. <\/p>\n<p>Le tableau de bord affiche \u00e9galement des analyses en temps r\u00e9el des demandes, ce qui vous permet de suivre votre utilisation, les taux de r\u00e9ussite et les cr\u00e9dits restants sans quitter la page.<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-44268\" src=\"https:\/\/floppydata.com\/wp-content\/uploads\/2026\/05\/image4-4.png\" alt=\"Floppydata Web Unlocker  \" width=\"1999\" height=\"1129\"><\/p>\n<p>Avant d&rsquo;\u00e9crire du code, j&rsquo;aime bien tester l&rsquo;URL cible dans le<a href=\"https:\/\/app.floppydata.com\/tools\/scrape\"> Web Unlocker <\/a>sans code. Cela me permet de voir la r\u00e9ponse HTML avant de construire un analyseur, de sorte que je sais exactement \u00e0 quels s\u00e9lecteurs et \u00e0 quelles donn\u00e9es m&rsquo;attendre. <\/p>\n<p>L&rsquo;utilisation de l&rsquo;outil Web Unlocker est simple comme bonjour. Ouvrez simplement le <a href=\"https:\/\/app.floppydata.com\/tools\/scrape\">Web Unlocker<\/a> \u00e0 partir de votre tableau de bord Floppydata. Collez ensuite l&rsquo;URL<a href=\"https:\/\/www.zillow.com\/boston-ma\/\" target=\"_blank\" rel=\"noopener\">\u00ab\u00a0https:\/\/www.zillow.com\/boston-ma\/\u00a0\u00bb<\/a>, cliquez sur le bouton <strong>Scrape <\/strong>et attendez quelques secondes.  <\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-44278\" src=\"https:\/\/floppydata.com\/wp-content\/uploads\/2026\/05\/image2-3.png\" alt=\"Web Unlocker\" width=\"1159\" height=\"881\" srcset=\"https:\/\/floppydata.com\/wp-content\/uploads\/2026\/05\/image2-3.png 1159w, https:\/\/floppydata.com\/wp-content\/uploads\/2026\/05\/image2-3-300x228.png 300w, https:\/\/floppydata.com\/wp-content\/uploads\/2026\/05\/image2-3-1024x778.png 1024w, https:\/\/floppydata.com\/wp-content\/uploads\/2026\/05\/image2-3-768x584.png 768w\" sizes=\"(max-width: 1159px) 100vw, 1159px\" \/><\/p>\n<p>Une fois le scrape termin\u00e9, consultez le panneau de <strong>pr\u00e9visualisation de la sortie<\/strong> ci-dessous. Vous devriez voir la page HTML compl\u00e8te contenant les r\u00e9sultats de notre recherche Zillow. <\/p>\n<p>Si les donn\u00e9es semblent satisfaisantes, utilisez <strong>Copier HTML<\/strong> pour les r\u00e9cup\u00e9rer ou <strong>T\u00e9l\u00e9charger<\/strong> pour enregistrer le fichier localement.<\/p>\n<h3><strong>Comprendre la structure de pagination de Zillow<\/strong><\/h3>\n<p>L&rsquo;aper\u00e7u de la sortie renvoie du HTML brut, ce qui est utile car je peux inspecter la structure exacte avant d&rsquo;\u00e9crire du code.<\/p>\n<p>Cela revient \u00e0 ouvrir les outils de d\u00e9veloppement du navigateur en appuyant sur <strong>F12<\/strong> et \u00e0 inspecter la page directement. Dans le code HTML t\u00e9l\u00e9charg\u00e9, j&rsquo;ai trouv\u00e9 un \u00e9l\u00e9ment important qui facilite grandement l&rsquo;analyseur. <\/p>\n<p>La plupart des tutoriels vous diront de saisir les fiches d&rsquo;inscription avec des s\u00e9lecteurs CSS, mais Zillow ne rend que 9 fiches dans le balisage de la page. Les 32 autres se chargent au fur et \u00e0 mesure que vous d\u00e9filez, de sorte que le scraping avec des s\u00e9lecteurs CSS passe \u00e0 c\u00f4t\u00e9 de la plupart des donn\u00e9es. <\/p>\n<p>Les r\u00e9sultats de la recherche se trouvent plut\u00f4t \u00e0 l&rsquo;int\u00e9rieur d&rsquo;un grand objet JSON dans la page HTML. Ce JSON se trouve \u00e0 l&rsquo;int\u00e9rieur de cette balise script : <\/p>\n<div style=\"margin: 20px 0 28px 0;\">\n<pre style=\"background: #f8fafc; border: 1px solid #e5e7eb; border-radius: 10px; padding: 18px; margin: 0; font-size: 13px; line-height: 1.6; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;\"><code><span style=\"color: #9333ea;\">&lt;script<\/span> <span style=\"color: #16a34a;\">id=<\/span><span style=\"color: #dc2626;\">\"__NEXT_DATA__\"<\/span> <span style=\"color: #16a34a;\">type=<\/span><span style=\"color: #dc2626;\">\"application\/json\"<\/span><span style=\"color: #9333ea;\">&gt;<\/span><\/code><\/pre>\n<\/div>\n<p>La page utilise ce JSON pour charger les donn\u00e9es sur le frontend, et nous pouvons \u00e9galement le lire. \u00c0 l&rsquo;int\u00e9rieur de ce JSON, les listes se trouvent \u00e0 cet endroit pr\u00e9cis : <\/p>\n<div style=\"margin: 20px 0 28px 0;\">\n<pre style=\"background: #f8fafc; border: 1px solid #e5e7eb; border-radius: 10px; padding: 18px; margin: 0; font-size: 13px; line-height: 1.6; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;\"><code><span style=\"color: #0891b2;\">data<\/span>[<span style=\"color: #dc2626;\">\"props\"<\/span>][<span style=\"color: #dc2626;\">\"pageProps\"<\/span>][<span style=\"color: #dc2626;\">\"searchPageState\"<\/span>][<span style=\"color: #dc2626;\">\"cat1\"<\/span>][<span style=\"color: #dc2626;\">\"searchResults\"<\/span>][<span style=\"color: #dc2626;\">\"listResults\"<\/span>]<\/code><\/pre>\n<\/div>\n<p>Notre plan d&rsquo;analyse est donc simple.<\/p>\n<p>Nous allons trouver le script <strong>__NEXT_DATA__ <\/strong>avec BeautifulSoup, analyser le JSON, aller dans le tableau <strong>listResults<\/strong>, et extraire les champs dont nous avons besoin.<\/p>\n<h2><strong>Zillow web scraping avec Python et Web Unlocker<\/strong><\/h2>\n<p>Nous pouvons maintenant passer du tableau de bord au code.<\/p>\n<p>Le snippet du tableau de bord utilise <strong>httpx<\/strong>, mais je vais utiliser <strong>requests<\/strong> ici parce que c&rsquo;est plus familier pour la plupart des lecteurs de Python.<\/p>\n<h3><strong>\u00c9tape 1 : \u00c9tablir la demande<\/strong><\/h3>\n<p>Commen\u00e7ons par la configuration de base. Nous avons besoin du point de terminaison Web Unlocker, de notre cl\u00e9 API et de l&rsquo;URL cible de Zillow : <\/p>\n<div style=\"margin: 20px 0 28px 0;\">\n<pre style=\"background: #f8fafc; border: 1px solid #e5e7eb; border-radius: 10px; padding: 18px; margin: 0; font-size: 13px; line-height: 1.6; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;\"><code><span style=\"color: #ea580c;\">import<\/span> requests\n<span style=\"color: #ea580c;\">import<\/span> json\n<span style=\"color: #ea580c;\">from<\/span> bs4 <span style=\"color: #ea580c;\">import<\/span> BeautifulSoup\n\n<span style=\"color: #0891b2;\">API_URL<\/span> = <span style=\"color: #dc2626;\">\"https:\/\/client-api.floppy.host\/v1\/webUnlocker\"<\/span>\n<span style=\"color: #0891b2;\">API_KEY<\/span> = <span style=\"color: #dc2626;\">\"YOUR_API_KEY\"<\/span>\n<span style=\"color: #0891b2;\">SEARCH_URL<\/span> = <span style=\"color: #dc2626;\">\"https:\/\/www.zillow.com\/boston-ma\/\"<\/span>\n\n<span style=\"color: #0891b2;\">SEARCH_URL<\/span> = <span style=\"color: #dc2626;\">\"live_zillow_boston.json\"<\/span><\/code><\/pre>\n<\/div>\n<p><em>Remplacer <\/em><strong><em>VOTRE_CL\u00c9_API<\/em><\/strong><em> par la cl\u00e9 de votre tableau de bord Floppydata.<\/em><\/p>\n<p>J&rsquo;utilise Boston comme march\u00e9 cible ici, mais si vous voulez r\u00e9cup\u00e9rer une autre ville, remplacez simplement l&rsquo;URL de recherche.<\/p>\n<h3><strong>\u00c9tape 2 : R\u00e9cup\u00e9rer la page \u00e0 l&rsquo;aide de Web Unlocker<\/strong><\/h3>\n<p>Le Web Unlocker prend une charge utile JSON avec l&rsquo;URL cible et quelques options. Il renvoie une r\u00e9ponse JSON qui contient le code HTML rendu dans un champ <strong>html :<\/strong>  <\/p>\n<p>Je cr\u00e9e maintenant une fonction <strong>fetch_html()<\/strong>pour envoyer l&rsquo;URL de Zillow \u00e0 Web Unlocker et renvoyer le code HTML rendu.<\/p>\n<div style=\"margin: 20px 0 28px 0;\">\n<pre style=\"background: #f8fafc; border: 1px solid #e5e7eb; border-radius: 10px; padding: 18px; margin: 0; font-size: 13px; line-height: 1.6; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;\"><code><span style=\"color: #ea580c;\">def<\/span> <span style=\"color: #9333ea;\">fetch_html<\/span>(<span style=\"color: #0891b2;\">url<\/span>):\n    <span style=\"color: #0891b2;\">response<\/span> = <span style=\"color: #9333ea;\">requests.post<\/span>(\n        <span style=\"color: #0891b2;\">API_URL<\/span>,\n        headers={\n            <span style=\"color: #dc2626;\">\"Content-Type\"<\/span>: <span style=\"color: #dc2626;\">\"application\/json\"<\/span>,\n            <span style=\"color: #dc2626;\">\"X-Api-Key\"<\/span>: <span style=\"color: #0891b2;\">API_KEY<\/span>,\n        },\n        json={\n            <span style=\"color: #dc2626;\">\"url\"<\/span>: <span style=\"color: #0891b2;\">url<\/span>,\n            <span style=\"color: #dc2626;\">\"country\"<\/span>: <span style=\"color: #dc2626;\">\"US\"<\/span>,\n            <span style=\"color: #dc2626;\">\"city\"<\/span>: <span style=\"color: #dc2626;\">\"Boston\"<\/span>,\n            <span style=\"color: #dc2626;\">\"difficulty\"<\/span>: <span style=\"color: #dc2626;\">\"medium\"<\/span>,\n            <span style=\"color: #dc2626;\">\"expiration\"<\/span>: <span style=\"color: #16a34a;\">0<\/span>,\n        },\n        timeout=<span style=\"color: #16a34a;\">120<\/span>,\n    )\n    <span style=\"color: #0891b2;\">response<\/span>.<span style=\"color: #9333ea;\">raise_for_status<\/span>()\n\n    <span style=\"color: #0891b2;\">data<\/span> = <span style=\"color: #0891b2;\">response<\/span>.<span style=\"color: #9333ea;\">json<\/span>()\n    <span style=\"color: #0891b2;\">html<\/span> = <span style=\"color: #0891b2;\">data<\/span>.<span style=\"color: #9333ea;\">get<\/span>(<span style=\"color: #dc2626;\">\"html\"<\/span>)\n\n    <span style=\"color: #ea580c;\">if<\/span> <span style=\"color: #ea580c;\">not<\/span> <span style=\"color: #0891b2;\">html<\/span>:\n        <span style=\"color: #ea580c;\">raise<\/span> <span style=\"color: #9333ea;\">ValueError<\/span>(<span style=\"color: #dc2626;\">\"Unlocker response did not include an 'html' field.\"<\/span>)\n\n    <span style=\"color: #ea580c;\">return<\/span> <span style=\"color: #0891b2;\">html<\/span><\/code><\/pre>\n<\/div>\n<p>Il se passe plusieurs choses ici. Les champs \u00a0\u00bb <strong>pays<\/strong> \u00a0\u00bb et \u00a0\u00bb <strong>ville\u00a0\u00bb<\/strong> permettent \u00e0 la demande de mieux correspondre \u00e0 l&#8217;emplacement cible. J&rsquo;ai utilis\u00e9 la <strong>difficult\u00e9 : \u00ab\u00a0moyenne\u00a0\u00bb<\/strong> parce que Zillow n&rsquo;est pas une simple page statique, et qu&rsquo;elle n\u00e9cessite donc un processus de d\u00e9blocage plus puissant.  <\/p>\n<p>Le champ d&rsquo;<strong>expiration<\/strong> est fix\u00e9 \u00e0 <strong>0<\/strong>, de sorte que j&rsquo;obtiens une nouvelle r\u00e9ponse. Lorsque la demande aboutit, Web Unlocker renvoie une r\u00e9ponse JSON, et le code HTML rendu se trouve dans le champ <strong>html<\/strong>. <\/p>\n<h3><strong>\u00c9tape 3 : Extraire les listes<\/strong><\/h3>\n<p>Nous pouvons maintenant appliquer le plan d&rsquo;analyse syntaxique que nous avons \u00e9labor\u00e9 pr\u00e9c\u00e9demment. Je vais cr\u00e9er une fonction <strong>extract_listings()<\/strong>. Cette fonction prend le HTML, trouve les donn\u00e9es JSON de Zillow et extrait les annonces :  <\/p>\n<div style=\"margin: 20px 0 28px 0;\">\n<pre style=\"background: #f8fafc; border: 1px solid #e5e7eb; border-radius: 10px; padding: 18px; margin: 0; font-size: 13px; line-height: 1.6; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;\"><code><span style=\"color: #ea580c;\">def<\/span> <span style=\"color: #9333ea;\">extract_listings<\/span>(<span style=\"color: #0891b2;\">html<\/span>):\n    <span style=\"color: #0891b2;\">soup<\/span> = <span style=\"color: #9333ea;\">BeautifulSoup<\/span>(<span style=\"color: #0891b2;\">html<\/span>, <span style=\"color: #dc2626;\">\"html.parser\"<\/span>)\n    <span style=\"color: #0891b2;\">next_data<\/span> = <span style=\"color: #0891b2;\">soup<\/span>.<span style=\"color: #9333ea;\">find<\/span>(<span style=\"color: #dc2626;\">\"script\"<\/span>, id=<span style=\"color: #dc2626;\">\"__NEXT_DATA__\"<\/span>)\n\n    <span style=\"color: #ea580c;\">if<\/span> <span style=\"color: #ea580c;\">not<\/span> <span style=\"color: #0891b2;\">next_data<\/span> <span style=\"color: #ea580c;\">or<\/span> <span style=\"color: #ea580c;\">not<\/span> <span style=\"color: #0891b2;\">next_data<\/span>.string:\n        <span style=\"color: #ea580c;\">raise<\/span> <span style=\"color: #9333ea;\">ValueError<\/span>(<span style=\"color: #dc2626;\">\"Could not find Zillow's __NEXT_DATA__ script.\"<\/span>)\n\n    <span style=\"color: #0891b2;\">data<\/span> = <span style=\"color: #9333ea;\">json.loads<\/span>(<span style=\"color: #0891b2;\">next_data<\/span>.string)\n    <span style=\"color: #0891b2;\">search_state<\/span> = <span style=\"color: #0891b2;\">data<\/span>.<span style=\"color: #9333ea;\">get<\/span>(<span style=\"color: #dc2626;\">\"props\"<\/span>, {}).<span style=\"color: #9333ea;\">get<\/span>(<span style=\"color: #dc2626;\">\"pageProps\"<\/span>, {}).<span style=\"color: #9333ea;\">get<\/span>(<span style=\"color: #dc2626;\">\"searchPageState\"<\/span>, {})\n    <span style=\"color: #0891b2;\">list_results<\/span> = (\n        <span style=\"color: #0891b2;\">search_state<\/span>.<span style=\"color: #9333ea;\">get<\/span>(<span style=\"color: #dc2626;\">\"cat1\"<\/span>, {})\n        .<span style=\"color: #9333ea;\">get<\/span>(<span style=\"color: #dc2626;\">\"searchResults\"<\/span>, {})\n        .<span style=\"color: #9333ea;\">get<\/span>(<span style=\"color: #dc2626;\">\"listResults\"<\/span>, [])\n    )\n\n    <span style=\"color: #0891b2;\">listings<\/span> = []\n\n    <span style=\"color: #ea580c;\">for<\/span> <span style=\"color: #0891b2;\">item<\/span> <span style=\"color: #ea580c;\">in<\/span> <span style=\"color: #0891b2;\">list_results<\/span>:\n        <span style=\"color: #0891b2;\">listings<\/span>.<span style=\"color: #9333ea;\">append<\/span>(\n            {\n                <span style=\"color: #dc2626;\">\"zpid\"<\/span>: <span style=\"color: #0891b2;\">item<\/span>.<span style=\"color: #9333ea;\">get<\/span>(<span style=\"color: #dc2626;\">\"zpid\"<\/span>),\n                <span style=\"color: #dc2626;\">\"address\"<\/span>: <span style=\"color: #0891b2;\">item<\/span>.<span style=\"color: #9333ea;\">get<\/span>(<span style=\"color: #dc2626;\">\"address\"<\/span>),\n                <span style=\"color: #dc2626;\">\"price\"<\/span>: <span style=\"color: #0891b2;\">item<\/span>.<span style=\"color: #9333ea;\">get<\/span>(<span style=\"color: #dc2626;\">\"price\"<\/span>),\n                <span style=\"color: #dc2626;\">\"beds\"<\/span>: <span style=\"color: #0891b2;\">item<\/span>.<span style=\"color: #9333ea;\">get<\/span>(<span style=\"color: #dc2626;\">\"beds\"<\/span>),\n                <span style=\"color: #dc2626;\">\"baths\"<\/span>: <span style=\"color: #0891b2;\">item<\/span>.<span style=\"color: #9333ea;\">get<\/span>(<span style=\"color: #dc2626;\">\"baths\"<\/span>),\n                <span style=\"color: #dc2626;\">\"sqft\"<\/span>: <span style=\"color: #0891b2;\">item<\/span>.<span style=\"color: #9333ea;\">get<\/span>(<span style=\"color: #dc2626;\">\"area\"<\/span>),\n                <span style=\"color: #dc2626;\">\"status\"<\/span>: <span style=\"color: #0891b2;\">item<\/span>.<span style=\"color: #9333ea;\">get<\/span>(<span style=\"color: #dc2626;\">\"statusType\"<\/span>),\n                <span style=\"color: #dc2626;\">\"url\"<\/span>: <span style=\"color: #0891b2;\">item<\/span>.<span style=\"color: #9333ea;\">get<\/span>(<span style=\"color: #dc2626;\">\"detailUrl\"<\/span>),\n            }\n        )\n\n    <span style=\"color: #ea580c;\">return<\/span> <span style=\"color: #0891b2;\">listings<\/span><\/code><\/pre>\n<\/div>\n<p>En utilisant BeautifulSoup, je peux facilement aller directement au JSON structur\u00e9 \u00e0 l&rsquo;int\u00e9rieur de la page. Ensuite, j&rsquo;ai analys\u00e9 le contenu du script en JSON et j&rsquo;ai obtenu le tableau <strong>listResults<\/strong>. <\/p>\n<p>Chaque \u00e9l\u00e9ment de listResults est une fiche de propri\u00e9t\u00e9, et pour chaque fiche, nous pouvons collecter des donn\u00e9es pr\u00e9cieuses telles que<\/p>\n<ul>\n<li>adresse<\/li>\n<li>prix<\/li>\n<li>lits<\/li>\n<li>bains<\/li>\n<li>zone<\/li>\n<li>statusType<\/li>\n<li>detailUrl<\/li>\n<\/ul>\n<p>J&rsquo;ai renomm\u00e9 la surface en sqft dans le r\u00e9sultat final parce que c&rsquo;est plus facile \u00e0 comprendre.<\/p>\n<h3><strong>\u00c9tape 4 : Enregistrer les r\u00e9sultats dans un fichier JSON<\/strong><\/h3>\n<p>Enfin, nous pouvons ajouter une fonction <strong>main()<\/strong> pour ex\u00e9cuter le scraper et enregistrer la sortie dans un fichier JSON : <\/p>\n<div style=\"margin: 20px 0 28px 0;\">\n<pre style=\"background: #f8fafc; border: 1px solid #e5e7eb; border-radius: 10px; padding: 18px; margin: 0; font-size: 13px; line-height: 1.6; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;\"><code><span style=\"color: #ea580c;\">def<\/span> <span style=\"color: #9333ea;\">main<\/span>():\n    <span style=\"color: #9333ea;\">print<\/span>(<span style=\"color: #dc2626;\">f\"Fetching data from: {<span style=\"color: #0891b2;\">SEARCH_URL<\/span>}\"<\/span>)\n    <span style=\"color: #0891b2;\">html<\/span> = <span style=\"color: #9333ea;\">fetch_html<\/span>(<span style=\"color: #0891b2;\">SEARCH_URL<\/span>)\n    <span style=\"color: #0891b2;\">listings<\/span> = <span style=\"color: #9333ea;\">extract_listings<\/span>(<span style=\"color: #0891b2;\">html<\/span>)\n\n    <span style=\"color: #ea580c;\">if<\/span> <span style=\"color: #ea580c;\">not<\/span> <span style=\"color: #0891b2;\">listings<\/span>:\n        <span style=\"color: #ea580c;\">raise<\/span> <span style=\"color: #9333ea;\">SystemExit<\/span>(<span style=\"color: #dc2626;\">\"No listings found in Zillow's JSON data.\"<\/span>)\n\n    <span style=\"color: #ea580c;\">with<\/span> <span style=\"color: #9333ea;\">open<\/span>(<span style=\"color: #0891b2;\">OUTPUT_FILE<\/span>, <span style=\"color: #dc2626;\">\"w\"<\/span>, encoding=<span style=\"color: #dc2626;\">\"utf-8\"<\/span>) <span style=\"color: #ea580c;\">as<\/span> <span style=\"color: #0891b2;\">file<\/span>:\n        <span style=\"color: #9333ea;\">json.dump<\/span>(<span style=\"color: #0891b2;\">listings<\/span>, <span style=\"color: #0891b2;\">file<\/span>, indent=<span style=\"color: #16a34a;\">2<\/span>)\n\n    <span style=\"color: #9333ea;\">print<\/span>(<span style=\"color: #dc2626;\">f\"Found {<span style=\"color: #9333ea;\">len<\/span>(<span style=\"color: #0891b2;\">listings<\/span>)} listings\"<\/span>)\n    <span style=\"color: #9333ea;\">print<\/span>(<span style=\"color: #dc2626;\">f\"Saved results to {<span style=\"color: #0891b2;\">OUTPUT_FILE<\/span>}\"<\/span>)<\/code><\/pre>\n<\/div>\n<p>Cette fonction r\u00e9cup\u00e8re la page, extrait les listes, v\u00e9rifie que la liste n&rsquo;est pas vide et enregistre le tout dans un fichier JSON. Une fois que les donn\u00e9es ont l&rsquo;air correctes, nous pouvons les convertir au format CSV ou les utiliser directement dans nos applications. <\/p>\n<h3><strong>Le sc\u00e9nario complet<\/strong><\/h3>\n<p>Voici tout le code que j&rsquo;ai utilis\u00e9 pour extraire avec succ\u00e8s mes listes Zillow :<\/p>\n<div style=\"margin: 20px 0 28px 0;\">\n<pre style=\"background: #f8fafc; border: 1px solid #e5e7eb; border-radius: 10px; padding: 18px; margin: 0; font-size: 13px; line-height: 1.6; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;\"><code><span style=\"color: #ea580c;\">from<\/span> bs4 <span style=\"color: #ea580c;\">import<\/span> BeautifulSoup\n<span style=\"color: #ea580c;\">import<\/span> requests\n<span style=\"color: #ea580c;\">import<\/span> json\n\n<span style=\"color: #0891b2;\">API_URL<\/span> = <span style=\"color: #dc2626;\">\"https:\/\/client-api.floppy.host\/v1\/webUnlocker\"<\/span>\n<span style=\"color: #0891b2;\">API_KEY<\/span> = <span style=\"color: #dc2626;\">\"Your_API_KEY\"<\/span>\n<span style=\"color: #0891b2;\">SEARCH_URL<\/span> = <span style=\"color: #dc2626;\">\"https:\/\/www.zillow.com\/boston-ma\/\"<\/span>\n<span style=\"color: #0891b2;\">OUTPUT_FILE<\/span> = <span style=\"color: #dc2626;\">\"live_zillow_boston.json\"<\/span>\n\n\n<span style=\"color: #ea580c;\">def<\/span> <span style=\"color: #9333ea;\">fetch_html<\/span>(<span style=\"color: #0891b2;\">url<\/span>):\n    <span style=\"color: #0891b2;\">response<\/span> = <span style=\"color: #9333ea;\">requests.post<\/span>(\n        <span style=\"color: #0891b2;\">API_URL<\/span>,\n        headers={\n            <span style=\"color: #dc2626;\">\"Content-Type\"<\/span>: <span style=\"color: #dc2626;\">\"application\/json\"<\/span>,\n            <span style=\"color: #dc2626;\">\"X-Api-Key\"<\/span>: <span style=\"color: #0891b2;\">API_KEY<\/span>,\n        },\n        json={\n            <span style=\"color: #dc2626;\">\"url\"<\/span>: <span style=\"color: #0891b2;\">url<\/span>,\n            <span style=\"color: #dc2626;\">\"country\"<\/span>: <span style=\"color: #dc2626;\">\"US\"<\/span>,\n            <span style=\"color: #dc2626;\">\"city\"<\/span>: <span style=\"color: #dc2626;\">\"Boston\"<\/span>,\n            <span style=\"color: #dc2626;\">\"difficulty\"<\/span>: <span style=\"color: #dc2626;\">\"medium\"<\/span>,\n            <span style=\"color: #dc2626;\">\"expiration\"<\/span>: <span style=\"color: #16a34a;\">0<\/span>,\n        },\n        timeout=<span style=\"color: #16a34a;\">120<\/span>,\n    )\n    <span style=\"color: #0891b2;\">response<\/span>.<span style=\"color: #9333ea;\">raise_for_status<\/span>()\n\n    <span style=\"color: #0891b2;\">data<\/span> = <span style=\"color: #0891b2;\">response<\/span>.<span style=\"color: #9333ea;\">json<\/span>()\n    <span style=\"color: #0891b2;\">html<\/span> = <span style=\"color: #0891b2;\">data<\/span>.<span style=\"color: #9333ea;\">get<\/span>(<span style=\"color: #dc2626;\">\"html\"<\/span>)\n\n    <span style=\"color: #ea580c;\">if<\/span> <span style=\"color: #ea580c;\">not<\/span> <span style=\"color: #0891b2;\">html<\/span>:\n        <span style=\"color: #ea580c;\">raise<\/span> <span style=\"color: #9333ea;\">ValueError<\/span>(<span style=\"color: #dc2626;\">\"Unlocker response did not include an 'html' field.\"<\/span>)\n\n    <span style=\"color: #ea580c;\">return<\/span> <span style=\"color: #0891b2;\">html<\/span>\n\n\n<span style=\"color: #ea580c;\">def<\/span> <span style=\"color: #9333ea;\">extract_listings<\/span>(<span style=\"color: #0891b2;\">html<\/span>):\n    <span style=\"color: #0891b2;\">soup<\/span> = <span style=\"color: #9333ea;\">BeautifulSoup<\/span>(<span style=\"color: #0891b2;\">html<\/span>, <span style=\"color: #dc2626;\">\"html.parser\"<\/span>)\n    <span style=\"color: #0891b2;\">next_data<\/span> = <span style=\"color: #0891b2;\">soup<\/span>.<span style=\"color: #9333ea;\">find<\/span>(<span style=\"color: #dc2626;\">\"script\"<\/span>, id=<span style=\"color: #dc2626;\">\"__NEXT_DATA__\"<\/span>)\n\n    <span style=\"color: #ea580c;\">if<\/span> <span style=\"color: #ea580c;\">not<\/span> <span style=\"color: #0891b2;\">next_data<\/span> <span style=\"color: #ea580c;\">or<\/span> <span style=\"color: #ea580c;\">not<\/span> <span style=\"color: #0891b2;\">next_data<\/span>.string:\n        <span style=\"color: #ea580c;\">raise<\/span> <span style=\"color: #9333ea;\">ValueError<\/span>(<span style=\"color: #dc2626;\">\"Could not find Zillow's __NEXT_DATA__ script.\"<\/span>)\n\n    <span style=\"color: #0891b2;\">data<\/span> = <span style=\"color: #9333ea;\">json.loads<\/span>(<span style=\"color: #0891b2;\">next_data<\/span>.string)\n    <span style=\"color: #0891b2;\">search_state<\/span> = <span style=\"color: #0891b2;\">data<\/span>.<span style=\"color: #9333ea;\">get<\/span>(<span style=\"color: #dc2626;\">\"props\"<\/span>, {}).<span style=\"color: #9333ea;\">get<\/span>(<span style=\"color: #dc2626;\">\"pageProps\"<\/span>, {}).<span style=\"color: #9333ea;\">get<\/span>(<span style=\"color: #dc2626;\">\"searchPageState\"<\/span>, {})\n    <span style=\"color: #0891b2;\">list_results<\/span> = (\n        <span style=\"color: #0891b2;\">search_state<\/span>.<span style=\"color: #9333ea;\">get<\/span>(<span style=\"color: #dc2626;\">\"cat1\"<\/span>, {})\n        .<span style=\"color: #9333ea;\">get<\/span>(<span style=\"color: #dc2626;\">\"searchResults\"<\/span>, {})\n        .<span style=\"color: #9333ea;\">get<\/span>(<span style=\"color: #dc2626;\">\"listResults\"<\/span>, [])\n    )\n\n    <span style=\"color: #0891b2;\">listings<\/span> = []\n\n    <span style=\"color: #ea580c;\">for<\/span> <span style=\"color: #0891b2;\">item<\/span> <span style=\"color: #ea580c;\">in<\/span> <span style=\"color: #0891b2;\">list_results<\/span>:\n        <span style=\"color: #0891b2;\">listings<\/span>.<span style=\"color: #9333ea;\">append<\/span>(\n            {\n                <span style=\"color: #dc2626;\">\"zpid\"<\/span>: <span style=\"color: #0891b2;\">item<\/span>.<span style=\"color: #9333ea;\">get<\/span>(<span style=\"color: #dc2626;\">\"zpid\"<\/span>),\n                <span style=\"color: #dc2626;\">\"address\"<\/span>: <span style=\"color: #0891b2;\">item<\/span>.<span style=\"color: #9333ea;\">get<\/span>(<span style=\"color: #dc2626;\">\"address\"<\/span>),\n                <span style=\"color: #dc2626;\">\"price\"<\/span>: <span style=\"color: #0891b2;\">item<\/span>.<span style=\"color: #9333ea;\">get<\/span>(<span style=\"color: #dc2626;\">\"price\"<\/span>),\n                <span style=\"color: #dc2626;\">\"beds\"<\/span>: <span style=\"color: #0891b2;\">item<\/span>.<span style=\"color: #9333ea;\">get<\/span>(<span style=\"color: #dc2626;\">\"beds\"<\/span>),\n                <span style=\"color: #dc2626;\">\"baths\"<\/span>: <span style=\"color: #0891b2;\">item<\/span>.<span style=\"color: #9333ea;\">get<\/span>(<span style=\"color: #dc2626;\">\"baths\"<\/span>),\n                <span style=\"color: #dc2626;\">\"sqft\"<\/span>: <span style=\"color: #0891b2;\">item<\/span>.<span style=\"color: #9333ea;\">get<\/span>(<span style=\"color: #dc2626;\">\"area\"<\/span>),\n                <span style=\"color: #dc2626;\">\"status\"<\/span>: <span style=\"color: #0891b2;\">item<\/span>.<span style=\"color: #9333ea;\">get<\/span>(<span style=\"color: #dc2626;\">\"statusType\"<\/span>),\n                <span style=\"color: #dc2626;\">\"url\"<\/span>: <span style=\"color: #0891b2;\">item<\/span>.<span style=\"color: #9333ea;\">get<\/span>(<span style=\"color: #dc2626;\">\"detailUrl\"<\/span>),\n            }\n        )\n\n    <span style=\"color: #ea580c;\">return<\/span> <span style=\"color: #0891b2;\">listings<\/span>\n\n\n<span style=\"color: #ea580c;\">def<\/span> <span style=\"color: #9333ea;\">main<\/span>():\n    <span style=\"color: #9333ea;\">print<\/span>(<span style=\"color: #dc2626;\">f\"Fetching data from: {<span style=\"color: #0891b2;\">SEARCH_URL<\/span>}\"<\/span>)\n    <span style=\"color: #0891b2;\">html<\/span> = <span style=\"color: #9333ea;\">fetch_html<\/span>(<span style=\"color: #0891b2;\">SEARCH_URL<\/span>)\n    <span style=\"color: #0891b2;\">listings<\/span> = <span style=\"color: #9333ea;\">extract_listings<\/span>(<span style=\"color: #0891b2;\">html<\/span>)\n\n    <span style=\"color: #ea580c;\">if<\/span> <span style=\"color: #ea580c;\">not<\/span> <span style=\"color: #0891b2;\">listings<\/span>:\n        <span style=\"color: #ea580c;\">raise<\/span> <span style=\"color: #9333ea;\">SystemExit<\/span>(<span style=\"color: #dc2626;\">\"No listings found in Zillow's JSON data.\"<\/span>)\n\n    <span style=\"color: #ea580c;\">with<\/span> <span style=\"color: #9333ea;\">open<\/span>(<span style=\"color: #0891b2;\">OUTPUT_FILE<\/span>, <span style=\"color: #dc2626;\">\"w\"<\/span>, encoding=<span style=\"color: #dc2626;\">\"utf-8\"<\/span>) <span style=\"color: #ea580c;\">as<\/span> <span style=\"color: #0891b2;\">file<\/span>:\n        <span style=\"color: #9333ea;\">json.dump<\/span>(<span style=\"color: #0891b2;\">listings<\/span>, <span style=\"color: #0891b2;\">file<\/span>, indent=<span style=\"color: #16a34a;\">2<\/span>)\n\n    <span style=\"color: #9333ea;\">print<\/span>(<span style=\"color: #dc2626;\">f\"Found {<span style=\"color: #9333ea;\">len<\/span>(<span style=\"color: #0891b2;\">listings<\/span>)} listings\"<\/span>)\n    <span style=\"color: #9333ea;\">print<\/span>(<span style=\"color: #dc2626;\">f\"Saved results to {<span style=\"color: #0891b2;\">OUTPUT_FILE<\/span>}\"<\/span>)\n\n\n<span style=\"color: #ea580c;\">if<\/span> <span style=\"color: #6366f1;\">__name__<\/span> == <span style=\"color: #dc2626;\">\"__main__\"<\/span>:\n    <span style=\"color: #9333ea;\">main<\/span>()<\/code><\/pre>\n<\/div>\n<p>Si tout est configur\u00e9 correctement, vous devriez obtenir un r\u00e9sultat comme celui-ci :<\/p>\n<div style=\"margin: 20px 0 28px 0;\">\n<pre style=\"background: #f8fafc; border: 1px solid #e5e7eb; border-radius: 10px; padding: 18px; margin: 0; font-size: 13px; line-height: 1.6; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;\"><code>[\n  {\n    <span style=\"color: #dc2626;\">\"zpid\"<\/span>: <span style=\"color: #dc2626;\">\"59174136\"<\/span>,\n    <span style=\"color: #dc2626;\">\"address\"<\/span>: <span style=\"color: #dc2626;\">\"45 Garden St APT 3, Boston, MA 02114\"<\/span>,\n    <span style=\"color: #dc2626;\">\"price\"<\/span>: <span style=\"color: #dc2626;\">\"$685,000\"<\/span>,\n    <span style=\"color: #dc2626;\">\"beds\"<\/span>: <span style=\"color: #16a34a;\">2<\/span>,\n    <span style=\"color: #dc2626;\">\"baths\"<\/span>: <span style=\"color: #16a34a;\">1<\/span>,\n    <span style=\"color: #dc2626;\">\"sqft\"<\/span>: <span style=\"color: #16a34a;\">525<\/span>,\n    <span style=\"color: #dc2626;\">\"status\"<\/span>: <span style=\"color: #dc2626;\">\"FOR_SALE\"<\/span>,\n    <span style=\"color: #dc2626;\">\"url\"<\/span>: <span style=\"color: #dc2626;\">\"https:\/\/www.zillow.com\/homedetails\/45-Garden-St-APT-3-Boston-MA-02114\/59174136_zpid\/\"<\/span>\n  }\n]<\/code><\/pre>\n<\/div>\n<p>\u00c0 ce stade, votre scraper fonctionne, ce qui signifie que vous \u00eates maintenant en mesure de r\u00e9cup\u00e9rer des informations cl\u00e9s \u00e0 partir de n&rsquo;importe quel listing Zillow.<\/p>\n<h2><strong>D\u00e9pannage des probl\u00e8mes courants<\/strong><\/h2>\n<p>Si vous exploitez souvent les donn\u00e9es immobili\u00e8res de Zillow, vous vous heurterez certainement \u00e0 des obstacles \u00e0 un moment ou \u00e0 un autre. J&rsquo;en ai moi-m\u00eame rencontr\u00e9 quelques-uns. Je peux donc vous dire \u00e0 quoi vous attendre, notamment :  <\/p>\n<ul>\n<li><strong>Erreurs<\/strong><strong>403<\/strong>: Cela signifie que Zillow a bloqu\u00e9 votre robot. Essayez de modifier vos en-t\u00eates ou d&rsquo;utiliser un proxy pour continuer \u00e0 r\u00e9cup\u00e9rer les donn\u00e9es de Zillow. <\/li>\n<li><strong>R\u00e9ponses<\/strong><strong>vides<\/strong>: Cela peut \u00eatre d\u00fb au rendu JavaScript. Essayez d&rsquo;utiliser un outil qui rend enti\u00e8rement la page avant de renvoyer le code HTML, comme le Web Unlocker. <\/li>\n<li><strong>Donn\u00e9es<\/strong><strong>manquantes<\/strong>: Toutes les annonces ne contiennent pas les m\u00eames informations. Utilisez toujours .get() lorsque vous r\u00e9cup\u00e9rez des donn\u00e9es Zillow afin que votre scraper ne se plante pas sur une cl\u00e9 manquante.<\/li>\n<\/ul>\n<p>Zillow n&rsquo;offrant pas d&rsquo;API gratuite, vous devrez trouver un moyen de la contourner. Si vous avez besoin d&rsquo;un moyen fiable d&rsquo;acc\u00e9der aux donn\u00e9es d&rsquo;inscription de Zillow, le Web Unlocker de Floppydata est votre meilleur choix. <\/p>\n<h2><strong>Conclusion<\/strong><\/h2>\n<p>Zillow ne ressemble pas \u00e0 un site hautement s\u00e9curis\u00e9, mais il est prot\u00e9g\u00e9 par PerimeterX et un syst\u00e8me de d\u00e9tection \u00e0 plusieurs niveaux qui surveille votre IP, vos en-t\u00eates, votre empreinte TLS et vos signaux comportementaux. Si vous agissez de mani\u00e8re suspecte, vous serez signal\u00e9 et banni pour une dur\u00e9e ind\u00e9termin\u00e9e. <\/p>\n<p>C&rsquo;est pourquoi vous devez \u00eatre prudent lorsque vous les r\u00e9cup\u00e9rez. C&rsquo;est l\u00e0 que Floppydata Web Unlocker intervient. Il :  <\/p>\n<ul>\n<li>Rotation des procurations r\u00e9sidentielles premium<\/li>\n<li>Rotation des en-t\u00eates et empreinte r\u00e9elle du navigateur<\/li>\n<li>Chargement propre et HTML complet \u00e0 chaque fois<\/li>\n<li>Factures uniquement pour les r\u00e9ponses positives<\/li>\n<\/ul>\n<p>Avec cette configuration, vous n&rsquo;avez pas \u00e0 combattre le syst\u00e8me anti-bot de Zillow par vous-m\u00eame ; laissez Floppy Data Web Unlocker vous aider. <a href=\"https:\/\/app.floppydata.com\/tools\/scrape\">Commencez \u00e0 scraper Zillow<\/a> d\u00e8s maintenant avec <strong>5 scraps gratuits<\/strong>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction Zillow \u00e9tant l&rsquo;une des principales plateformes immobili\u00e8res aux \u00c9tats-Unis, de nombreuses entreprises souhaitent y puiser des donn\u00e9es sur les biens immobiliers. La plateforme re\u00e7oit actuellement environ 243 millions de visites par mois, et contient donc naturellement une grande quantit\u00e9 de donn\u00e9es immobili\u00e8res utiles. Cependant, les d\u00e9veloppeurs partagent souvent sur Reddit leurs difficult\u00e9s \u00e0 contourner [&hellip;]<\/p>\n","protected":false},"author":20,"featured_media":44290,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[439,487,561],"tags":[],"class_list":["post-44369","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog","category-how-to","category-scraping"],"acf":[],"_links":{"self":[{"href":"https:\/\/floppydata.com\/fr\/wp-json\/wp\/v2\/posts\/44369","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/floppydata.com\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/floppydata.com\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/floppydata.com\/fr\/wp-json\/wp\/v2\/users\/20"}],"replies":[{"embeddable":true,"href":"https:\/\/floppydata.com\/fr\/wp-json\/wp\/v2\/comments?post=44369"}],"version-history":[{"count":0,"href":"https:\/\/floppydata.com\/fr\/wp-json\/wp\/v2\/posts\/44369\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/floppydata.com\/fr\/wp-json\/wp\/v2\/media\/44290"}],"wp:attachment":[{"href":"https:\/\/floppydata.com\/fr\/wp-json\/wp\/v2\/media?parent=44369"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/floppydata.com\/fr\/wp-json\/wp\/v2\/categories?post=44369"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/floppydata.com\/fr\/wp-json\/wp\/v2\/tags?post=44369"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}