6
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

念願の賃貸スクレイピングをしてみた!

Last updated at Posted at 2019-02-27

#スクレイピングをしたかった
長らく放置をしてしまいました。就職をして資格を取ったり、自宅サーバー組んでインフラ系学んだり、
時にはゲームを作ろうとして3Dモデリングしてた時もありました。

ですが、なんだかんだでPythonに戻ってまいりましたw

今回は、Pythonを勉強し始めてから気になっていたスクレイピングをしてみたいと思います。(過去2回挫折)

##何をするか

近々、引っ越しをするためにいい物件を探します!
任意の賃貸情報サイトをスクレイピングし、家賃や駅までの時間、築年数などを取得していきます!

##用意するもの
・Python3系
・json
・BeautifulSoup
・スクレイピングしたいサイト
・森永のラムネ

##とりあえずコードどぉ~~おおん!!

#coding utf-8

import os
import re
import requests
import json
import traceback
from bs4 import BeautifulSoup as bs

def get_moreinfo(j):
    return j.find("a", class_="detailBtn").get("href")

def get_type(j):
    info = j.find(class_="type").find_all("p")
    return info[0].getText(), float(info[1].getText().rstrip("2").strip("m"))

def get_rent(j):
    return float(j.find(class_="price").getText())

def get_floor(j):
    try:
        return int(re.sub(r'\D', '', j.find(class_="roomNumber").getText()))
    except:
        return 0

def get_time(i):
    timelist = []
    for j in i.find(class_="traffic").find_all("li"):
        a = 0
        for k in re.findall(r'(\d+|\D+)', j.getText()):
            try:
                a += int(k)
            except:
                pass
        timelist.append(a)
    return timelist

def get_old_material_floormax(i):
    detailinfo = i.find(class_="detailData").find_all("td")
    return int(re.sub(r'\D', '', detailinfo[0].getText())), detailinfo[1].getText(), int(re.sub(r'\D', '', detailinfo[2].getText()))

def get_address(i):
    return i.find(class_="address").getText().strip()

def get_name(i):
    return i.find(class_="buildingName").getText().strip()

def get_page(count, pref, city):
    p = pref
    c = city
    co = count
    url = "https://sumaity.com/chintai/" + p + "/" + c + "/?page=" + str(co)
    return url

def main():
    pref = input("Prefecture: ")
    city = input("City: ")
    filename = pref + "_" + city
    count = 1

    os.mkdir(filename)
    print("Creating a Directory for Data Files...")

    while True:
        try:
            page = requests.get(get_page(count, pref, city))
            soup = bs(page.text, "html.parser")
            houselist = {}

            if page.status_code == 200:
                for i in soup.find_all(class_="building"):

                    infolist = {}
                    indexname = get_name(i)
                    infolist["address"] = get_address(i)
                    infolist["old"], infolist["material"], infolist["floormax"] = get_old_material_floormax(i)
                    infolist["time"] = get_time(i)

                    for j in i.find_all(class_=["estate applicable", "estate applicable gray"]):
                        infolist["floor"] = get_floor(j)
                        infolist["rent"] = get_rent(j)
                        infolist["type"] = get_type(j)
                        infolist["moreinfo"] = get_moreinfo(j)

                    houselist[indexname] = infolist

                print("Successfully exported " + str(count) + " pages...")
                count += 1

            elif count == 1:
                os.rmdir(filename)
                print("Status Code: " + str(page.status_code))
                break;
            else:
                print("Export Processing Complete!!")
                break;

            with open("./" + filename + "/" + filename + str(count-1) + ".json", "w") as f:
                json.dump(houselist, f, ensure_ascii=False, indent=4)

        except:
            traceback.print_exc()
            break;

if __name__ == '__main__':
    main()

ざぁ~っと目を通していただけましたかね。

##やってること
BeautifulSoupをとreqestsを使ってスクレイピングをしています!
###・ユーザーから県と市または区をinputします
やっぱりinputいいですよね!いつかかっこいい対話型の情報作成アプリとか作ってみたいですわ。
###・ディレクトリを作成しておきます。
これはosを使って同じ階層内に先ほどのinputから受け取った情報でディレクトリを作成しました。
あとでここに集めた情報をぶっこみます
今回は使いませんでしたが、形式を決めて情報を取っておけば何回もアクセスしなくていいし、
あとで使えるかなっておもいました。
###・受け取った都市の情報でアクセス先のリンクを作成します。
今回はラッキーなことにWebサイトの階層がそうなってました!
https://サイト名.com/販売形態/県/市または区
みたいになってました!!!
また、このあと複数のページにわたって作業するため、ページ移動用のcountを設けています!
###・作成したURLにからHTMLを入手します。
ここでreqestsが持ってきたhtmlをBeautifulSoupが使えるようにするんですよね!たぶん。
この時に一緒に集めた情報をいったんためておく用のリストも作りました。いらないかもしれません。
この辺で、用意していた森永のラムネをたべます。
###・いざ、スクレイプ!!
最終的には建物ではなく部屋ごとに情報が欲しいので、for文やwhile文を駆使してぐるぐるまわしました。
まず、建物の情報のブロックを探し、そこから築年数や駅からの距離など、部屋共通の情報を取り出します。
その後、家賃や間取りなど部屋固有の情報を取り出します。
これをすべてのページに施し、houselistにじゃんじゃん集めて、最終的にjsonファイルとして、
あらかじめ作っておいたディレクトリに放り込みます。

おわり。

#さいごに
超適当な投稿でごめんなさい。コード事態はがんばって書いたので許してください。なんでもします。

反省点としては、classがよくわかってない。ので使ってない。このスクリプトにはclassの出番ありますか?
あとは相変わらずコードが汚い。やたらと1行に収めようとした結果です。

ご指摘いいいいいいいいいいいいいいいっぱい受け付けてます。

今度は、あつめたjsonファイルを使って、家賃、広さ、駅からの距離などの相関関係をグラフにしたり、順位をつけて
市内で一番いい部屋を見つけれるようにしたいと思ってます!
(不動産屋には勝てません)

もうすぐ朝なので寝ます。
(Qiitaへの投稿の仕方が雑なのは承知です。起きたら恥ずかしくて消すかもしれないです。)

6
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?