Houzz ist eine der größten Plattformen für Wohndesign, Möbel und Renovierung und verbindet einen umfangreichen Produktkatalog mit redaktioneller Inspiration. Seine öffentlichen Produkt- und Listing-Seiten enthalten genau die strukturierten Daten, die Preisbeobachtung, Wettbewerbsanalyse und Trendauswertung antreiben: den Produktnamen, den Preis, die Bewertung und die Anzahl der Rezensionen, den Verkäufer oder die Marke, die Kategorie und den Link zurück zu jeder Produktseite. Diese Daten von Hand über eine Kategorie mit Hunderten von Produkten hinweg zu erfassen ist langsam und fehleranfällig.
Diese Anleitung zeigt Ihnen, wie Sie Houzz-Daten scrapen, und zwar mit Python auf zuverlässige Weise. Sie bauen einen kleinen, lauffähigen Scraper, der gerenderte Houzz-Seiten über die Crawling API abruft, Produktlinks aus einem Kategorie-Listing sammelt, die gewünschten Felder mit BeautifulSoup parst, die Paginierung verarbeitet und sauberes JSON und CSV exportiert. Die gesamte Schritt-für-Schritt-Anleitung bleibt auf öffentliche Produktdaten beschränkt, und der Abschnitt zur Rechtslage gegen Ende ist kein Standardtext, lesen Sie ihn also, bevor Sie das auf reales Volumen richten.
Was Sie bauen werden
Ein Python-Skript, das eine öffentliche Houzz-Kategorie-URL entgegennimmt, die Produktseiten-Links sammelt, jede gerenderte Seite über die Crawling API abruft und einen strukturierten Datensatz pro Produkt extrahiert. Das durchgehende Beispiel ist die Kategorie der Badezimmer-Waschtische und Waschtischkonsolen. Wir ziehen diese Felder heraus:
- Name der Produktname, wie er auf der Karte und der Produktseite angezeigt wird.
- Preis der gelistete Preis des Produkts.
- Bewertung die durchschnittliche Sternebewertung.
- Rezensionen die Anzahl der Kundenrezensionen hinter dieser Bewertung.
- Verkäufer der Verkäufer, Shop oder die Marke, die das Produkt anbietet.
- Kategorie die Kategorie, in der das Produkt liegt.
- Link die kanonische URL der Produktseite.
Warum eine einfache Anfrage bei Houzz scheitert
Wenn Sie eine Houzz-Kategorie- oder Produkt-URL mit einem nackten HTTP-Client anfragen, erhalten Sie eine Antwort mit Status 200 und nur einem Bruchteil der Daten im Body. Zwei Dinge arbeiten gegen Sie. Erstens rendert Houzz den Großteil seines Produktrasters und der Produktdetails im Browser über JavaScript, sodass das anfängliche HTML eine dünne Hülle ist, die sich erst füllt, nachdem die Skripte der Seite laufen. Ziehen Sie die Produktkarten aus dieser ersten Antwort heraus, erfassen Sie eine Handvoll Einträge oder gar keine. Zweitens markiert Houzz automatisierten Traffic schnell: Rechenzentrums-IPs und Muster, die nicht wie ein echter Browser aussehen, werden rate-limitiert, IP-blockiert oder herausgefordert, bevor sie die gerenderten Inhalte erreichen.
Ein funktionierender Houzz-Scraper braucht also zwei Dinge in einer Anfrage: einen Browser, der die Seite tatsächlich rendert, und eine IP, die die Plattform als echten Besucher liest. Das können Sie selbst mit einem Headless-Browser plus einem Pool rotierender Residential-Proxys zusammenstellen, aber diese gesund zu halten ist der Großteil der Arbeit. Die Crawling API fasst beides in einem einzigen Aufruf zusammen: Sie senden ihr die URL mit einem JavaScript-Token, sie rendert die Seite hinter einer vertrauenswürdigen IP und gibt Ihnen fertiges HTML zum Parsen zurück. Falls JavaScript-lastige Ziele für Sie neu sind, behandelt der Leitfaden zum Crawlen von JavaScript-Websites das Warum ausführlicher.
Crawlbase bietet zwei Token-Typen. Das normale Token ruft statisches HTML ab; das JavaScript-Token (JS) rendert die Seite zuerst in einem echten Browser. Houzz füllt sein Produktraster und seine Produktfelder clientseitig, daher brauchen Sie hier das JS-Token. Das normale Token gibt dieselbe dünne Hülle zurück, die auch ein einfacher Abruf liefern würde, und es gibt wenig Brauchbares daraus zu parsen.
Voraussetzungen
Bevor Sie Code schreiben, müssen einige Dinge vorhanden sein. Keines davon dauert lange.
Python-Grundkenntnisse. Sie sollten sich damit auskennen, ein Python-Skript zu schreiben und auszuführen sowie Pakete mit pip zu installieren. Falls die Parsing-Seite für Sie neu ist, ist der BeautifulSoup-Leitfaden ein guter Begleiter zu diesem Tutorial.
Python 3.8 oder neuer. Bestätigen Sie Ihre Version mit python --version. Falls Sie es nicht haben, installieren Sie es von python.org oder über eine Distribution wie Anaconda, und stellen Sie sicher, dass Python in Ihrem PATH liegt.
Ein Crawlbase-Konto und JS-Token. Registrieren Sie sich, öffnen Sie Ihr Dashboard und kopieren Sie Ihr JavaScript-Token (JS) von der Account-Docs-Seite. Crawlbase enthält bis zu 5.000 kostenlose Anfragen zum Start, was reichlich ist, um diese Anleitung durchzuarbeiten. Behandeln Sie das Token wie ein Passwort: Es authentifiziert Ihre Anfragen, halten Sie es also aus der Versionskontrolle heraus.
Das Projekt einrichten
Erstellen Sie eine virtuelle Umgebung, damit die Projektabhängigkeiten isoliert bleiben, und installieren Sie dann die Bibliotheken, die der Scraper braucht.
python --version python -m venv houzz_env source houzz_env/bin/activate pip install crawlbase beautifulsoup4
Unter Windows aktivieren Sie die Umgebung mit houzz_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-Selektor herausziehen können. Sowohl json als auch csv sind in der Standardbibliothek enthalten, es gibt für den Export-Schritt also nichts weiter zu installieren.
Schritt 1: Eine gerenderte Houzz-Seite abrufen
Beginnen Sie damit, eine fertige Seite zu holen. Importieren Sie die Klasse CrawlingAPI, initialisieren Sie sie mit Ihrem JS-Token und fragen Sie eine Houzz-Kategorie-URL an. Houzz lädt sein Raster asynchron, übergeben Sie also ajax_wait und page_wait, um auf die dynamischen Inhalte zu warten, bevor die Seite erfasst wird. Den Crawlbase-cb_status (legacy pc_status) vor dem Parsen zu prüfen hält Fehler laut statt still.
from crawlbase import CrawlingAPI api = CrawlingAPI({"token": "YOUR_CRAWLBASE_TOKEN"}) OPTIONS = { "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/122.0", "ajax_wait": "true", "page_wait": 5000, } def crawl(page_url): response = api.get(page_url, OPTIONS) if response["headers"]["cb_status"] == "200": return response["body"].decode("utf-8") print(f"Request failed: {response['headers']['cb_status']}") return None if __name__ == "__main__": listing_url = "https://www.houzz.com/products/bathroom-vanities-and-sink-consoles/best-sellers--best-sellers" html = crawl(listing_url) print(html[:500] if html else "No HTML returned")
Die beiden Wartoptionen sind für ein clientseitig gerendertes Ziel wie Houzz wichtig. ajax_wait weist die API an, auf den Abschluss des Ladens asynchroner Inhalte zu warten, und page_wait hält für eine feste Anzahl von Millisekunden nach dem Laden, sodass spät rendernde Karten erscheinen, bevor die Seite erfasst wird. Fünf Sekunden sind ein vernünftiger Start; erhöhen Sie den Wert, falls die Ergebnisse dünn zurückkommen. Führen Sie das Skript mit python houzz_scraper.py aus, und Sie sollten echtes Houzz-Kategorie-Markup sehen, nicht die Hülle, die eine einfache Anfrage zurückgibt. Das bestätigt, dass das Rendering funktioniert, bevor Sie einen einzigen Selektor schreiben.
Houzz braucht eine gerenderte Seite hinter einer vertrauenswürdigen IP, in einem Aufruf, was genau das ist, was die Optionen ajax_wait und page_wait oben einrichten. Die Crawling API nimmt ein JS-Token, lässt die Seite in einem echten Browser laufen, rotiert serverseitig durch Residential-IPs und reicht Ihnen fertiges HTML, sodass Sie sich das Betreiben einer Headless-Flotte und eines Proxy-Pools selbst sparen. Richten Sie sie zuerst im kostenlosen Tarif auf eine öffentliche Kategorie-Seite.
Schritt 2: Produktlinks von der Kategorie-Seite sammeln
Eine Houzz-Kategorie-Seite ist ein Raster aus Produktkarten, von denen jede auf eine vollständige Produktseite verlinkt. Laden Sie das gerenderte HTML in BeautifulSoup und ziehen Sie den href aus dem Titel-Link jeder Karte. Houzz verschachtelt diese in seinem Produktlisten-Container, sodass der Selektor von der Liste hinab zur Karte und ihrem Titel-Anchor wandert.
from bs4 import BeautifulSoup CARD_SELECTOR = ( 'div[data-container="Product List"] > div.hz-product-card ' 'a.hz-product-card__product-title' ) def get_product_urls(html): soup = BeautifulSoup(html, "html.parser") return [a["href"] for a in soup.select(CARD_SELECTOR) if a.get("href")]
Jede Produktkarte trägt die Klasse hz-product-card, und der Titel-Link darin trägt hz-product-card__product-title mit der Produktseiten-URL in seinem href. Lässt man dies gegen das gerenderte Kategorie-HTML laufen, ergibt sich eine saubere Liste von Produktseiten-URLs:
[ "https://www.houzz.com/products/the-sequoia-bathroom-vanity-acacia-30-single-sink-freestanding-prvw-vr~170329010", "https://www.houzz.com/products/bosque-bath-vanity-driftwood-42-single-sink-undermount-freestanding-prvw-vr~107752516", "https://www.houzz.com/products/render-bathroom-vanity-oak-white-prvw-vr~176775440", "https://www.houzz.com/products/the-wailea-bathroom-vanity-single-sink-42-weathered-fir-freestanding-prvw-vr~188522678" ]
Houzz' Klassennamen und Container-Attribute ändern sich ohne Vorankündigung. Behandeln Sie die Selektoren hier als Ausgangsvorlage, nicht als Vertrag. Kommt eine Liste leer zurück, inspizieren Sie die Live-Seite erneut in den Dev Tools Ihres Browsers und aktualisieren Sie den Selektor. Regelmäßige Selektor-Wartung ist für jeden produktiven Scraper normal und kein Zeichen, dass etwas kaputt ist.
Schritt 3: Die Paginierung über Kategorie-Seiten hinweg verarbeiten
Eine Kategorie-Seite ist ein Ausschnitt des Katalogs. Houzz stellt in seinem Paginierungs-Steuerelement einen "Nächste Seite"-Link bereit, Sie holen also eine Seite, sammeln deren Links und folgen dann dem Nächste-Seite-Link, bis es keinen mehr gibt. Ein kleiner Retry-Wrapper um den Abruf verhindert, dass eine einzelne langsame Seite den Lauf beendet.
import time BASE = "https://www.houzz.com" def fetch_html(page_url, max_retries=2): for attempt in range(max_retries + 1): html = crawl(page_url) if html: return html if attempt < max_retries: print(f"Retrying ({attempt + 1}/{max_retries})...") time.sleep(1) print(f"Unable to fetch {page_url}") return None def get_next_page_url(soup): nxt = soup.select_one("a.hz-pagination-link--next") return BASE + nxt["href"] if nxt and nxt.get("href") else None def collect_all_urls(start_url, max_pages): all_urls = [] url = start_url page = 0 while url and page < max_pages: html = fetch_html(url) if not html: break all_urls.extend(get_product_urls(html)) soup = BeautifulSoup(html, "html.parser") url = get_next_page_url(soup) page += 1 time.sleep(2) return all_urls
fetch_html wiederholt einen fehlgeschlagenen Abruf bis zu zweimal mit einer kurzen Pause und gibt bei Erfolg das HTML zurück und None, sobald es aufgibt. get_next_page_url liest den hz-pagination-link--next-Anchor und fügt seinen relativen href an den Houzz-Host an. collect_all_urls folgt diesem Nächste-Seite-Link von einer Seite zur nächsten, deckelt den Crawl bei Ihrer max_pages-Obergrenze, damit eine große Kategorie nicht außer Kontrolle gerät, und sammelt Links von jeder Seite. Das time.sleep(2) zwischen den Seiten taktet den Lauf, sodass Sie die Website nicht überrennen.
Schritt 4: Jede Produktseite parsen
Mit einer vollständigen Liste von Produkt-URLs holen Sie jede Seite und extrahieren die Felder. Houzz gruppiert die Eckdaten rund um seinen Preisblock, sodass die Selektoren unten Name, Preis, Bewertung, Rezensionsanzahl, Verkäufer und Kategorie auf einzelne Elemente abbilden. Jede Abfrage ist abgesichert, sodass ein fehlendes Feld None zurückgibt, statt den Lauf zum Absturz zu bringen.
def text_of(soup, selector): el = soup.select_one(selector) return el.get_text(strip=True) if el else None def get_rating(soup): star = soup.select_one("span.star-rating") if star and star.get("aria-label"): return star["aria-label"].replace("Average rating: ", "") return None def scrape_product(html, url): soup = BeautifulSoup(html, "html.parser") return { "link": url, "name": text_of(soup, "span.view-product-title"), "price": text_of(soup, "span.pricing-info__price"), "rating": get_rating(soup), "reviews": text_of(soup, "span.review-count"), "seller": text_of(soup, "a.seller-name"), "category": text_of(soup, "nav.breadcrumb li:last-child"), }
Der text_of-Helfer fragt ein Element ab und gibt seinen getrimmten Text zurück oder None, wenn das Element fehlt, sodass ein Produkt, das ein Feld auslässt, die Schleife nicht unterbricht. Die Selektoren kommen direkt aus dem Produktlayout von Houzz: name liest den view-product-title-Span, price liest den pricing-info__price-Span, und die Bewertung liegt in einem star-rating-Span, dessen aria-label wie "4.9 out of 5 stars" lautet, was get_rating bereinigt. Rezensionsanzahl, Verkäufer und Kategorie sitzen in den umliegenden Metadaten; inspizieren Sie die Live-Seite erneut, falls eines davon als None zurückkommt, da Houzz diese Wrapper regelmäßig überarbeitet.
Schritt 5: Das vollständige Skript zusammensetzen
Verdrahten Sie nun die Teile zu einem lauffähigen Skript: URLs über mehrere Seiten sammeln, jedes Produkt scrapen und die Datensätze sowohl nach JSON als auch nach CSV exportieren.
import csv import json import time from crawlbase import CrawlingAPI from bs4 import BeautifulSoup api = CrawlingAPI({"token": "YOUR_CRAWLBASE_TOKEN"}) BASE = "https://www.houzz.com" OPTIONS = { "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/122.0", "ajax_wait": "true", "page_wait": 5000, } CARD_SELECTOR = ( 'div[data-container="Product List"] > div.hz-product-card ' 'a.hz-product-card__product-title' ) def crawl(page_url): response = api.get(page_url, OPTIONS) if response["headers"]["cb_status"] == "200": return response["body"].decode("utf-8") print(f"Request failed: {response['headers']['cb_status']}") return None def fetch_html(page_url, max_retries=2): for attempt in range(max_retries + 1): html = crawl(page_url) if html: return html if attempt < max_retries: time.sleep(1) return None def text_of(soup, selector): el = soup.select_one(selector) return el.get_text(strip=True) if el else None def get_rating(soup): star = soup.select_one("span.star-rating") if star and star.get("aria-label"): return star["aria-label"].replace("Average rating: ", "") return None def get_product_urls(html): soup = BeautifulSoup(html, "html.parser") return [a["href"] for a in soup.select(CARD_SELECTOR) if a.get("href")] def get_next_page_url(soup): nxt = soup.select_one("a.hz-pagination-link--next") return BASE + nxt["href"] if nxt and nxt.get("href") else None def collect_all_urls(start_url, max_pages): all_urls = [] url = start_url page = 0 while url and page < max_pages: html = fetch_html(url) if not html: break all_urls.extend(get_product_urls(html)) soup = BeautifulSoup(html, "html.parser") url = get_next_page_url(soup) page += 1 time.sleep(2) return all_urls def scrape_product(html, url): soup = BeautifulSoup(html, "html.parser") return { "link": url, "name": text_of(soup, "span.view-product-title"), "price": text_of(soup, "span.pricing-info__price"), "rating": get_rating(soup), "reviews": text_of(soup, "span.review-count"), "seller": text_of(soup, "a.seller-name"), "category": text_of(soup, "nav.breadcrumb li:last-child"), } def save_outputs(records): with open("houzz_products.json", "w") as f: json.dump(records, f, indent=2) if not records: return with open("houzz_products.csv", "w", newline="") as f: writer = csv.DictWriter(f, fieldnames=records[0].keys()) writer.writeheader() writer.writerows(records) def main(): listing_url = "https://www.houzz.com/products/bathroom-vanities-and-sink-consoles/best-sellers--best-sellers" urls = collect_all_urls(listing_url, max_pages=2) records = [] for url in urls: html = fetch_html(url) if html: records.append(scrape_product(html, url)) time.sleep(2) save_outputs(records) print(f"Saved {len(records)} products") if __name__ == "__main__": main()
Das Skript sammelt Produktlinks über bis zu zwei Kategorie-Seiten, holt jede Produktseite mit dem Retry-Wrapper, parst sie zu einem Datensatz und taktet die Schleife mit einer zweisekündigen Pause. save_outputs schreibt sowohl eine JSON- als auch eine CSV-Datei und verwendet die Schlüssel des ersten Datensatzes als Kopfzeile, sodass Sie die Daten in der Form haben, die Ihr nachgelagertes Werkzeug jeweils erwartet. Passen Sie max_pages und die Kategorie-URL an Ihr Ziel an.
Wie die Ausgabe aussieht
Führen Sie das vollständige Skript mit python houzz_scraper.py aus, und Sie erhalten einen sauberen strukturierten Datensatz pro Produkt, bereit für Analyse, eine Datenbank oder eine Tabelle.
[ { "link": "https://www.houzz.com/products/the-sequoia-bathroom-vanity-acacia-30-single-sink-freestanding-prvw-vr~170329010", "name": "The Sequoia Bathroom Vanity, Acacia, 30\", Single Sink, Freestanding", "price": "$948", "rating": "4.9 out of 5 stars", "reviews": "128 Reviews", "seller": "Cambridge Plumbing", "category": "Bathroom Vanities" }, { "link": "https://www.houzz.com/products/render-bathroom-vanity-oak-white-prvw-vr~176775440", "name": "Render Bathroom Vanity, Oak White", "price": "$295", "rating": "4.5 out of 5 stars", "reviews": "43 Reviews", "seller": "Modway", "category": "Bathroom Vanities" } ]
Die passende CSV trägt dieselben Spalten, eine Zeile pro Produkt, was direkt in pandas oder jede Tabelle fällt, um nach Preisspanne, Bewertung oder Verkäufer zu filtern. Wenn Ihr Ziel ein Arbeitsblatt statt eines Skripts ist, speisen dieselben Datensätze eine E-Commerce-Scraping-Pipeline ohne weiteres Umformen.
Bei großem Volumen unblockiert bleiben
Selbst wenn das Rendering erledigt ist, achtet Houzz auf scraper-förmigen Traffic. Ein paar Gewohnheiten halten einen längeren Lauf gesund, und sie gelten für jedes harte kommerzielle Ziel.
- Takten Sie Ihre Anfragen. Produktseiten in einer engen Schleife zu hämmern ist der schnellste Weg, gedrosselt oder herausgefordert zu werden. Die zweisekündigen Pausen oben sind die Untergrenze, nicht die Obergrenze; weiten Sie sie für größere Jobs aus und variieren Sie Ihre Ziele, statt eine Kategorie mit voller Geschwindigkeit zu crawlen.
- Setzen Sie auf Rotation. Ein Pool aus Residential-IPs verteilt Anfragen über viele echte Nutzeradressen, sodass keine einzelne ein Rate-Limit auslöst. Die Crawling API erledigt das für Sie; wenn Sie Ihren eigenen Stack bauen, ist das der Teil, den Sie richtig hinbekommen müssen.
-
Lesen Sie die Statuscodes. Ein Lauf, der beginnt, Nicht-200-
cb_status-Werte zurückzugeben, sagt Ihnen, dass die aktuelle Rate oder IP-Stufe nicht mehr ausreicht. Behandeln Sie das als Signal, einen Gang zurückzuschalten, nicht als Rauschen zum Ignorieren.
Für größere Crawls reiht der asynchrone Crawler Anfragen in eine Warteschlange und liefert Ergebnisse an einen Webhook, was sich eignet, um viele Kategorie-Seiten zu verarbeiten, ohne Verbindungen offenzuhalten. Für das umfassendere Vorgehen siehe wie man Websites scrapt, ohne blockiert zu werden.
Ist es legal, Houzz zu scrapen?
Ob das Scrapen von Houzz erlaubt ist, hängt von den Nutzungsbedingungen von Houzz, Ihrer Rechtsordnung und davon ab, was Sie mit den Daten tun. Die Nutzungsbedingungen von Houzz beschränken automatisierten Zugriff und Massendatenerfassung, sodass Scraping unabhängig davon, wie sorgfältig Ihr Werkzeug ist, gegen diese Bedingungen verstoßen kann. Nichts an dem Code hier ändert das; er bringt nur den technischen Teil zum Laufen. Lesen Sie die Nutzungsbedingungen von Houzz und seine robots.txt, respektieren Sie alle festgelegten Rate-Erwartungen und verbotenen Pfade und behandeln Sie beides als Grenze für das, was Sie erfassen. Halten Sie Ihr Anfragevolumen niedrig genug, dass Sie die Server nicht belasten.
Ein paar Leitlinien, an die man sich halten sollte. Erfassen Sie nur öffentliche Produkt- und Listing-Daten: den Produktnamen, Preis, die Bewertung, Rezensionsanzahl, den Verkäufer oder die Marke und die Kategorie, die jeder ohne Konto sehen kann. Houzz hostet außerdem eine große Menge nutzergenerierter Inhalte, darunter Projektfotos, Designideen und Rezensionen, die an namentlich genannte Personen geknüpft sind; behandeln Sie alles, was an eine reale Person geknüpft ist, als personenbezogene Daten, die außerhalb dieses Rahmens liegen, und beachten Sie, dass DSGVO und CCPA gelten, sobald personenbezogene Daten ins Spiel kommen. Produktfotografie und Designbilder auf Houzz sind durch die Verkäufer, Designer und Houzz selbst urheberrechtlich geschützt, sodass das Erfassen einer Bild-URL Ihnen nicht das Recht gibt, das Bild weiterzuverbreiten, wiederzuverwenden oder erneut zu veröffentlichen. Bleiben Sie bei den sachlichen Produktfeldern, nicht den Medien.
Diese Anleitung ist bewusst auf öffentliche Produktseiten beschränkt, denn das ist die Linie, die die Arbeit vertretbar hält. Sie deckt nichts ab, was hinter einem Login liegt, keine Konto- oder gespeicherten Ideen-Daten, keine persönlichen Angaben von Hausbesitzern oder Fachleuten und keine urheberrechtlich geschützten Fotos, die Sie weiterverbreiten würden. Wenn Ihr Projekt mehr als öffentliche Produktfelder braucht, ist der richtige Weg eine Lizenzvereinbarung: Houzz betreibt eine öffentliche API und Partnerprogramme für erlaubte Anwendungsfälle wie sein Trade Program und Verkäufer-Integrationen, und das ist der korrekte Weg für kommerzielle oder Massennutzung, nicht ein raffinierterer Scraper.
Wichtigste Erkenntnisse
- Houzz wird clientseitig gerendert. Eine einfache Anfrage gibt eine dünne Hülle mit wenig vom Produktraster zurück, Sie müssen die Seite also rendern, bevor Sie sie parsen.
-
Sie brauchen Rendering und eine vertrauenswürdige IP zusammen. Die Crawling API mit einem JS-Token erledigt beides in einem Aufruf;
ajax_waitundpage_waitsteuern, wie lange sie auf Inhalte wartet. -
Arbeiten Sie in zwei Ebenen. Sammeln Sie Produktlinks von jeder Kategorie-Seite mit dem
hz-product-card__product-title-Selektor und holen und parsen Sie dann jedes Produkt nach Name, Preis, Bewertung, Rezensionen, Verkäufer und Kategorie. -
Paginieren und exportieren. Folgen Sie dem
hz-pagination-link--next-Link von Houzz bis zu einer Obergrenze, takten Sie den Lauf mit kurzen Pausen und schreiben Sie die Datensätze nach JSON und CSV. - Bleiben Sie bei öffentlichen Daten. Respektieren Sie die ToS und robots.txt von Houzz, halten Sie sich an sachliche Produktfelder, fassen Sie niemals Logins, personenbezogene Daten oder urheberrechtlich geschützte Bilder an, die Sie weiterverbreiten würden, und nutzen Sie die offizielle API für Massen- oder kommerzielle Nutzung.
Häufig gestellte Fragen
Warum gibt eine einfache Anfrage fast keine Houzz-Produkte zurück?
Weil Houzz sein Produktraster und seine Produktdetails clientseitig mit JavaScript lädt. Das anfängliche HTML ist eine Hülle, die sich erst füllt, nachdem die Skripte der Seite in einem Browser laufen, sodass eine rohe HTTP-Anfrage Status 200 mit den meisten fehlenden Karten und Produktfeldern zurückgibt. Um den vollständigen Satz zu erhalten, müssen Sie die Seite zuerst rendern, was das JS-Token der Crawling API für Sie erledigt.
Brauche ich für Houzz das normale Token oder das JS-Token?
Das JS-Token. Das normale Token ruft statisches HTML ab, das bei Houzz dieselbe dünne Hülle ist, die ein einfacher Abruf zurückgibt. Das JS-Token rendert die Seite in einem echten Browser, bevor es das HTML zurückreicht, sodass die Produktkarten und Produktfelder vorhanden sind, wenn BeautifulSoup sie parst.
Welche Daten kann ich von einer Houzz-Produktseite scrapen?
Öffentliche Produktfelder: den Produktnamen, den Preis, die durchschnittliche Bewertung und Rezensionsanzahl, den Verkäufer oder die Marke, die Kategorie und den Produktlink. Bleiben Sie bei Daten, die für jeden Besucher ohne Konto sichtbar sind, und vermeiden Sie Projektfotos, Rezensionen oder jegliche Inhalte, die an identifizierbare Personen geknüpft sind, was außerhalb des Rahmens öffentlicher Produkte liegt, den diese Anleitung abdeckt.
Meine Selektoren geben None zurück. Was hat sich geändert?
Mit ziemlicher Sicherheit das Markup von Houzz. Klassennamen wie hz-product-card, pricing-info__price und star-rating sowie Container-Attribute ändern sich ohne Vorankündigung, sodass Selektoren, die letzten Monat funktioniert haben, brechen können. Inspizieren Sie eine Live-Seite erneut in den Dev Tools Ihres Browsers und aktualisieren Sie die Selektoren. Regelmäßige Selektor-Wartung ist für jeden produktiven Scraper normal.
Wie scrape ich mehr als eine Seite einer Houzz-Kategorie?
Houzz stellt einen Nächste-Seite-Anchor mit der Klasse hz-pagination-link--next bereit. Lesen Sie seinen href, fügen Sie ihn an den Houzz-Host an und folgen Sie ihm von einer Seite zur nächsten, bis der Link fehlt oder Sie Ihre max_pages-Obergrenze erreichen. Die Funktion collect_all_urls oben zeigt die vollständige Schleife, mit einer kurzen Pause zwischen den Seiten.
Darf ich gescrapte Houzz-Daten kommerziell nutzen?
Behandeln Sie das als rechtliche Frage, nicht als technische. Die Nutzungsbedingungen von Houzz beschränken die Wiederverwendung, ein Großteil der Produktbilder ist durch Verkäufer und Designer urheberrechtlich geschützt, und sämtliche Nutzerinhalte sind personenbezogene Daten, sodass kommerzielle oder Massennutzung in der Regel eine Genehmigung braucht. Prüfen Sie die Bedingungen, ziehen Sie die offizielle API und die Partnerprogramme von Houzz in Betracht und holen Sie Rechtsrat ein, bevor Sie ein Produkt auf den Daten aufbauen.
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.
