Ravi de vous rencontrer. Je m'appelle S.I, étudiante de troisième année à l'université appartenant au Département de génie de l'information. Je n'ai traité que de l'expérience Python dans les expériences universitaires.
La Division de la science des données de Kakko Co., Ltd., où je suis stagiaire, a pour tâche de créer un robot d'exploration pendant la période d'essai pour collecter, traiter et visualiser les données, et discuter brièvement de ce que j'ai appris.
Un ami de l'université vivra seul. Cependant, lorsque je regarde le site Web de l'immobilier, il y a trop de propriétés à choisir. Veuillez le résoudre par l'analyse des données.
Dans les 60 minutes de trajet depuis la gare JR Kanamachi
Lorsque vous recherchez une propriété à partir de votre propre expérience de recherche d'une propriété, les «informations que vous voulez savoir» sont J'ai pensé que c'était une "condition pour trouver un bien" à dire à l'agent immobilier qui agit en tant qu'intermédiaire, et j'ai décidé de le résoudre par l'analyse des données.
Cette fois-ci, nous utiliserons la "Recherche de temps de trajet / école" de Smighty pour explorer, et les résultats de la recherche seront dans les 60 minutes de la gare de Kanamachi.
Le code d'exploration ressemble à ceci:
crawling.py
import requests
from bs4 import BeautifulSoup
import time
import os
import datetime
def crawling():
#Chemin du répertoire pour l'enregistrement des fichiers html
dirname = './html_files'
if not os.path.exists(dirname):
#Créer un répertoire s'il n'existe pas
os.mkdir(dirname)
#Convertir la première page en html
url = "https://sumaity.com/chintai/commute_list/list.php?search_type=c&text_from_stname%5B%5D=%E9%87%91%E7%94%BA&cost_time%5B%5D=60&price_low=&price_high="
response = requests.get(url)
time.sleep(1)
#Enregistrer dans un fichier
page_count = 1 #Nombre de pages
with open('./html_files/page{}.html'.format(page_count), 'w', encoding='utf-8') as file:
file.write(response.text)
#Nombre total de propriétés(Valeur théorique)Acquisition (comme condition d'acceptation)
soup = BeautifulSoup(response.content, "lxml")
num_bukken = int(soup.find(class_='searchResultHit').contents[1].text.replace(',', ''))
print("Nombre total de propriétés dans les 60 minutes suivant le temps de trajet:", num_bukken)
#Enregistrez le nombre total de propriétés dans un fichier texte car il sera utilisé pour vérifier les conditions d'acceptation lors du scraping.
path = './data.txt'
with open(path, mode='w') as f:
f.write("{}\n".format(num_bukken))
#Exploration sur la deuxième page et les suivantes, continuez jusqu'à ce que la page suivante soit épuisée
while True:
page_count += 1
#Trouvez l'URL suivante
next_url = soup.find("li", class_="next")
#Pause et terminer lorsque la page suivante est épuisée
if next_url == None:
print("Nombre total de pages:", page_count-1)
with open(path, mode='a') as f:
f.write("{}\n".format(page_count-1))
break
#Obtenez l'URL de la page suivante et enregistrez-la sous forme de fichier html
url = next_url.a.get('href')
response = requests.get(url)
time.sleep(1)
with open('./html_files/page{}.html'.format(page_count), 'w', encoding='utf-8') as file:
file.write(response.text)
#Préparez-vous à l'analyse pour obtenir l'URL de la page suivante
soup = BeautifulSoup(response.content, "lxml")
#Sortie de progression de l'exploration
if page_count % 10 == 0:
print(page_count, 'Obtenir la page')
#Fonction principale
if __name__ == "__main__":
date_now = datetime.datetime.now()
print("Commencez à explorer:", date_now)
crawling()
date_now = datetime.datetime.now()
print("Exploration terminée:", date_now)
Voici les variables grattées cette fois.
Le code de scraping ressemble à ceci:
scraping.py
from bs4 import BeautifulSoup
import datetime
import csv
import re
#Expression régulière pour diviser une adresse en préfecture et en ville
pat = '(...??[Préfectures])((?:Asahikawa|Date|Ishikari|Morioka|Oshu|Tamura|Sud de Soma|Nasu Shiobara|Higashimurayama|Musashi Murayama|Hamura|Tokamachi|Joetsu|Toyama|Ville de Nono|Omachi|Gamagun|Yokkaichi|Himeji|Yamato Koriyama|Hirohiichi|en dessous de>Pin|Iwakuni|Tagawa|Omura|Miyako|Furano|Beppu|Saeki|Kurobe|Petits objets|Shiojiri|Tamano|Shunan)ville|(?:余ville|高ville|[^ville]{2,3}?)comté(?:Tamamura|Omachi|.{1,5}?)[Villes et villages]|(?:.{1,4}ville)?[^ville]{1,4}?quartier|.{1,7}?[villeVilles et villages])(.+)'
def scraping(total_page, room_num):
#Initialisation du nombre de propriétés
room_count = 0
#Préparation du fichier csv (ajout d'un en-tête)
with open('room_data.csv', 'w', newline='', encoding='CP932') as file:
header = ['No', 'building_name', 'category', 'prefecture', 'city', 'station_num', 'station', 'method', 'time', 'age', 'total_stairs', 'stairs', 'layout', 'room_num', 'space', 'south', 'corner', 'rent', 'unit_price', 'url']
writer = csv.DictWriter(file, fieldnames=header)
writer.writeheader()
for page_num in range(total_page):
#Sortie de progression du grattage
if page_num % 10 == 0:
print(page_num , '/', total_page)
#Ouvrez le fichier html à gratter avec Beautiful Soup
with open('./html_files/page{}.html'.format(page_num + 1), 'r', encoding='utf-8') as file:
page = file.read()
soup = BeautifulSoup(page, "lxml")
#Obtenez des informations pour chaque bâtiment
building_list = soup.find_all("div", class_="building")
for building in building_list:
#Catégorie de bâtiment: Manoir ou appartement ou maison individuelle
buildingCategory = building.find(class_="buildingCategory").getText()
#Nom du bâtiment
buildingName = building.find(class_="buildingName").h3.getText().replace("{}".format(buildingCategory), "").replace("Nouvelle arrivee", "")
#Extraction des candidats pour la station la plus proche et la distance de la station
traffic = building.find("ul", class_="traffic").find_all("li")
#Nombre de stations les plus proches
station_num = len(traffic)
#Extraire ceux avec un temps de marche court
min_time = 1000000 #Initialisez le temps minimum requis
for j in range(station_num):
traffic[j] = traffic[j].text
figures = re.findall(r'\d+', traffic[j])
time = 0
for figure in figures:
#Calcul du temps requis
time += int(figure)
#Stocker le temps minimum requis et indexer si minimum
if time < min_time:
min_time = time
index = j
#Si vous avez des informations sur la gare ou l'itinéraire
if len(traffic[index].split(' ')) > 1:
#Décision d'itinéraire
line = traffic[index].split(' ')[0]
#Déterminer la station la plus proche
station = traffic[index].split(' ')[1].split('station')[0]
#Acquisition du transport (bus, voiture, marche) jusqu'à la gare
if len(traffic[index].split(' ')) > 2:
if "autobus" in traffic[index].split(' ')[1]:
method = "bus"
elif "voiture" in traffic[index].split(' ')[2]:
method = "car"
else:
method = "walk"
#Aucune information de transport vers la gare
else:
method = None
#S'il n'y a pas d'informations sur la station ou l'itinéraire
else:
station = None
line = None
method = None
time = None
#adresse de rue
address = building.find(class_="address").getText().replace('\n','')
address = re.split(pat, address)
if len(address) < 3:
prefecture = "Tokyo"
city = "Quartier Adachi"
else:
prefecture = address[1]
city = address[2]
#Détails du bâtiment (âge, structure, nombre total d'étages)
building_detail = building.find(class_="detailData").find_all("td")
for j in range(len(building_detail)):
building_detail[j] = building_detail[j].text
# ----Obtenez seulement le nombre d'âge----
#Âge inconnu
if 'Construction inconnue' == building_detail[0]:
building_detail[0] = None
#0 ans
elif 'Moins que' in building_detail[0]:
building_detail[0] = 0
#Valeur normale
else:
building_detail[0] = int(re.findall(r'\d+', building_detail[0])[0])
#Obtenez uniquement le nombre total d'étages
building_detail[2] = int(re.findall(r'\d+', building_detail[2])[0])
# ----Obtenir les détails de la chambre----
rooms = building.find(class_="detail").find_all("tr",
{'class': ['estate applicable', 'estate applicable gray']})
for j in range(len(rooms)):
#Compter le nombre de propriétés
room_count += 1
# ----Nombre d'étages----
stairs = rooms[j].find("td", class_="roomNumber").text
#Obtenir uniquement des nombres (supprimer "étage", traiter les valeurs manquantes)
if "-" == stairs:
stairs = None
else:
stairs = int(re.findall(r'\d+', stairs)[0])
#Faire du loyer un type entier
price = rooms[j].find(class_="roomPrice").find_all("p")[0].text
price = round(10000 * float(price.split('Dix mille')[0]))
#Frais de gestion
kanri_price = rooms[j].find(class_="roomPrice").find_all("p")[1].text
#Unification de la notation (suppression de la notation de 10 000 yens, "-"Et" 0 yen "traitement des valeurs manquantes)
if "-" in kanri_price or "0 yen" == kanri_price:
kanri_price = 0
else:
kanri_price = int(kanri_price.split('Cercle')[0].replace(',',''))
#Type de chambre (disposition)
room_type = rooms[j].find(class_="type").find_all("p")[0].text
if room_type == "Studio":
room_type = "1R"
#nombre de pièces
num_of_rooms = int(re.findall(r'\d+', room_type)[0])
#Superficie de la pièce, suppression de l'unité "m2"
room_area = rooms[j].find(class_="type").find_all("p")[1].text
room_area = float(room_area.split('m')[0])
#Chambre d'angle exposée sud
special = rooms[j].find_all("span", class_="specialLabel")
south = 0
corner = 0
for label in range(len(special)):
if "Exposition sud" in special[label].text:
south = 1
if "Chambre d'angle" in special[label].text:
corner = 1
#Obtenir une URL détaillée
room_url = rooms[j].find("td", class_="btn").a.get('href')
#location=Location+Demandez des frais de gestion
rent = price + kanri_price
# 1m^Trouvez le loyer (prix unitaire) pour chaque 2
unit_price = rent / room_area
#Sortie vers un fichier csv: codage par défaut"utf-8", Si vous gérez le japonais dans Windows"cp932"
with open('room_data.csv', 'a', newline='', encoding='CP932') as file:
writer = csv.DictWriter(file, fieldnames=header)
writer.writerow(
{'No':room_count, 'building_name':buildingName, 'category':buildingCategory, 'prefecture':prefecture, 'city':city, 'station_num':station_num, 'station':station,
'method':method, 'time':min_time, 'age':building_detail[0], 'total_stairs':building_detail[2], 'stairs':stairs,
'layout':room_type, 'room_num':num_of_rooms, 'space':room_area, 'south':south, 'corner':corner, 'rent':rent, 'unit_price':unit_price, 'url':room_url})
print("{}Nous avons acquis les données de propriété.".format(room_count))
#Confirmation des conditions d'acceptation
if room_count == room_num:
print("Conditions d'acceptation claires")
else:
print("{}Il y a une différence. Les conditions d'acceptation n'ont pas été effacées.".format(abs(room_count-room_num)))
if __name__ == "__main__":
date_now = datetime.datetime.now()
print("Commencez à gratter:", date_now)
#Passer le nombre total de pages et le nombre de propriétés à la fonction de scraping (condition d'acceptation)
path = './data.txt'
with open(path) as f:
data = f.readlines()
scraping(int(data[1].replace("\n","")), int(data[0].replace("\n","")))
date_now = datetime.datetime.now()
print("Grattage terminé:", date_now)
Tout d'abord, j'ai vérifié l'histogramme pour voir comment le loyer est réparti et j'ai supprimé les propriétés dont le loyer était trop élevé, car elles ne convenaient pas à la vie seule.
À partir de là, voyons comment chaque variable affecte le loyer.
Regardons le nombre de propriétés et la répartition des loyers pour chaque étage.
Lorsque le nombre de propriétés pour chaque étage est indiqué dans un graphique à barres, il a été constaté que les étages de 1R à 3LDK représentaient 98% du total. Si vous regardez la répartition du loyer pour ces étages sur une parcelle de violon, vous pouvez voir que la répartition du loyer diffère pour chaque étage. Par conséquent, la disposition est susceptible d'être une variable qui affecte le loyer.
Voyons où il y a de nombreuses propriétés.
Par préfecture, la plupart d'entre eux étaient Tokyo et Chiba, et Saitama représentait environ 3%. En regardant chaque ville, quartier, ville et village plus en détail, il y a plus de 1000 propriétés par Arakawa-ku, Kashiwa-shi, Matsudo-shi, Katsushika-ku, Adachi-ku, et cela semble être bon pour trouver des propriétés. Regardons la répartition des loyers dans chacun de ces quartiers.
En regardant l'histogramme des loyers par préfecture, nous pouvons voir qu'il existe de nombreuses propriétés à Tokyo, mais de nombreuses propriétés à loyer élevé, et de nombreuses propriétés à Chiba sont moins chères. Si vous regardez la carte de la barbe de la boîte de location pour chaque ville, quartier, ville et village en détail, vous pouvez voir que la boîte dans la zone verte de Chiba est située en bas. Il semble que vous puissiez trouver des propriétés bon marché à Matsudo, Kashiwa, Ryuyama, Ichikawa, Gagoko, Yoshikawa et Soka. Si vous regardez la carte de la barbe, vous pouvez voir que la répartition des loyers diffère selon le quartier, il semble donc que l'emplacement de la propriété affecte également le loyer.
Il existe une faible corrélation négative entre le temps de trajet et le loyer, et il semble que plus le temps de trajet est long, moins le loyer est bon. De plus, la différence de loyer en fonction du moyen de transport comme le bus ou la marche à pied utilisé à ce moment est indiquée. On constate que le loyer de la promenade bleue est plus élevé que celui du bus. Par conséquent, le transport et le temps de déplacement sont susceptibles d'affecter le loyer.
Nous avons regroupé les âges des bâtiments tous les 5 ans et publié un tableau barbe des loyers.
Vous pouvez voir que le loyer diminue progressivement de la propriété après 15 ans. Par conséquent, l'âge est également susceptible d'être une variable qui influe sur le loyer.
Regardons la répartition du loyer par le nombre total d'étages du bâtiment et l'histogramme du nombre total d'étages.
En regardant le nombre total d'étages et la répartition des loyers, il semble que le loyer des propriétés jusqu'à 2 étages soit bon marché. En regardant l'histogramme du nombre total d'étages, la plupart des propriétés de deux étages étaient des appartements. En outre, 95% des propriétés sont situées dans 10 étages, donc je pense que vous avez peut-être envie de propriétés de grande hauteur pour la première fois en vivant seul, mais cela semble difficile lorsqu'il s'agit de propriétés pour vivre seul. D'après les résultats ci-dessus, il a été constaté que les informations sur le bâtiment affectent également le loyer.
Je vais voir si l'orientation sud, qui est une caractéristique de la propriété, affecte le loyer. J'ai fait un histogramme des propriétés exposées au sud et de celles qui ne sont pas exposées au sud.
En regardant l'histogramme, la distribution est similaire, j'ai donc testé si la différence de loyer était significative. Il y avait une différence significative entre le loyer moyen des propriétés exposées au sud et celles non exposées au sud. A ce moment, le test de dispersion égale a été effectué par le test F, et il n'a pas été rejeté que la dispersion égale ait été obtenue, de sorte que le test t en supposant une dispersion égale a été effectué. En conséquence, la propriété exposée au sud coûte environ 1500 yens moins cher. D'après ce qui précède, il a été constaté que le fait qu'il soit ou non exposé au sud affecte le loyer.
De même, nous examinerons l'impact sur les pièces d'angle.
Puisque la dispersion égale a été rejetée par le test F et que la dispersion égale a été rejetée, le test t a été effectué en supposant que les variances n'étaient pas égales. En conséquence, il s'est avéré que la différence était significative et que le prix de la chambre d'angle était d'environ 2000 yens plus élevé. D'après ce qui précède, il a été constaté que la chambre d'angle affecte également le loyer.
Sur la base des résultats obtenus jusqu'à présent, je voudrais analyser à nouveau et préciser les conditions de la propriété que je recommanderais à mes amis de l'université qui sont réellement en difficulté.
La relation entre le nombre de propriétés et le loyer moyen est tracée pour chaque ville.
Vous pouvez voir que Matsudo City a de nombreuses propriétés et le loyer moyen est bas.
Le nombre de propriétés et le loyer moyen pour chaque étage sont les suivants.
Le loyer moyen pour 1R, 2K et 3K est moins cher, mais le nombre de propriétés 1K est écrasant. Si vous vivez seul, vous n'avez pas besoin de beaucoup d'espace, donc je pense que 1K est une bonne mise en page. Le prix du marché de location pour une propriété de 1K à Matsudo City était de 56000 yens en utilisant le prix médian.
Un graphique à barbe montrant les changements dans la répartition des loyers en fonction de l'âge des propriétés de 1K à Matsudo City
Vous pouvez voir qu'il y a de nombreuses propriétés en dessous du prix du marché si la propriété a 15 ans ou plus. Je pense que c'est une bonne idée de le chercher dans environ 15 ans.
Le temps nécessaire depuis la gare est indiqué sous forme de graphique à barres par codage couleur en fonction du moyen de transport.
On constate que 95% des propriétés pour vivre seul sont à moins de 20 minutes à pied. Nous avons tracé le nombre de propriétés et le loyer moyen pour chaque fois requis de la gare. Vous pouvez voir que le loyer sera moins cher si vous le prolongez dans les 15 minutes.
Sur la base de ce qui précède, les conditions pour trouver une propriété à dire à un ami sont les suivantes.
Si vous recherchez dans les conditions ci-dessus, il s'agira d'une chambre de type ** appartement **. Avec cette condition, je pense que vous pouvez trouver une bonne chambre en vous rendant chez un agent immobilier à Matsudo.
Le point de réflexion est que les données ont été analysées sans qu'une politique soit décidée. Ce n'est pas grave si vous le faites comme passe-temps, mais si vous le faites, vous vous retrouverez avec un diagramme que vous ne savez pas où l'utiliser, ce qui est une énorme perte de temps, vous devez donc analyser les données avec un but.
Je pense que ce numéro a été une expérience précieuse parce que j'ai pu faire des commentaires en créant du matériel et en faisant des présentations, pas seulement des analyses. J'ai remarqué que la collecte et l'analyse des données prenaient tellement de temps et qu'il était difficile de transmettre les résultats à l'autre partie, alors j'aimerais m'en servir à l'avenir.
c'est tout.