[Python] Fluss vom Web-Scraping zur Datenanalyse

Hallo, das ist @ 0yan. Heute habe ich Web Scraping-Datenanalyse als praktische Praxis der Datenanalyse ausprobiert. Ich möchte eines Tages eine gebrauchte Eigentumswohnung kaufen, daher habe ich die Informationen zu gebrauchten Eigentumswohnungen auf der Route ausgewählt, an der ich interessiert bin.

Umgebung

Was ich getan habe

  1. Web Scraping
  2. CSV schreiben / lesen
  3. Datenvorverarbeitung
  4. Analyse

1. Web Scraping

Die verwendeten Pakete sind wie folgt.

Paket verwendet

import datetime
import re
import time
from urllib.parse import urljoin

from bs4 import BeautifulSoup
import pandas as pd
import requests

Kratzfluss

Die Seite, die ich gekratzt habe, ist

Es war eine Konfiguration. Schließlich,

[{'Name des Anwesens': spam, 'Verkaufspreis': spam, 'Lage': spam, 'Entlang der Linie / Station': spam,
  'Besetztes Gebiet': spam, 'Gebäudeplan': spam, 'Balkon': spam, 'Datum des Baus': spam},
 {'Name des Anwesens': spam, 'Verkaufspreis': spam, 'Lage': spam, 'Entlang der Linie / Station': spam,
  'Besetztes Gebiet': spam, 'Gebäudeplan': spam, 'Balkon': spam, 'Datum des Baus': spam},
・ ・ ・,
 {'Name des Anwesens': spam, 'Verkaufspreis': spam, 'Lage': spam, 'Entlang der Linie / Station': spam,
  'Besetztes Gebiet': spam, 'Gebäudeplan': spam, 'Balkon': spam, 'Datum des Baus': spam}]

Ich möchte eine Liste von Elementen mit Eigenschaftsinformationen vom Typ Wörterbuch erstellen und diese an pandas.DataFrame übergeben. Daher habe ich sie mit dem folgenden Verfahren abgekratzt (siehe Kommentare).

#Initialisierung von Variablen (Wörterbuchtyp) zum Speichern von Eigenschaftsinformationen und Variablen (Liste) zum Speichern dieser
property_dict = {}
properties_list = []


# 「property_Liste der Schlüssel, die zum Generieren von "dict" "key" erforderlich sind_"Liste" generieren
key_list = ['Name des Anwesens', 'Verkaufspreis', 'Lage', 'Entlang der Linie / Station', 'Besetztes Gebiet', 'Gebäudeplan', 'Balkon', 'Datum des Baus']
key_list *= 30  #30 Eigenschaften/Seite


#Schöne Suppeninstanziierung auf Seite 1
first_page_url = 'Bestimmte Immobilien-Website verwendet Wohnung Informationen Suchergebnis (1. Seite) URL'
res = requests.get(first_page_url) 
soup = BeautifulSoup(res.text, 'html.parser')


#Wiederholen Sie dies für 93 Seiten (Da dies nur einmal der Fall ist, entfällt die Erfassung der maximalen Seitenanzahl.)
for page in range(93):
    #Liste der dd-Tags mit den Eigenschaftsdaten "dd"_"Liste" generieren
    dd_list = [re.sub('[\n\r\t\xa0]', '', x.get_text()) for x in soup.select('dd')]  #Schließen Sie unnötige Zeilenumbrüche usw. aus.
    dd_list = dd_list[8:]  #Schließen Sie unnötige Seiten-TOP-Daten aus

    #Eigenschaftsdaten vom Wörterbuchtyp sind eine Liste von Elementen "Eigenschaften"_"Liste" generieren
    zipped = zip(key_list, dd_list)
    for i, z in enumerate(zipped, start=1):
        if i % 8 == 0:
            properties_list.append(property_dict)
            property_dict = {}
        else:
            property_dict.update({z[0]: z[1]})
        
    #Holen Sie sich die URL der nächsten Seite (nach dem Basisteil)
    next_page = soup.select('p.pagination-parts>a')[-1]
    
    #Erstellen Sie auf der nächsten Seite eine Beautiful Soup-Instanz
    base_url = 'https://xxx.co.jp/'  #URL einer bestimmten Immobilienseite
    dynamic_url = urljoin(base_url, next_page.get("href"))
    time.sleep(3)
    res = requests.get(dynamic_url)
    soup = BeautifulSoup(res.text, 'html.parser')

Schließlich habe ich die Eigenschaftsliste "properties_list" an "pandas.DataFrame" übergeben und einen DataFrame generiert.

df = pd.DataFrame(properties_list)

2. CSV schreiben / lesen

Es ist mühsam, jedes Mal zu kratzen, und es belastet die Site-Seite. Deshalb habe ich beschlossen, es einmal in CSV zu schreiben und es dann zu lesen und zu verwenden.

csv_file = f'{datetime.date.today()}_Informationen zum Kauf gebrauchter Wohnungen.csv'
df.to_csv(csv_file, encoding='cp932', index=False)
df = pd.read_csv(csv_file, encoding='cp932')

3. Datenvorverarbeitung

Ich höre oft den Satz "Datenanalyse benötigt 80% der Zeit für die Vorverarbeitung", aber mir wurde klar, dass "das ist ...". Die folgende Vorverarbeitung wurde durchgeführt.

import re

#Datensätze mit nicht betragsmäßigem Verkaufspreis ausschließen
df = df[df['Verkaufspreis'].str.match('[0-9]*[Zehntausend]Kreis') | df['Verkaufspreis'].str.match('[0-9]MilliardeKreis') | df['Verkaufspreis'].str.match('[0-9]*Milliarde[0-9]*ZehntausendKreis')]

#Verkaufspreis[Zehntausend Yen]Hinzufügen
price = df['Verkaufspreis'].apply(lambda x: x.replace('* Einschließlich Rechte', ''))
price = price.apply(lambda x: re.sub('([0-9]*)Milliarde([0-9]*)Zehntausend Yen', r'\1\2', x))  # 1憶2000Zehntausend Yen → 12000
price = price.apply(lambda x: re.sub('([0-9]*)100 Millionen Yen', r'\10000', x))  # 1100 Millionen Yen → 10000
price = price.apply(lambda x: re.sub('([0-9]*)Zehntausend Yen', r'\1', x))  # 9000Zehntausend Yen → 9000
price = price.apply(lambda x: x.replace('@00', '0'))  #Kann nicht berücksichtigt werden → In 0 konvertieren
price = price.apply(lambda x: x.replace('21900~31800', '0'))  #Das gleiche wie oben
df['Verkaufspreis[Zehntausend Yen]'] = price.astype('int')
df = df[df['Verkaufspreis[Zehntausend Yen]'] > 0]  #0 Datensatzausschluss

#Besetztes Gebiet[m2]Hinzufügen
df['Besetztes Gebiet[m2]'] = df['Besetztes Gebiet'].apply(lambda x: re.sub('(.*)m2.*', r'\1', x))
df['Besetztes Gebiet[m2]'] = df['Besetztes Gebiet[m2]'].apply(lambda x: re.sub('-', '0', x)).astype('float')  #Kann nicht berücksichtigt werden → In 0 konvertieren
df = df[df['Besetztes Gebiet[m2]'] > 0]  #0 Datensatzausschluss

#Balkon[m2]Hinzufügen
df['Balkon[m2]'] = df['Balkon'].apply(lambda x: re.sub('(.*)m2.*', r'\1', x))
df['Balkon[m2]'] = df['Balkon[m2]'].apply(lambda x: re.sub('-', '0', x)).astype('float')  #Kann nicht berücksichtigt werden → In 0 konvertieren
df = df[df['Balkon[m2]'] > 0]  #0 Datensatzausschluss

#Route hinzufügen
df['Route'] = df['Entlang der Linie / Station'].apply(lambda x: re.sub('(.*Linie).*', r'\1', x, count=5))

#Nächste Station hinzufügen
df['Nächste Station'] = df['Entlang der Linie / Station'].apply(lambda x: re.sub('.*「(.*)」.*', r'\1', x, count=5))

#Zu Fuß[Protokoll]Hinzufügen
df['Zu Fuß[Protokoll]'] = df['Entlang der Linie / Station'].apply(lambda x: re.sub('.*Ayumu([0-9]*)Protokoll.*', r'\1', x)).astype('int')

#Präfektur hinzufügen
df['Präfekturen'] = df['Lage'].apply(lambda x: re.sub('(.*?[Präfekturen]).*', r'\1', x))

#Stadt hinzugefügt
df['Gemeinde'] = df['Lage'].apply(lambda x: re.sub('.*[Präfekturen](.*?[Gemeinde]).*',r'\1',x))

#Überschreibe df der gewünschten Spalte
df = df[['Name des Anwesens', 'Verkaufspreis[Zehntausend Yen]', 'Route', 'Nächste Station', 'Zu Fuß[Protokoll]',
         'Gebäudeplan', 'Besetztes Gebiet[m2]', 'Balkon[m2]',
         'Präfekturen', 'Gemeinde', 'Lage']]

4. Analyse

Ich habe die gesamte Linie, in der ich leben möchte, und die 2LDK oder mehr der Stationen (3 Stationen) analysiert, an denen ich besonders interessiert bin.

Ganze Strecke

Filtern

route = ['Linie A.', 'Linie B', 'C-Linie', 'D Linie', 'E Linie', 'F Linie']
floor_plan = ['2LDK', '2LDK+S (Nado)',
              '3DK', '3DK+S (Nado)', '3LDK', '3LDK+S (Nado)', '3LDK+2S (Nado)',
              '4DK', '4DK+S (Nado)', '4LDK', '4LDK+S (Nado)']
filtered = df[df['Route'].isin(route) & df['Gebäudeplan'].isin(floor_plan)]

Korrelationsanalyse

import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline

sns.pairplot(filtered)
plt.show()

image.png

Es scheint eine leichte Korrelation zwischen dem Verkaufspreis und der besetzten Fläche zu geben, aber ansonsten scheint dies den Verkaufspreis nicht so sehr zu beeinflussen.

Verteilung der Verkaufspreise

import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline

sns.boxplot(x='Verkaufspreis[Zehntausend Yen]', data=filtered)
plt.show()

image.png

Von den Liegenschaften auf der gesamten Strecke wurden 50% mit rund 40-75 Millionen Yen besiedelt. Immerhin ist es in Tokio teuer ...

Statistiken

filtered.describe()

image.png

Das war alles für die gesamte Strecke.

Stationen von besonderem Interesse auf der Strecke (3 Stationen)

Von hier aus überprüfte ich die Stationen (3 Stationen), an denen ich interessiert war.

station = ['Eine Station', 'B Station', 'C Station']
grouped = filtered[filtered['Nächste Station'].isin(station)]

Verteilung der Verkaufspreise

Wir haben die Verteilung der Verkaufspreise an den drei Stationen untersucht.

import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline

sns.violinplot(x='Verkaufspreis[Zehntausend Yen]', y='Nächste Station', data=grouped)
plt.show()

image.png

Das, was mich am meisten interessiert, ist der Boden (grün), aber er hat eine bimodale Verteilung. Vielleicht ist es zwischen Tawaman und anderen polarisiert.

Statistiken

grouped.describe()

image.png

Die Station, die Sie am meisten interessiert

Ich fragte mich, ob es an der Station, an der ich am meisten interessiert war, eine Immobilie gab, die weniger als 50 Millionen Yen kostete, und analysierte sie weiter.

Analyse für jede Etage

Anzahl der Eigenschaften
c = filtered[filtered['Nächste Station'] == 'C Station']
c.groupby(by='Gebäudeplan')['Gebäudeplan'].count()

image.png

Verkaufspreis
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline

sns.swarmplot(x='Verkaufspreis[Zehntausend Yen]', y='Gebäudeplan', data=c)
plt.show()

image.png

Es gab nur 7 Fälle für weniger als 50 Millionen Yen ...

Immobilien weniger als 50 Millionen Yen

Ich habe die Eigenschaften für weniger als 50 Millionen Yen weiter untersucht.

c_u5k = c[c['Verkaufspreis[Zehntausend Yen]'] < 5000]
c_u5k = c_u5k[['Name des Anwesens', 'Gebäudeplan', 'Besetztes Gebiet[m2]', 'Balkon[m2]',
               'Verkaufspreis[Zehntausend Yen]', 'Lage', 'Zu Fuß[Protokoll]']].sort_values(['Name des Anwesens', 'Gebäudeplan'])
c_u5k

image.png

Da es nur 7 Fälle gibt, war ich an 1471 interessiert, als ich den Standort in Google Maps nachgeschlagen habe. 3LDK, 69,5㎡ sind 42,8 Millionen Yen, was in der Nähe dieser Station billig zu sein scheint, aber ist es wirklich billig vom Marktpreis von 3LDK von 3 Stationen, an denen Sie überhaupt interessiert sind? Ich habe es nachgeschlagen.

grouped[grouped['Gebäudeplan'] == '3LDK'].describe()

image.png

Ergebnis,

Es war ziemlich billig. Nach einer Untersuchung des Grundes wurde festgestellt, dass das Anwesen 1985 erbaut wurde und ziemlich alt ist. Da es kein Innenfoto gibt und es heißt "Sie können umbauen!", Kann gefolgert werden, dass es erheblich altert.

Selbst wenn die Renovierung 10 Millionen Yen kostet, ist sie dennoch billig. Ich wünschte ich hätte das Geld ... in diesen Tagen.

Impressionen

Es war mein erstes Mal, dass ich Web Scraping machte, aber es war eine sehr nützliche Praxis, da es wahrscheinlich in Zukunft benötigt wird. Es wird gesagt, dass "was du magst, ist gut in Dingen", aber es war ein Tag, an dem ich wieder das Gefühl hatte, dass das, was ich tun wollte, wie das Analysieren, woran ich interessiert war, der schnellste Weg war, mich zu verbessern.

Websites, die Datenanalyse gelernt haben

Ich werde auf der Website von Kame @ US Data Scientist "Einführung in Python für Data Science" studieren. Ich tat. Die wichtigen Punkte sind leicht verständlich zusammengefasst. Ich empfehle es.

Verweise

Ich habe aus den folgenden Artikeln beim Web Scraping gelernt.

@ tom78784 Artikel Scraping beim Wiederholen von Seitenübergängen in Python

@ Chanmoros Artikel Schöne Suppe in 10 Minuten

Vielen Dank!

Recommended Posts

[Python] Fluss vom Web-Scraping zur Datenanalyse
Datenanalyse zur Verbesserung von POG 1 ~ Web Scraping mit Python ~
Meteorologie x Python ~ Von der Wetterdatenerfassung bis zur Spektrumanalyse ~
Datenanalyse Python
Python: Lesen von JSON-Daten von der Web-API
[Python] Webanwendung von 0! Hands-on (4) -Datenformung-
Portiert von der R-Sprache von "Sazae-sans Janken Data Analysis" nach Python
Einführung in die Datenanalyse mit Python P17-P26 [ch02 1.usa.gov Daten von bit.ly]
Datenanalyse mit Python 2
So öffnen Sie einen Webbrowser über Python
Änderungen von Python 3.0 zu Python 3.5
Änderungen von Python 2 zu Python 3.0
Datenanalyse Übersicht Python
[Python] Lesen von Daten aus CIFAR-10 und CIFAR-100
Python-Datenanalysevorlage
Datenanalyse mit Python
Extrahieren Sie mit Python Daten von einer Webseite
[Python] Von der morphologischen Analyse von CSV-Daten bis zur CSV-Ausgabe und Diagrammanzeige [GiNZA]
WEB Scraping mit Python und versuchen, aus Bewertungen eine Wortwolke zu machen
[Für Anfänger] So studieren Sie den Python3-Datenanalysetest
So kratzen Sie Bilddaten von Flickr mit Python
Lesehinweis: Einführung in die Datenanalyse mit Python
Senden Sie Daten von Python über die Socket-Kommunikation an Processing
[Technisches Buch] Einführung in die Datenanalyse mit Python -1 Kapitel Einführung-
Mein Python-Datenanalyse-Container
Post von Python nach Slack
Web Scraping mit Python + JupyterLab
Python für die Datenanalyse Kapitel 4
Anaconda aktualisiert von 4.2.0 auf 4.3.0 (python3.5 aktualisiert auf python3.6)
Lernnotizen zur Python-Datenanalyse
Datenrabatfluss für Pferderennen
Web Scraping mit Selenium (Python)
Wechseln Sie von Python2.7 zu Python3.6 (centos7)
Stellen Sie von Python aus eine Verbindung zu SQLite her
Python für die Datenanalyse Kapitel 2
Web Scraping Anfänger mit Python
Datenanalyse mit Python-Pandas
Python für die Datenanalyse Kapitel 3
[Von Zeit zu Zeit aktualisiert] Python-Memos, die häufig für die Datenanalyse verwendet werden [N-Division usw.]
[Impression] [Datenanalyse ab Null] Einführung in die Python-Datenwissenschaft in Geschäftsfällen
[Python] Einführung in das Scraping | Programm zum Öffnen von Webseiten (Selenium-Webdriver)
20200329_Einführung in die Datenanalyse mit Python 2nd Edition Personal Summary
Scrapen der gewünschten Daten von der Website durch Verknüpfen von Python und Excel
Drücken Sie in Python auf REST, um Daten von New Relic abzurufen
Übergeben Sie die OpenCV-Daten der ursprünglichen C ++ - Bibliothek an Python
Rufen Sie Matlab von Python zur Optimierung auf
Von der Installation von Elasticsearch bis zur Dateneingabe
[Python] Wie man MP3-Daten fFT
Python: Zeitreihenanalyse: Vorverarbeitung von Zeitreihendaten
Post von Python auf Facebook Timeline
Web Scraping mit Python Erster Schritt
Ich habe versucht, WebScraping mit Python.
[Lambda] [Python] Von Lambda auf Twitter posten!
Python (vom ersten Mal bis zur Ausführung)
Poste ein Bild von Python auf Tumblr