Homes.com listet Immobiliendaten in den gesamten Vereinigten Staaten auf, und die Such- und Angebots-Seiten enthalten genau die strukturierten Felder, die für Preisverfolgung, Marktforschung und Investitionsanalyse benötigt werden: einen Angebotsstitel, die Straßenadresse, den Angebotspreis, Schlafzimmer, Badezimmer, Wohnfläche und den Link zur jeweiligen Immobilie. Einmal in eine Tabelle übertragen, lassen sich Stadtteile vergleichen, Preisentwicklungen beobachten und lohnende Angebote herausfiltern, ohne hunderte von Seiten manuell durchzuklicken.
Diese Anleitung zeigt Ihnen, wie Sie Homes.com scrapen mit Python auf zuverlässige Weise. Sie erstellen einen kleinen, lauffähigen Scraper, der eine gerenderte Suchseite über die Crawling API abruft, die gewünschten Felder mit BeautifulSoup parst, die Pagination durchläuft und die Ergebnisse als JSON und CSV speichert. Die gesamte Anleitung beschränkt sich auf öffentliche Angebotsdaten. Der Abschnitt zur Rechtslage am Ende ist kein Boilerplate, lesen Sie ihn also, bevor Sie den Scraper auf größere Mengen ansetzen.
Was Sie bauen werden
Ein Python-Skript, das eine öffentliche Homes.com-Such-URL entgegennimmt, das gerenderte HTML über die Crawling API abruft, mehrere Ergebnisseiten durchläuft und pro Angebot einen strukturierten Datensatz extrahiert. Als durchgängiges Beispiel verwenden wir eine Stadtsuche und lesen folgende Felder aus:
- Titel der Angebotstyp, zum Beispiel "House for Rent" oder "Condo for Rent".
- Adresse die Straßenadresse der Immobilie.
- Preis der auf der Karte angezeigte Angebotspreis oder die monatliche Miete.
- Beds die Anzahl der Schlafzimmer.
- Baths die Anzahl der Badezimmer.
- Size die Wohnfläche, sofern das Angebot sie ausweist.
- Link die absolute URL zur vollständigen Immobiliendetailseite.
Warum ein einfacher Request bei Homes.com scheitert
Wenn Sie eine Homes.com-Such-URL mit einem einfachen HTTP-Client anfordern, erhalten Sie eine Antwort mit Status 200, aber kaum Angebotsdaten im Body. Zwei Faktoren arbeiten gegen Sie. Erstens rendert Homes.com einen Großteil seiner Inhalte im Browser per JavaScript, sodass das initiale HTML nur eine leere Hülle ist, die sich erst nach Ausführung der Seitenskripte füllt. Zweitens erkennt die Website automatisierten Traffic schnell: Datacenter-IPs und Anfragemuster, die nicht nach einem echten Browser aussehen, werden rate-limited, mit einer Challenge versehen oder erhalten ein Captcha, bevor sie überhaupt den gerenderten Inhalt erreichen.
Ein funktionierender Homes.com-Scraper benötigt daher zwei Dinge in einer einzigen Anfrage: einen Browser, der die Seite tatsächlich rendert, und eine IP-Adresse, die die Plattform als echten Besucher einordnet. Das lässt sich selbst mit einem Headless-Browser plus einem Pool rotierender Residential-Proxys zusammensetzen, aber das Zusammenführen und Pflegen dieser Komponenten ist der aufwändigste Teil. Die Crawling API fasst beides in einem einzigen Aufruf zusammen: Sie übergeben ihr die URL mit einem JavaScript-Token, sie rendert die Seite hinter einer vertrauenswürdigen IP und liefert fertig gerenderte HTML zur Weiterverarbeitung. Mehr darüber, warum dynamische Seiten dies erfordern, erfahren Sie unter how to crawl JavaScript websites.
Crawlbase bietet zwei Token-Typen. Das normale Token ruft statisches HTML ab; das JavaScript-Token (JS-Token) rendert die Seite zunächst in einem echten Browser. Da Homes.com seine Angebotsfelder clientseitig befüllt, benötigen Sie hier das JS-Token. Das normale Token liefert dieselbe leere Hülle wie ein einfacher Fetch, und es gibt nichts Verwertbares darin zu parsen.
Voraussetzungen
Sie benötigen einige Dinge, bevor Sie Code schreiben. Keines davon nimmt viel Zeit in Anspruch.
Grundlegendes Python-Wissen. Sie sollten in der Lage sein, ein Python-Skript zu schreiben und auszuführen sowie Pakete mit pip zu installieren. Wenn Sie neu in der Sprache sind, bietet die Anleitung scrape a website with Python die Grundlagen, die dieses Tutorial voraussetzt.
Python 3.8 oder höher. Prüfen Sie Ihre Version mit python --version. Falls Sie es nicht haben, installieren Sie es von python.org oder über eine Distribution wie Anaconda.
Ein Crawlbase-Konto und ein JS-Token. Registrieren Sie sich, öffnen Sie Ihr Dashboard und kopieren Sie Ihr JavaScript-Token (JS-Token) von der Account-Docs-Seite. Sie erhalten bis zu 20.000 kostenlose Anfragen, eine Kreditkarte ist nicht erforderlich. Behandeln Sie das Token wie ein Passwort: Es authentifiziert Ihre Anfragen, halten Sie es also aus der Versionskontrolle heraus.
Projekt einrichten
Erstellen Sie eine virtuelle Umgebung, damit die Projektabhängigkeiten isoliert bleiben, und installieren Sie dann die zwei Bibliotheken, die der Scraper benötigt.
python --version python -m venv homes_scraping_env source homes_scraping_env/bin/activate pip install crawlbase beautifulsoup4
Unter Windows aktivieren Sie die Umgebung mit homes_scraping_env\Scripts\activate statt der source-Zeile. Zwei Abhängigkeiten erledigen die Arbeit: crawlbase ist der offizielle Client für die Crawling API, und beautifulsoup4 parst das zurückgegebene HTML, sodass Sie einzelne Felder per CSS-Selector extrahieren können. Falls Sie den Parser noch nicht kennen, ist der BeautifulSoup-Leitfaden eine gute Ergänzung zu diesem Tutorial.
Schritt 1: Die gerenderte Suchseite abrufen
Beginnen Sie damit, die fertig gerenderte Seite zu holen. Importieren Sie die CrawlingAPI-Klasse, initialisieren Sie sie mit Ihrem JS-Token und fordern Sie die Such-URL an. Die beiden Wait-Optionen sind bei einem clientseitig gerenderten Ziel wichtig: ajax_wait weist die API an, auf das Ende asynchroner Inhalte zu warten, und page_wait hält eine festgelegte Anzahl von Millisekunden nach dem Laden an, damit spät gerenderte Elemente vor der Seitenerfassung erscheinen. Die Statusprüfung vor dem Parsen macht Fehler sofort sichtbar, anstatt sie zu verschleiern.
from crawlbase import CrawlingAPI crawling_api = CrawlingAPI({"token": "YOUR_CRAWLBASE_TOKEN"}) options = { "ajax_wait": "true", "page_wait": 10000, "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36", } def make_crawlbase_request(url): response = crawling_api.get(url, options) if response["headers"]["cb_status"] == "200": return response["body"].decode("utf-8") print(f"Failed to fetch the page. Crawlbase status: {response['headers']['cb_status']}") return None if __name__ == "__main__": url = "https://www.homes.com/los-angeles-ca/homes-for-rent/p1/" html = make_crawlbase_request(url) print(html[:500] if html else "No HTML returned")
Die Funktion liest response["headers"]["cb_status"], den anfragebezogenen Status, den die Crawling API zusammen mit dem Body zurückgibt, und gibt HTML nur dann zurück, wenn dieser Wert "200" lautet. Zehn Sekunden page_wait sind ein vernünftiger Ausgangswert für Homes.com; erhöhen Sie den Wert, wenn die Angebotsfelder leer zurückkommen. Führen Sie das Skript mit python homes_scraper.py aus, und Sie sollten echtes Such-Markup sehen, nicht die leere Hülle eines einfachen Fetches. Das bestätigt, dass das Rendering funktioniert, bevor Sie einen einzigen Selector schreiben.
Dieser einzelne make_crawlbase_request-Aufruf erledigt den schwierigen Teil für Sie. Homes.com benötigt eine gerenderte Seite hinter einer vertrauenswürdigen IP, und die Crawling API übernimmt mit Ihrem JS-Token das Rendering in einem echten Browser, rotiert serverseitig Residential-IPs und liefert fertiges HTML zurück, sodass Sie keinen Headless-Browser-Fleet und keinen Proxy-Pool selbst betreiben müssen. Testen Sie es zunächst mit einer öffentlichen Suchseite im kostenlosen Tarif.
Schritt 2: Die Angebotskarten mit BeautifulSoup parsen
Mit dem gerenderten HTML laden Sie es in BeautifulSoup und extrahieren jede Karte. Wenn Sie eine Homes.com-Suchseite in den Entwicklertools Ihres Browsers untersuchen, sehen Sie, dass jedes Angebot in einem div mit der Klasse for-rent-content-container eingebettet ist. Wählen Sie alle davon aus und lesen Sie anschließend die einzelnen Felder aus jeder Karte aus. Der Titel befindet sich in einem p.property-name, die Adresse in einem p.address, und Preis, Schlafzimmer sowie Badezimmer stammen aus den li-Elementen in ul.detailed-info-container, in dieser Reihenfolge.
from bs4 import BeautifulSoup BASE_URL = "https://www.homes.com" def parse_listings(html): soup = BeautifulSoup(html, "html.parser") cards = soup.select("div.for-rent-content-container") properties = [] for card in cards: title_elem = card.select_one("p.property-name") address_elem = card.select_one("p.address") info_container = card.select_one("ul.detailed-info-container") info = info_container.find_all("li") if info_container else [] link_elem = card.select_one("a") properties.append({ "title": title_elem.text.strip() if title_elem else "N/A", "address": address_elem.text.strip() if address_elem else "N/A", "price": info[0].text.strip() if len(info) > 0 else "N/A", "beds": info[1].text.strip() if len(info) > 1 else "N/A", "baths": info[2].text.strip() if len(info) > 2 else "N/A", "size": info[3].text.strip() if len(info) > 3 else "N/A", "link": BASE_URL + link_elem["href"] if link_elem and link_elem.get("href") else "N/A", }) return properties
Jede Sicherheitsabfrage gibt "N/A" zurück, anstatt einen Fehler zu werfen, wenn ein Element fehlt, sodass ein fehlendes Feld den Durchlauf nicht abbricht. Die Detailzeile ist positionsbasiert: Homes.com ordnet Preis, Schlafzimmer, Badezimmer und Größe als geordnete li-Elemente an, sodass der Code sie per Index liest und zuerst die Länge prüft. Der Link wird vom Anker der Karte als relativer Pfad übernommen, daher liefert das Voranstellen der BASE_URL eine absolute URL, mit der Sie direkt zur Immobiliendetailseite navigieren können.
Die Klassennamen von Homes.com (die for-rent-content-container-Karte, die Felder property-name und address, die Zeilen detailed-info-container) ändern sich ohne Vorankündigung. Betrachten Sie die obigen Selektoren als Startvorlage, nicht als Vertrag. Wenn ein Feld als "N/A" zurückkommt, untersuchen Sie die Live-Seite in den Entwicklertools Ihres Browsers und aktualisieren Sie den Selektor. Regelmäßige Selektor-Wartung ist für jeden produktiven Scraper normal, kein Zeichen für einen Fehler.
Schritt 3: Die Pagination durchlaufen
Eine Seite ist eine Demo; ein echter Job läuft über den gesamten Ergebnissatz. Homes.com hängt ein Seitensegment an den Suchpfad an, sodass die Angebote einer Stadt unter .../homes-for-rent/p1/, .../p2/ usw. zu finden sind. Laufen Sie über eine feste Anzahl von Seiten, rufen Sie jede über dieselbe Request-Funktion ab, parsen Sie die Karten und sammeln Sie alles in einer einzigen Liste. Eine kurze Pause zwischen den Seiten verhindert, dass der Durchlauf die Website überlastet.
import time SEARCH_URL = "https://www.homes.com/los-angeles-ca/homes-for-rent" MAX_PAGES = 3 def scrape_search(): properties = [] for page in range(1, MAX_PAGES + 1): url = f"{SEARCH_URL}/p{page}/" print(f"Scraping page {page}: {url}") html = make_crawlbase_request(url) if html: properties.extend(parse_listings(html)) time.sleep(2) return properties
Das time.sleep(2) zwischen den Seiten ist beabsichtigt: Es drosselt den Durchlauf, sodass Sie die Website nicht überlasten, was die effektivste Gewohnheit ist, um nicht blockiert zu werden. Passen Sie MAX_PAGES und den Stadt-Slug in SEARCH_URL an Ihr Ziel an. Um stattdessen Mietobjekte in Chicago zu scrapen, ersetzen Sie den Wert durch chicago-il; um Kaufangebote zu scrapen, ändern Sie homes-for-rent in den entsprechenden Kaufpfad.
Schritt 4: Als JSON und CSV exportieren
Mit einer Liste von Datensätzen schreiben Sie diese in das Format, das Ihre nachgelagerte Verarbeitung benötigt. JSON behält die Struktur für Code, der sie wieder einliest; CSV lässt sich direkt in eine Tabelle für Sortierung und Diagramme laden. Zwei kleine Hilfsfunktionen decken beide Fälle ab.
import json import csv def save_to_json(properties, filename="properties.json"): with open(filename, "w") as f: json.dump(properties, f, indent=4) def save_to_csv(properties, filename="properties.csv"): if not properties: return with open(filename, "w", newline="") as f: writer = csv.DictWriter(f, fieldnames=properties[0].keys()) writer.writeheader() writer.writerows(properties)
Der CSV-Writer liest seine Spaltenüberschriften aus den Schlüsseln des ersten Datensatzes, sodass die Spalten mit den in Schritt 2 geparsten Feldern synchron bleiben. Wenn Sie dort ein Feld hinzufügen oder umbenennen, folgen beide Exporte automatisch.
Alles zusammensetzen
Hier ist der vollständige, lauffähige Scraper: jede Suchseite über die Crawling API abrufen, die Karten parsen, die Pagination durchlaufen und die Ergebnisse als JSON und CSV speichern. Fügen Sie Ihr Token ein und führen Sie das Skript aus.
import json import csv import time from crawlbase import CrawlingAPI from bs4 import BeautifulSoup crawling_api = CrawlingAPI({"token": "YOUR_CRAWLBASE_TOKEN"}) BASE_URL = "https://www.homes.com" SEARCH_URL = "https://www.homes.com/los-angeles-ca/homes-for-rent" MAX_PAGES = 3 options = { "ajax_wait": "true", "page_wait": 10000, "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36", } def make_crawlbase_request(url): response = crawling_api.get(url, options) if response["headers"]["cb_status"] == "200": return response["body"].decode("utf-8") print(f"Failed to fetch the page. Crawlbase status: {response['headers']['cb_status']}") return None def parse_listings(html): soup = BeautifulSoup(html, "html.parser") cards = soup.select("div.for-rent-content-container") properties = [] for card in cards: title_elem = card.select_one("p.property-name") address_elem = card.select_one("p.address") info_container = card.select_one("ul.detailed-info-container") info = info_container.find_all("li") if info_container else [] link_elem = card.select_one("a") properties.append({ "title": title_elem.text.strip() if title_elem else "N/A", "address": address_elem.text.strip() if address_elem else "N/A", "price": info[0].text.strip() if len(info) > 0 else "N/A", "beds": info[1].text.strip() if len(info) > 1 else "N/A", "baths": info[2].text.strip() if len(info) > 2 else "N/A", "size": info[3].text.strip() if len(info) > 3 else "N/A", "link": BASE_URL + link_elem["href"] if link_elem and link_elem.get("href") else "N/A", }) return properties def scrape_search(): properties = [] for page in range(1, MAX_PAGES + 1): url = f"{SEARCH_URL}/p{page}/" print(f"Scraping page {page}: {url}") html = make_crawlbase_request(url) if html: properties.extend(parse_listings(html)) time.sleep(2) return properties def save_to_json(properties, filename="properties.json"): with open(filename, "w") as f: json.dump(properties, f, indent=4) def save_to_csv(properties, filename="properties.csv"): if not properties: return with open(filename, "w", newline="") as f: writer = csv.DictWriter(f, fieldnames=properties[0].keys()) writer.writeheader() writer.writerows(properties) if __name__ == "__main__": listings = scrape_search() save_to_json(listings) save_to_csv(listings) print(f"Saved {len(listings)} listings to properties.json and properties.csv")
Wie die Ausgabe aussieht
Führen Sie das vollständige Skript mit python homes_scraper.py aus und erhalten Sie pro Angebot einen sauberen Datensatz, der in JSON, CSV oder eine Datenbank geschrieben werden kann.
[ { "title": "Condo for Rent", "address": "3824 Keystone Ave Unit 2, Culver City, CA 90232", "price": "$3,300 per month", "beds": "2 Beds", "baths": "1.5 Baths", "size": "1,100 Sq Ft", "link": "https://www.homes.com/los-angeles-ca/homes-for-rent/property/3824-keystone-ave-culver-city-ca-unit-2/2er2mwklw8zq6/" }, { "title": "House for Rent", "address": "3901 Alonzo Ave, Encino, CA 91316", "price": "$17,000 per month", "beds": "4 Beds", "baths": "3.5 Baths", "size": "3,400 Sq Ft", "link": "https://www.homes.com/los-angeles-ca/homes-for-rent/property/3901-alonzo-ave-encino-ca/879negnf45nee/" } ]
Die CSV-Version derselben Daten enthält eine Zeile pro Angebot mit den Spalten title, address, price, beds, baths, size und link, die sich in jeder Tabelle sauber öffnet und nach Preis sortieren oder nach Stadtteil filtern lässt.
Zu Immobiliendetailseiten skalieren
Der Such-Scraper liefert die Felder auf Kartenebene. Wenn Sie die vollständigen Details einer einzelnen Immobilie benötigen, folgen Sie dem bereits erfassten link und parsen Sie die Immobiliendetailseite, die reichhaltigere Felder enthält: Grundstücksgröße, eine ausführlichere Beschreibung und die öffentlich sichtbare Kontaktzeile des Maklers. Die Immobiliendetailseite verwendet eigene Selektoren: Die Adresse befindet sich in div.property-info-address, der Preis in span#price, Schlafzimmer und Badezimmer in span.feature-beds und span.feature-baths, und die Grundstücksgröße in span.property-info-feature.lotsize. Verwenden Sie make_crawlbase_request erneut, um die Seite abzurufen, und wenden Sie dieselben Selektoren wie bei den Karten an. Drosseln Sie jeden Abruf mit einem kurzen Sleep, genau wie die Such-Schleife es tut.
Nicht blockiert werden
Auch wenn das Rendering bereits gehandhabt wird, beobachtet Homes.com weiterhin Scraper-typischen Traffic. Einige Gewohnheiten halten einen Durchlauf gesund, und sie gelten für jedes schwierige kommerzielle Ziel.
-
Anfragen drosseln. Seiten in einer engen Schleife zu hämmern ist der schnellste Weg, um rate-limited zu werden oder ein Captcha zu erhalten. Verteilen Sie Anfragen, wie das obige
sleepes tut, und variieren Sie Ihre Ziele statt einen Pfad mit voller Geschwindigkeit zu crawlen. - Rotation nutzen. Ein Pool von Residential-IPs verteilt Anfragen über viele echte Nutzeradressen, sodass keine einzelne davon ein Rate-Limit auslöst. Die Crawling API erledigt das für Sie; wenn Sie einen eigenen Stack aufbauen, ist das der Teil, den Sie richtig hinbekommen müssen.
- Statuscodes lesen. Ein Durchlauf, der beginnt, Challenges oder Fehler zurückzugeben, signalisiert Ihnen, dass die aktuelle Rate oder IP-Stufe nicht mehr ausreicht. Behandeln Sie das als Signal zum Zurückrudern, nicht als Rauschen, das Sie ignorieren können.
Das umfassendere Playbook finden Sie unter how to scrape websites without getting blocked. Wenn Sie lieber Ihren eigenen Traffic über einen rotierenden Pool leiten möchten statt die verwaltete API zu verwenden, bietet der Smart AI Proxy (auch AI Proxy genannt) dieselbe Residential-IP-Rotation als Drop-in-Proxy-Endpunkt. Derselbe Ansatz lässt sich auf andere Immobilienwebsites übertragen: Lesen Sie unsere Anleitungen zum Scrapen von Zillow, Scrapen von Redfin und Scrapen von Realtor.com.
Ist das Scrapen von Homes.com legal?
Ob das Scrapen von Homes.com erlaubt ist, hängt von den Nutzungsbedingungen von Homes.com, Ihrer Rechtsprechung und dem ab, was Sie mit den Daten tun. Die Nutzungsbedingungen schränken den automatisierten Zugriff ein, sodass das Scrapen gegen diese Bedingungen verstoßen kann, unabhängig davon, wie sorgfältig Ihre Tools sind. Keiner der Codes hier ändert daran etwas; er macht nur den technischen Teil funktionsfähig. Lesen Sie die Nutzungsbedingungen von Homes.com und dessen robots.txt, respektieren Sie etwaige festgelegte Rate-Limits und behandeln Sie beides als Grenze für das, was Sie sammeln.
Einige Grundsätze, an die es sich zu halten lohnt. Sammeln Sie nur öffentliche Angebotsdaten: den Titel, die Adresse, den Preis, die Anzahl der Schlafzimmer und Badezimmer, die Wohnfläche und den Link, die jeder ohne Konto sehen kann. Halten Sie Ihr Anfragevolumen niedrig genug, um die Server der Website nicht zu belasten. Vermeiden Sie alles, was mit identifizierbaren Personen zusammenhängt, einschließlich der Namen und Kontaktdaten von Maklern, Eigentümern oder Verwaltern auf einer Seite. Diese sind personenbezogene Daten, und ihre Erfassung oder Speicherung kann Datenschutzgesetze wie die DSGVO und den CCPA ins Spiel bringen. Lassen Sie sie also weg, es sei denn, Sie haben eine klare rechtliche Grundlage und einen echten Bedarf.
Ein weiterer Punkt ist für Immobilien spezifisch: Ein Großteil der zugrunde liegenden Angebotsdaten stammt von Multiple Listing Services (MLS), und diese Daten sind häufig unter Bedingungen lizenziert, die eine Weitergabe einschränken. Wenn Ihr Projekt diese Tiefe oder eine kommerzielle Massennutzung benötigt, ist der richtige Weg ein lizenzierter MLS-Feed oder ein offizielles Datenabkommen, kein ausgefeilterer Scraper. Diese Anleitung beschränkt sich bewusst auf öffentliche Angebotsseiten, weil das die Grenze ist, die die Arbeit vertretbar hält. Sie umfasst nichts hinter einem Login, Konto- oder gespeicherten Suchdaten, persönliche Daten von Maklern oder Eigentümern oder Versuche, Authentifizierung zu umgehen. Nur öffentliche Angebotsdaten.
Wichtigste Erkenntnisse
- Homes.com wird clientseitig gerendert. Ein einfacher Fetch liefert eine leere Hülle, daher müssen Sie die Seite rendern, bevor Sie sie parsen.
-
Sie benötigen Rendering und eine vertrauenswürdige IP zusammen. Die Crawling API mit einem JS-Token erledigt beides in einem Aufruf;
ajax_waitundpage_waitsteuern, wie lange auf Inhalte gewartet wird. -
BeautifulSoup übernimmt die Extraktion. Ordnen Sie Titel, Adresse, Preis, Schlafzimmer, Badezimmer, Größe und Link den
for-rent-content-container-Kartenselektoren zu, und rechnen Sie damit, dass sich diese Selektoren ändern. -
Pagination durchlaufen, dann exportieren. Iterieren Sie das
p{page}-Segment, sammeln Sie jede Karte, drosseln Sie den Durchlauf mit einem kurzen Sleep und schreiben Sie die Ergebnisse als JSON und CSV. - Auf öffentliche Daten beschränken. Respektieren Sie die AGB und robots.txt von Homes.com, sammeln Sie nur öffentliche Angebotsfelder, lassen Sie persönliche Daten von Maklern und Eigentümern weg, und nutzen Sie für alles Kommerzielle oder Massenhafte einen lizenzierten MLS-Feed.
Häufig gestellte Fragen
Warum liefert ein einfacher Request keine Daten von Homes.com?
Weil Homes.com seinen Angebotscontent clientseitig mit JavaScript rendert. Das initiale HTML ist eine Hülle, die sich erst nach Ausführung der Seitenskripte in einem Browser füllt, sodass ein roher HTTP-Request Status 200 mit leeren Feldern für Preis, Schlafzimmer, Badezimmer und Größe zurückgibt. Um echte Daten zu erhalten, müssen Sie die Seite zunächst rendern, was das JS-Token der Crawling API für Sie übernimmt.
Benötige ich das normale Token oder das JS-Token für Homes.com?
Das JS-Token. Das normale Token ruft statisches HTML ab, das bei Homes.com dieselbe leere Hülle wie ein einfacher Request ist. Das JS-Token rendert die Seite in einem echten Browser, bevor es das HTML zurückgibt, sodass die Angebotsfelder vorhanden sind, wenn BeautifulSoup sie parst. Die Optionen ajax_wait und page_wait teilen dem Renderer mit, wie lange er auf diesen Inhalt warten soll.
Welche Daten kann ich von einem Homes.com-Angebot scrapen?
Öffentliche Angebotsfelder: den Titel, die Straßenadresse, den Angebotspreis oder die monatliche Miete, die Anzahl der Schlafzimmer und Badezimmer, die Wohnfläche sofern angegeben, und den Link zur Immobiliendetailseite. Beschränken Sie sich auf Daten, die für jeden Besucher ohne Konto sichtbar sind, und vermeiden Sie die persönlichen Daten von Maklern oder Eigentümern, die außerhalb des in dieser Anleitung abgedeckten Bereichs öffentlicher Angebotsdaten liegen.
Meine Selektoren liefern "N/A". Was hat sich geändert?
Höchstwahrscheinlich das Markup von Homes.com. Die for-rent-content-container-Karte, die Felder property-name und address sowie die detailed-info-container-Zeilen ändern sich ohne Vorankündigung, sodass Selektoren, die letzten Monat funktionierten, brechen können. Untersuchen Sie eine Live-Seite in den Entwicklertools Ihres Browsers und aktualisieren Sie die Selektoren. Regelmäßige Selektor-Wartung ist für jeden produktiven Scraper normal.
Wie gehe ich mit der Pagination über die Angebote einer Stadt vor?
Homes.com hängt ein p{page}-Segment an den Suchpfad an, sodass Sie .../p1/, .../p2/ usw. in einer Schleife abrufen, die Karten auf jeder Seite parsen und sie in einer Liste sammeln. Halten Sie zwischen den Anfragen einen kurzen Sleep ein und stoppen Sie bei Ihrem gewählten Seitenlimit. Die oben gezeigte scrape_search-Funktion zeigt die vollständige Schleife.
Wie vermeide ich es, beim Scrapen von Homes.com blockiert zu werden?
Halten Sie Ihre pro-IP-Anfragerate niedrig, drosseln Sie Anfragen mit einer kurzen Verzögerung, variieren Sie Ihre Ziele statt einen Pfad zu schleifen, und leiten Sie Traffic durch rotierende Residential-IPs, sodass keine einzelne Adresse ein Rate-Limit auslöst. Die Crawling API verwaltet Rotation und einen vertrauenswürdigen IP-Pool für Sie; wenn Sie Ihren eigenen Stack aufbauen, ist das der Teil, in den Sie investieren sollten. Beobachten Sie die Statuscodes und rudern Sie zurück, wenn Sie beginnen, Challenges zu sehen.
Crawlen Sie jede Website im großen Maßstab, ohne gegen die Infrastruktur zu kämpfen.
Crawlbase übernimmt Proxys, Fingerprints und CAPTCHAs, damit Ihr Team Datenpipelines ausliefert, statt Crawl-Infrastruktur zu pflegen. 1.000 Anfragen kostenlos, keine Karte erforderlich.
