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.
Die verwendeten Pakete sind wie folgt.
import datetime
import re
import time
from urllib.parse import urljoin
from bs4 import BeautifulSoup
import pandas as pd
import requests
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)
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')
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']]
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.
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)]
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
sns.pairplot(filtered)
plt.show()
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.
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
sns.boxplot(x='Verkaufspreis[Zehntausend Yen]', data=filtered)
plt.show()
Von den Liegenschaften auf der gesamten Strecke wurden 50% mit rund 40-75 Millionen Yen besiedelt. Immerhin ist es in Tokio teuer ...
filtered.describe()
Das war alles für die gesamte Strecke.
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)]
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()
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.
grouped.describe()
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.
c = filtered[filtered['Nächste Station'] == 'C Station']
c.groupby(by='Gebäudeplan')['Gebäudeplan'].count()
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
sns.swarmplot(x='Verkaufspreis[Zehntausend Yen]', y='Gebäudeplan', data=c)
plt.show()
Es gab nur 7 Fälle für 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
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()
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.
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.
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.
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