Zurück zum Blog
Leitfäden
Raluca Penciuc3. März 202310 Min. Lesezeit

Wie man Idealista im Internet scrapt: Ein umfassender Leitfaden (2023 Update)

Wie man Idealista im Internet scrapt: Ein umfassender Leitfaden (2023 Update)

Voraussetzungen

Bevor wir beginnen, sollten wir uns vergewissern, dass wir die notwendigen Werkzeuge haben.

Laden Sie zunächst Node.js von der offiziellen Website herunter und installieren Sie es. Stellen Sie sicher, dass Sie die Long-Term Support (LTS) Version verwenden. Dadurch wird auch automatisch der Node Package Manager (NPM) installiert, den wir für die Installation weiterer Abhängigkeiten verwenden werden.

Für dieses Tutorial werden wir Visual Studio Code als integrierte Entwicklungsumgebung (IDE) verwenden, aber Sie können auch eine andere IDE Ihrer Wahl verwenden. Erstellen Sie einen neuen Ordner für Ihr Projekt, öffnen Sie das Terminal und führen Sie den folgenden Befehl aus, um ein neues Node.js-Projekt einzurichten:

npm init -y

Dadurch wird eine package.json-Datei in Ihrem Projektverzeichnis erstellt, in der Informationen über Ihr Projekt und seine Abhängigkeiten gespeichert werden.

Als nächstes müssen wir TypeScript und die Typdefinitionen für Node.js installieren. TypeScript bietet eine optionale statische Typisierung, die hilft, Fehler im Code zu vermeiden. Führen Sie dazu im Terminal aus:

npm install typescript @types/node --save-dev

Sie können die Installation überprüfen, indem Sie sie ausführen:

npx tsc --version

TypeScript verwendet eine Konfigurationsdatei namens tsconfig.json, um Compiler-Optionen und andere Einstellungen zu speichern. Um diese Datei in Ihrem Projekt zu erstellen, führen Sie den folgenden Befehl aus:

npx tsc -init

Stellen Sie sicher, dass der Wert für "outDir" auf "dist" gesetzt ist. Auf diese Weise werden die TypeScript-Dateien von den kompilierten Dateien getrennt. Weitere Informationen über diese Datei und ihre Eigenschaften finden Sie in der offiziellen TypeScript-Dokumentation.

Erstellen Sie nun ein Verzeichnis "src" in Ihrem Projekt und eine neue Datei "index.ts". Hier werden wir den Scraping-Code speichern. Um TypeScript-Code auszuführen, müssen Sie ihn zuerst kompilieren. Um sicherzustellen, dass wir diesen zusätzlichen Schritt nicht vergessen, können wir einen benutzerdefinierten Befehl verwenden.

Gehen Sie zur Datei "package.json" und bearbeiten Sie den Abschnitt "scripts" wie folgt:

"scripts": {

    "test": "npx tsc && node dist/index.js"

}

Wenn Sie das Skript ausführen wollen, müssen Sie nur "npm run test" in Ihr Terminal eingeben.

Um schließlich die Daten von der Website abzugreifen, werden wir Puppeteer verwenden, eine Headless-Browser-Bibliothek für Node.js, mit der Sie einen Webbrowser steuern und programmatisch mit Websites interagieren können. Um sie zu installieren, führen Sie diesen Befehl im Terminal aus:

npm Puppeteer installieren

Es ist sehr empfehlenswert, wenn Sie die Vollständigkeit Ihrer Daten sicherstellen wollen, da viele Websites heutzutage dynamisch generierte Inhalte enthalten. Wenn Sie neugierig geworden sind, können Sie sich die Puppeteer-Dokumentation ansehen, bevor Sie fortfahren, um zu sehen, wozu das Programm in der Lage ist.

Auffinden der Daten

Nachdem Sie nun Ihre Umgebung eingerichtet haben, können wir mit dem Extrahieren der Daten beginnen. Für diesen Artikel habe ich mich entschieden, die Liste der verfügbaren Häuser und Wohnungen in einer Region von Toledo, Spanien, zu durchsuchen: https://www.idealista.com/pt/alquiler-viviendas/toledo/buenavista-valparaiso-la-legua/.

Wir werden die folgenden Daten aus jedem Eintrag auf der Seite extrahieren:

  • die URL;
  • den Titel;
  • den Preis;
  • die Einzelheiten (Anzahl der Zimmer, Fläche usw.);
  • die Beschreibung

Alle diese Informationen sind in der nachstehenden Abbildung hervorgehoben:

Idealista-Immobilienanzeigenseite mit Browser-Entwicklertools, die HTML-Code für Titel-, Preis- und Beschreibungsfelder hervorheben

Wenn Sie die Entwicklertools für jedes dieser Elemente öffnen, können Sie die CSS-Selektoren sehen, die wir zum Auffinden der HTML-Elemente verwenden werden. Wenn Sie mit der Funktionsweise von CSS-Selektoren noch nicht vertraut sind, können Sie diesen Leitfaden für Einsteiger nutzen.

Datenextraktion

Um mit dem Schreiben unseres Skripts zu beginnen, überprüfen wir zunächst, ob die Installation von Puppeteer ordnungsgemäß verlaufen ist:

import puppeteer from 'puppeteer';

async function scrapeIdealistaData(idealista_url: string): Promise<void> {

    

    // Launch Puppeteer

    const browser = await puppeteer.launch({

        headless: false,

    	  args: ['--start-maximized'],

    	  defaultViewport: null

    })

    // Create a new page

    const page = await browser.newPage()

    // Navigate to the target URL

    await page.goto(idealista_url)

    // Close the browser

    await browser.close()

}

scrapeIdealistaData("https://www.idealista.com/pt/alquiler-viviendas/toledo/buenavista-valparaiso-la-legua/")

Hier öffnen wir ein Browserfenster, erstellen eine neue Seite, navigieren zu unserer Ziel-URL und schließen den Browser. Der Einfachheit halber und für das visuelle Debugging öffne ich das Browserfenster in maximierter Größe im Nicht-Headless-Modus.

Da alle Inserate die gleiche Struktur und die gleichen Daten haben, können wir alle Informationen für die gesamte Eigenschaftsliste in unserem Algorithmus extrahieren. Nach der Ausführung des Skripts können wir alle Ergebnisse in einer Schleife durchgehen und zu einer einzigen Liste zusammenstellen.

Um die URL aller Eigenschaften zu erhalten, suchen wir die Ankerelemente mit der Klasse "item-link". Dann wandeln wir das Ergebnis in ein JavaScript-Array um und ordnen jedes Element dem Wert des Attributs "href" zu.

// Extract listings location

const listings_location = await page.evaluate(() => {

    const locations = document.querySelectorAll('a.item-link')

    const locations_array = Array.from(locations)

    return locations ? locations_array.map(a => a.getAttribute('href')) : []

})

console.log(listings_location.length, listings_location)

Für die Überschriften können wir dasselbe Ankerelement verwenden, nur dass wir dieses Mal das Attribut "title" extrahieren.

// Extract listings titles

const listings_title = await page.evaluate(() => {

    const titles = document.querySelectorAll('a.item-link')

    const titles_array = Array.from(titles)

    return titles ? titles_array.map(t => t.getAttribute('title')) : []

})

console.log(listings_title.length, listings_title)

Für die Preise finden wir die "span"-Elemente mit 2 Klassennamen: "item-price" und "h2-simulated". Es ist wichtig, die Elemente so eindeutig wie möglich zu identifizieren, damit das Endergebnis nicht verfälscht wird. Auch sie müssen in ein Array umgewandelt und dann ihrem Textinhalt zugeordnet werden.

// Extract listings prices

const listings_price = await page.evaluate(() => {

    const prices = document.querySelectorAll('span.item-price.h2-simulated')

    const prices_array = Array.from(prices)

    return prices ? prices_array.map(p => p.textContent) : []

})

console.log(listings_price.length, listings_price)

Wir wenden das gleiche Prinzip für die Eigenschaftsdetails an, indem wir die "div"-Elemente mit dem Klassennamen "item-detail-char" analysieren.

// Extract listings details

const listings_detail = await page.evaluate(() => {

    const details = document.querySelectorAll('div.item-detail-char')

    const details_array = Array.from(details)

    return details ? details_array.map(d => d.textContent) : []

})

console.log(listings_detail.length, listings_detail)

Und schließlich die Beschreibung der Eigenschaften. Hier wenden wir einen zusätzlichen regulären Ausdruck an, um alle unnötigen Zeilenumbrüche zu entfernen.

// Extract listings descriptions

const listings_description = await page.evaluate(() => {

    const descriptions = document.querySelectorAll('div.item-description.description')

    const descriptions_array = Array.from(descriptions)

    return descriptions ? descriptions_array.map(d => d.textContent.replace(/(\r\n|\n|\r)/gm, "")) : []

})

console.log(listings_description.length, listings_description)

Jetzt sollten Sie 5 Listen haben, eine für jeden Teil der Daten, die wir gesammelt haben. Wie ich bereits erwähnt habe, sollten wir sie in einer einzigen Liste zusammenfassen. Auf diese Weise lassen sich die gesammelten Informationen viel leichter weiterverarbeiten.

// Group the lists

const listings = []

for (let i = 0; i < listings_location.length; i++) {

    listings.push({

        url: listings_location[i],

        title: listings_title[i],

        price: listings_price[i],

        details: listings_detail[i],

        description: listings_description[i]

    })

}

console.log(listings.length, listings)

Das Endergebnis sollte wie folgt aussehen:

[

  {

    url: '/pt/inmueble/99004556/',

    title: 'Apartamento em ronda de Buenavista, Buenavista-Valparaíso-La Legua, Toledo',

    price: '750€/mês',

    details: '\n3 quart.\n115 m² área bruta\n2º andar exterior com elevador\nOntem \n',

    description: 'Apartamento para alugar na Ronda Buenavista, em Toledo.Três quartos e duas casas de banho, sala, cozinha, terraço, garagem e arrecadação....'

  },

  {

    url: '/pt/inmueble/100106615/',

    title: 'Moradia em banda em Buenavista-Valparaíso-La Legua, Toledo',

    price: '1.000€/mês',

    details: '\n4 quart.\n195 m² área bruta\nOntem \n',

    description: 'Magnífica casa geminada para alugar com 3 andares, 4 quartos aconchegantes, 3 banheiros, sala ampla e luminosa, cozinha totalmente equipa...'

  },

  {

    url: '/pt/inmueble/100099977/',

    title: 'Moradia em banda em calle Francisco Ortiz, Buenavista-Valparaíso-La Legua, Toledo',

    price: '800€/mês',

    details: '\n3 quart.\n118 m² área bruta\n10 jan \n',

    description: 'O REMAX GRUPO FV aluga uma casa mobiliada na Calle Francisco Ortiz, em Toledo.Moradia geminada com 148 metros construídos, distribuídos...'

  },

  {

    url: '/pt/inmueble/100094142/',

    title: 'Apartamento em Buenavista-Valparaíso-La Legua, Toledo',

    price: '850€/mês',

    details: '\n4 quart.\n110 m² área bruta\n1º andar exterior com elevador\n10 jan \n',

    description: 'Apartamento muito espaçoso para alugar sem móveis, cozinha totalmente equipada.Composto por 4 quartos, 1 casa de banho, terraço.Calefaç...'

  }

]

Umgehung der Bot-Erkennung

Wenn Sie Ihr Skript im Laufe dieses Tutorials mindestens 2 Mal ausführen, haben Sie diese lästige Seite vielleicht schon bemerkt:

Die Anti-Bot-Verifizierungsseite von Idealista, auf der ein Puzzle-Bild mit Gänseblümchen und eine Schieberegler-Aufforderung zu sehen sind

Idealista verwendet DataDome als Anti-Bot-Schutz, der eine GeeTest CAPTCHA-Herausforderung enthält. Sie sollen das Puzzleteil bewegen, bis das Bild vollständig ist, und dann sollten Sie auf Ihre Zielseite zurückgeleitet werden.

Mit diesem Code können Sie Ihr Puppeteer-Skript einfach anhalten, bis Sie die Aufgabe gelöst haben:

await page.waitForFunction(() => {

    const pageContent = document.getElementById('main-content')

    return pageContent !== null

}, {timeout: 10000})

Damit wird unser Skript angewiesen, 10 Sekunden zu warten, bis ein bestimmter CSS-Selektor im DOM erscheint. Das sollte ausreichen, um das CAPTCHA zu lösen und dann die Navigation zu beenden.

Idealista hat den Zugriff gesperrt und mitgeteilt, dass eine verdächtige Nutzung festgestellt wurde und der Zugriff gesperrt wurde

...es sei denn, die Idealista-Seite blockiert Sie ohnehin.

An diesem Punkt wurde der Prozess immer komplexer und schwieriger, und Sie haben Ihr Projekt nicht einmal skaliert.

Wie ich bereits erwähnt habe, wird Idealista von DataDome geschützt. Sie sammeln mehrere Browserdaten, um einen eindeutigen Fingerabdruck zu erstellen und Sie damit zu verbinden. Wenn sie verdächtig sind, erhalten Sie die CAPTCHA-Herausforderung oben, die ziemlich schwierig automatisch zu lösen ist.

Unter den gesammelten Browserdaten finden wir:

  • Eigenschaften des Navigator-Objekts (deviceMemory, hardwareConcurrency, languages, platform, userAgent, webdriver, usw.)
  • Zeit- und Leistungskontrollen
  • WebGL
  • WebRTC IP-Schnüffeln
  • Aufzeichnung von Mausbewegungen
  • Unstimmigkeiten zwischen dem User-Agent und Ihrem Betriebssystem
  • und viele mehr.

Eine Möglichkeit, diese Herausforderungen zu überwinden und das Scrapen in großem Maßstab fortzusetzen, ist die Verwendung einer Scraping-API. Diese Art von Diensten bietet eine einfache und zuverlässige Möglichkeit, auf Daten von Websites wie Idealista.com zuzugreifen, ohne dass Sie einen eigenen Scraper entwickeln und pflegen müssen.

WebScrapingAPI ist ein Beispiel für ein solches Produkt. Sein Proxy-Rotationsmechanismus vermeidet CAPTCHAs gänzlich, und seine erweiterte Wissensbasis macht es möglich, die Browserdaten nach dem Zufallsprinzip so zu gestalten, dass sie wie ein echter Benutzer aussehen.

Die Einrichtung ist schnell und einfach. Alles, was Sie tun müssen, ist, ein Konto zu registrieren, damit Sie Ihren API-Schlüssel erhalten. Auf diesen können Sie über Ihr Dashboard zugreifen, und er wird zur Authentifizierung der von Ihnen gesendeten Anfragen verwendet.

Schnellstartanleitung für das Dashboard in drei Schritten: API-Zugangsschlüssel, API Playground und Integration in Ihre Anwendung

Da Sie Ihre Node.js-Umgebung bereits eingerichtet haben, können wir das entsprechende SDK verwenden. Führen Sie den folgenden Befehl aus, um es zu Ihren Projektabhängigkeiten hinzuzufügen:

npm install webscrapingapi

Jetzt müssen nur noch die bisherigen CSS-Selektoren an die API angepasst werden. Die leistungsstarke Funktion der Extraktionsregeln ermöglicht es, Daten ohne wesentliche Änderungen zu analysieren.

import webScrapingApiClient from 'webscrapingapi';

const client = new webScrapingApiClient("YOUR_API_KEY");

async function exampleUsage() {

    const api_params = {

        'render_js': 1,

    	  'proxy_type': 'residential',

    	  'timeout': 60000,

    	  'extract_rules': JSON.stringify({

            locations: {

                selector: 'a.item-link',

                output: '@href',

                all: '1'

        	},

        	titles: {

                selector: 'a.item-link',

                output: '@title',

                all: '1'

        	},

        	prices: {

                selector: 'span.item-price.h2-simulated',

                output: 'text',

                all: '1'

        	},

        	details: {

                selector: 'div.item-detail-char',

                output: 'text',

                all: '1'

        	},

        	descriptions: {

                selector: 'div.item-description.description',

                output: 'text',

                all: '1'

        	}

        })

    }

    const URL = "https://www.idealista.com/pt/alquiler-viviendas/toledo/buenavista-valparaiso-la-legua/"

    const response = await client.get(URL, api_params)

    if (response.success) {

        // Group the lists

    	  const listings = []

    	  for (let i = 0; i < response.response.data.locations.length; i++) {

            listings.push({

                url: response.response.data.locations[i],

                title: response.response.data.titles[i],

                price: response.response.data.prices[i],

                details: response.response.data.details[i],

                description: response.response.data.descriptions[i].replace(/(\r\n|\n|\r)/gm, "")

        	})

    	  }

    	  console.log(listings.length, listings)

    } else {

        console.log(response.error.response.data)

    }

}

exampleUsage();

Schlussfolgerung

In diesem Artikel haben wir Ihnen gezeigt, wie Sie Idealista, eine beliebte spanische Immobilien-Website, mit TypeScript und Puppeteer scrapen können. Wir haben den Prozess der Einrichtung der Voraussetzungen und des Scrappings der Daten durchlaufen und einige Möglichkeiten zur Verbesserung des Codes erörtert.

Web Scraping Idealista kann wertvolle Informationen für Unternehmen und Privatpersonen liefern. Mithilfe der in diesem Artikel beschriebenen Techniken können Sie Daten wie Immobilien-URLs, Preise und Beschreibungen aus der Website extrahieren.

Wenn Sie außerdem die Anti-Bot-Maßnahmen und die Komplexität des Scraping-Prozesses vermeiden wollen, kann die Verwendung eines professionellen Scrapers effizienter und zuverlässiger sein als die Erstellung eines eigenen Scrapers.

Wenn Sie die in diesem Leitfaden beschriebenen Schritte und Techniken befolgen, können Sie die Möglichkeiten von Web Scraping Idealista voll ausschöpfen und zur Unterstützung Ihrer Geschäftsanforderungen nutzen. Ganz gleich, ob es um Marktforschung, Lead-Generierung oder die Schaffung neuer Geschäftsmöglichkeiten geht, Web Scraping Idealista kann Ihnen helfen, der Konkurrenz einen Schritt voraus zu sein.

Über den Autor
Raluca Penciuc, Full-Stack-Entwicklerin bei WebScrapingAPI
Raluca PenciucFull-Stack-Entwickler

Raluca Penciuc ist Full-Stack-Entwicklerin bei WebScrapingAPI. Sie entwickelt Scraper, optimiert Umgehungsstrategien und findet zuverlässige Wege, um die Erkennung auf Zielwebsites zu verringern.

Los geht’s

Sind Sie bereit, Ihre Datenerfassung zu erweitern?

Schließen Sie sich den über 2.000 Unternehmen an, die WebScrapingAPI nutzen, um Webdaten im Unternehmensmaßstab ohne zusätzlichen Infrastrukturaufwand zu extrahieren.