ImmobilienScout24 Mining 2.0: Der Web Scraper für Häuserdaten!

Nachdem du diesen Beitrag gelesen hast, kannst du in wenigen Stunden mit einem selbst gebauten Web Scraper Daten von über 60.000 momentan zum Verkauf stehenden Häusern von Immobilienscout24.de herunter laden. Finde raus, wie es geht!

Worum es geht

In dieser Beitragsreihe habe ich dir ja schon gezeigt, wie du mit Python Daten von Wohnungen herunterladen kannst, welche neu auf Immobilienscout24 angeboten werden. Nachdem wir die Daten geschürft, analysiert, visualisiert und mit ihnen Machine-Learning-Modelle gebaut haben, ist es nun an der Zeit, sich einer anderen Art von Immobilie zu widmen.

Der Web Scraper

Eine Detailerklärung zum alten Scraper findest du hier. Beim jetzigen Skript werde ich eher darauf eingehen, was es von dem alten Skript unterscheidet. Unten siehst du den kompletten Code für den neuen Web Scraper. Klicke im Code-Fenster oben rechts einfach auf das “+”, damit der Code sich in einem neuen Fenster öffnet. So kannst du das Skript besser lesen. Voraussetzung für die fehlerfreie Ausführung des Codes sind die Module, welche gleich zu Beginn des Skripts importiert werden. In der Python-Distribution Anaconda (beliebt bei Data Scientists) sind je nach Version die meisten der benötigten Packages schon enthalten.

import bs4 as bs
import urllib.request
import time
from datetime import datetime
import pandas as pd
import json

for seite in range(1,3000):
    
    print("Loop " + str(seite) + " startet.")

    df = pd.DataFrame()
    l=[]

    try:
        
        soup = bs.BeautifulSoup(urllib.request.urlopen("https://www.immobilienscout24.de/Suche/S-2/P-"+str(seite)+"/Haus-Kauf").read(),'lxml')
        print("Aktuelle Seite: "+"https://www.immobilienscout24.de/Suche/S-2/P-"+str(seite)+"/Haus-Kauf")
        for paragraph in soup.find_all("a"):

            if r"/expose/" in str(paragraph.get("href")):
                l.append(paragraph.get("href").split("#")[0])

            l = list(set(l))

        for item in l:

            try:

                soup = bs.BeautifulSoup(urllib.request.urlopen('https://www.immobilienscout24.de'+item).read(),'lxml')

                data = pd.DataFrame(json.loads(str(soup.find_all("script")).split("keyValues = ")[1].split("}")[0]+str("}")),index=[str(datetime.now())])

                data["URL"] = str(item)

                beschreibung = []

                for i in soup.find_all("pre"):
                    beschreibung.append(i.text)

                data["beschreibung"] = str(beschreibung)

                df = df.append(data)

            except Exception as e: 
                print(str(datetime.now())+": " + str(e))
                l = list(filter(lambda x: x != item, l))
                print("ID " + str(item) + " entfernt.")
        print("Exportiert CSV")
        df.to_csv(".../rohdaten/"+str(datetime.now())[:19].replace(":","").replace(".","")+".csv",sep=";",decimal=",",encoding = "utf-8",index_label="timestamp")     

        print("Loop " + str(seite) + " endet.\n")
        
    except Exception as e: 
        print(str(datetime.now())+": " + str(e))

print("FERTIG!")

Der Web Scraper, welchen du oben siehst, ist dem alten Skript sehr ähnlich, jedoch nicht identisch. Der erste Unterschied besteht darin, dass das Programm keine Daten von Wohnungen, sondern von Häusern herunter lädt. Dazu müssen wir einfach die URL ändern, auf die zugegriffen wird.

URL für Mietwohnungen:

https://www.immobilienscout24.de/Suche/S-2/Wohnung-Miete

URL für den Hauskauf:

https://www.immobilienscout24.de/Suche/S-T/Haus-Kauf

Außerdem greift das Skript nicht immer wieder auf dieselbe Seite zu und schaut dort nach neuen Angeboten. Viel mehr startet es auf der ersten Seite mit den neusten Angeboten und gräbt sich von da aus Seite für Seite bis zu den ältesten Angeboten durch. Dadurch muss das Programm nicht mehrere Tage oder Wochen laufen, um einen signifikanten Datensatz zu sammeln. Auf meinem Rechner hat es genau 10 Stunden und 26 Minuten gedauert, bis der Web Scraper 3.000 Seiten durchsucht und damit Daten von 61.225 Häusern herunter geladen hat. Beim Festlegen der maximalen Seitenzahl solltest du vorher untersuchen, wie viele Ergebnisseiten es auf ImmobilienScout24 zu dem Zeitpunkt gibt, zu dem du den Web Scraper laufen lässt. Bei mir waren es etwas über 3.000. Die maximale Seitenzahl kannst du dann im Code in der allerersten Klammer angeben, dann durchsucht das Programm alle existierenden Ergebnisseiten. Solltest du eine zu hohe Zahl eingeben, wird das Skript dir zwar irgendwann einen Fehler ausgeben, bis dahin werden aber schon alle Daten, die du haben willst, auf deiner Festplatte gespeichert sein.

Rohdaten zusammenführen

Der Web Scraper legt alle Daten als CSV-Dateien auf deiner Festplatte ab – eine Datei pro Seite. Um die Daten letztendlich analysieren zu können, musst du sie natürlich irgendwie miteinander verknüpfen. Und das geht so.

import os
import pandas as pd

df = pd.DataFrame()
n=0
for i in os.listdir(".../rohdaten"):
    n+=1
    df = df.append(pd.read_csv(".../rohdaten/"+str(i),sep=";",decimal=",",encoding="utf-8"))
    print("Durchgang "+str(n))

Der Code generiert einen DataFrame, iteriert über jede Datei in deinem Zielverzeichnis, lädt sie in deine Programmierumgebung und hängt sie an den DataFrame an. In diesem befinden sich nun gesammelt alle von dir herunter geladenen Häuserdaten. Lass uns jetzt den DataFrame noch auf Duplikate untersuchen.

df.shape

df = df.drop_duplicates(subset="URL")
df.shape

Ein paar der Daten waren Duplikate, diese haben wir mit den obigen Befehl entfernt.

Fazit

Mit ein paar kleinen Änderungen am ursprünglichen Skript haben wir es geschafft, auf komplette neue Daten zuzugreifen und noch schneller noch mehr Daten herunter zu laden. Wie die Daten aussehen, was es für Korrationen gibt und ob man mit einem statistischen Modell den Kaufpreis prognostizieren kann, erfährst du in den kommenden Beiträgen. Viel Spaß beim Scrapen!

 

4 Gedanken zu „ImmobilienScout24 Mining 2.0: Der Web Scraper für Häuserdaten!

  • 19. Juni 2018 um 14:31
    Permalink

    Hall Chris,
    besten Dank für die perfekte Anleitung zur Datengewinnung auf immoscout. Für mich als Einsteiger in Python und R ist dies einfach nur TOP. Vielen Dank! Ich beschäftige mich auch mit verschiedenen Immobilienbewertungsverfahren. Mich würde interessieren, ob es möglich ist die Angebotsverweildauer des jeweiligen Angebots zu messen und eventuelle Preisveränderungen zu messen. Für ertragsorientierte Bewertungsmethoden wäre das absolut klasse. Ich habe gerade ein Studium der Immobilienbewirtschaftung begonnen und die Frage der Angebotsverweildauer und der Preisentwicklung von Angebotspreisen wird gerade heiß diskutiert. Hieraus könnten bei ertragsorientierten Bewertungsmethoden (Discounted Cashflow Methode) bessere Aussagen zur Mietausfallwagnis getroffen werden. Ich denke auch, dass dies bei deinem hedonischen Modell integrierbar ist. Da bin ich aber noch am grübeln. Zumindest konnte ich im Zuge meines Studiums dies mit einigen Statistikern für große Immobilienunternehmen besprechen und die waren begeistert von der Idee. Gibt es hierfür Möglichkeiten oder würde das den Rahmen sprengen?
    Beste Grüße
    Thomas

    Antwort
    • 19. Juni 2018 um 20:27
      Permalink

      Hi Thomas,

      herzlichen Dank für dein Feedback! Es freut mich, dass dir der Beitrag weiter hilft. 🙂

      Zu deiner Frage: Du kannst den Scraper natürlich wochenlang jeden Tag laufen lassen. Wenn du fertig bist mit dem Datensammeln, dann siehst du an den Zeitstempeln, wann eine URL zum ersten Mal und zum letzten Mal vom Scraper gefunden wurde. Der Nachteil daran ist, dass du nur für Häuser, die während dieser Zeit neu erschienen und dann wieder offline gegangen sind, die genaue Angebotsverweilsdauer berechnen kannst. Für alle anderen Häuser hast du dann nur eine “Mindestverweildauer”. Es kann also sein, dass du das Programm über einen langen Zeitraum laufen lassen musst, um eine repräsentative und genaue Stichprobe zu bekommen. Außerdem wirst du sehr sehr viele Duplikate haben. Das sollte der Sache aber keinen Abbruch tun.

      In den nächsten Beiträgen werde ich mit verschiedenen Machine Learning Algorithmen versuchen, anhand der Eigenschaften der Häuser ihren jeweiligen Kaufpreis zu schätzen. Weil du an Immobilienbewertungsverfahren interessiert bist, könnte das auch für dich interessant sein. Du sagst, dass du noch Python-Einsteiger bist. Willst du die Daten auch mit Python untersuchen?

      Viele Grüße

      Chris

      Antwort
  • 25. Oktober 2018 um 17:59
    Permalink

    Vielen Dank für den tollen Beitrag Chris. Die Daten, die man von Immobilienseiten gewinnt, ermöglichen eine Menge von spannende Analyse bzw Visualisierung.

    Hast du Erfahrung damit, ob immobilienscout24 die request blockiert wenn man in einer kurzen Zeit zu oft die requests hinschickt? 3000 Seiten hast du für 10 Std gebraucht, was gleich eine Geschwindigkeit von 5 Seiten pro Minute, was die Seite akzeptiert.

    Antwort
    • 2. November 2018 um 14:07
      Permalink

      Hi Vinh,

      Bis jetzt wurde ich noch nie blockiert, allerings habe ich auch noch nie mehr Requests geschickt als von dir beschrieben. Würde mich aber auch interessieren, was bei zu vielen Anfragen pro Minute passiert. Wenn du es ausprobierst, lass es mich gerne wissen!

      Viele Grüße

      Chris

      Antwort

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

*

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.