本記事では、SUUMOから物件情報を自動で集めるためのPython( まず最も多い疑問——「規約上、本当にダメなのか」——を整理します。結論から言えば、SUUMOの利用規約に「スクレイピング」という単語そのものは登場しません。しかしそれは「OK」を意味しません。明示禁止文言ではなく、より広く包括的な3つの条項で実質的に縛られている、という構造です。 SUUMO利用規約(リクルート社が運営するため、ドメインはrequests + BeautifulSoup)を使った最小実装のコード例から、つまずきやすいエラーの対処、押さえておきたい利用規約・著作権法・偽計業務妨害などの法的論点、そして用途に応じて使い分けたい公的データなどの併用候補まで、実装者目線で網羅的に整理します。コードを書いて動かしたい人と、業務導入前に押さえるべきポイントを把握したい人の両方に向けた構成です。
SUUMOのスクレイピングは規約違反なのか?
利用規約に「スクレイピング」の明示禁止条項はあるか
cdn.p.recruit.co.jpにホストされています)を確認しても、「スクレイピング」「クローラー」「ロボット」といった単語による明示的な禁止条項は見当たりません。これだけを根拠に「禁止されていない」と解釈する記事もありますが、それは早計です。日本の利用規約は欧米のように個別行為を列挙するスタイルではなく、包括条項で広くカバーする書き方が一般的だからです。
スクレイピングを規約上どう評価するかは、以下3つの条項を組み合わせて読み解くことになります。 規約解釈のポイント:「スクレイピング」という単語の有無ではなく、取得方法(自動化の度合い)・取得規模(負荷)・取得目的(私的利用か商業利用か)の3軸でバランスを取るのが実務上の判断基準です。3軸を意識して設計すれば、規約の包括条項に正面から触れる事態は避けやすくなります。 「規約違反 =直ちに刑事罰」ではありません。規約は契約の一種であり、違反があっても多くの場合まずは民事的な対応(アカウント停止、IP遮断、警告書送付)に留まります。ただし、規約違反は法的紛争になった際の不利な事実として効いてきます。さらに、取得方法や規模が大きくなると、規約違反とは別レイヤーで以下のリスクが現実化します。 これらの法的論点は記事末尾の「法務で押さえる4つの論点」で詳しく扱います。ここで押さえておきたいのは、規約・民事・刑事の3層にはそれぞれ別の閾値があるということ。アクセス頻度・取得規模・利用目的をそれぞれ適切に抑えれば、各層のリスクは実務上コントロール可能な範囲に収まります。 規約論と並んで、実装者がぶつかるのが「そもそも技術的に取れない」という壁です。SUUMOはUA・IPレピュテーション・アクセスパターン・Cookieなど複数シグナルを組み合わせたbot検知を行っていると考えられ、軽い気持ちで書いたスクリプトはどこかで止まることが多いと報告されています。判定は実行環境や時期で変動しますが、報告されている挙動と、過剰な検知を避けるための原則を整理します。 スクレイピング解説記事でしばしば言及されるのが、「 一方で、本記事執筆時の特定環境からの検証では、 結論:「UAをChromeに偽装すれば必ず通る」も「デフォルトUAなら必ず弾かれる」も、どちらも単純化しすぎです。SUUMOのbot検知はIP・パターン・Cookie・UAなど複数シグナルの組み合わせで判定される構造のため、1回のアクセス結果はサンプルでしかなく、サイト全体の挙動を代表しません。継続的にアクセスするほど検知精度が上がる傾向もあるため、「最初の数リクエストは通ったが、しばらくして403/429が返り始める」というパターンも珍しくありません。 賃貸一覧ページ アンチボット対策に引っかかると、一般的に段階的に強い制限がかかると言われています。 共有IP(VPN・モバイル回線・データセンターIP)で遮断されると、同じIPを使う他の利用者にも影響が出ます。「自分だけの問題」では済まないため、業務で動かす場合は遮断時の影響範囲まで設計に含めるべきです。なお、プロキシ(IPローテーション)でこの遮断を回避する設計案もありますが、検知回避の意図と評価されるリスクがあるため、後段の「プロキシの利用判断」で詳しく扱います。 実装に入る前に、SUUMOのページ構造と、技術的に取得できるデータ項目を整理します。賃貸一覧ページを例に、URLパラメータ・物件カードの粒度・1建物に複数部屋がぶら下がる構造などを把握しておくと、後段のコード例が理解しやすくなります。 SUUMOの主要ページは、おおむね以下のURL構造を取ります。 賃貸の一覧URLパラメータは、 1ページあたりの表示件数はデフォルト10件、UI上で20/30/50件に変更可能です。URLには表示件数を指定するパラメータが付くため、件数を増やすほど1ページあたりのデータ量は増えますが、ページごとの処理時間も伸びます。1ページあたり50件にしてリクエスト数を抑えるか、デフォルト10件で並列度を下げるか、という設計判断が出てきます。 賃貸の一覧ページ・詳細ページから(技術的に)取得できる主なデータ項目を整理します。実装の難易度は項目によって差があり、特に「画像URL」「地図座標」「仲介業者情報」は別ページへの遷移や追加リクエストが必要になることが多いです。 SUUMOの一覧ページは、現時点では主要部分がサーバーサイドレンダリング(SSR)されており、HTTPで取得したHTMLに物件カードが既に埋め込まれています。つまり ページ構造はSUUMO運営側の都合で変わることがあります。「今このセレクタで動く」と「半年後も動く」は別問題なので、スクレイピングをビジネスロジックに組み込む場合は、セレクタの抽象化・異常検知・通知設計をあらかじめ仕込んでおくと運用が安定します。逆に言えば、ここを設計段階で押さえておけば、構造変更があっても短時間で復旧できる体制が組めます。 ここからは、Pythonの セレクタの鮮度に関する注意:以下のコード例で使用しているクラス名( 利用目的に関する注意:このコードは技術解説目的の最小例です。実運用ではsleep間隔・User-Agentの設定・並列度の制御など、後述する技術的・法務的な配慮を踏まえて設計してください。大量取得が必要なユースケースでは、用途によっては不動産情報ライブラリなどの公的データの方が運用コストが軽い場合もあるので、後段の代替手段セクションも合わせて検討すると判断材料が増えます。 使用するライブラリは 実質禁止に効く3つの条項
規約違反と法的リスクの関係
SUUMOのアンチボット対策——何が検知され得るのか
User-Agentと403ブロックの関係
python-requests やcurl のデフォルトUser-Agent(UA)でアクセスすると HTTP 403 Forbiddenが返る」という挙動です。SUUMOについても、複数の実装記事や検証ブログで「デフォルトUAだと弾かれた」というレポートが上がっています。これは技術的には十分にあり得る挙動で、対策として「ブラウザ相当のUAを指定する」というアドバイスがセットで紹介されることが多いです。curl のデフォルトUAでもpython-requests/2.32のデフォルトUAでも200が返るケースが観測されました。つまり、UAによる403ブロックは「常に発動する固定的なルール」ではなく、実行環境(IPアドレスのレピュテーション、データセンターIPか家庭用IPか、時間帯、直前のアクセス頻度、Cookieの保持状況、A/Bテストのバリアント等)によって動的に判定されると考えるのが妥当です。robots.txtから読み取れる運営側の意思
https://suumo.jp/robots.txtを読むと、運営側がbotにどう振る舞ってほしいかが垣間見えます。要点は3つです。
Crawl-delay: 30 を明示。30秒に1リクエストという、検索エンジンbot基準でもかなり保守的な値。これが運営側の「ボットに期待する間隔」のシグナルGoogle-Extended: Allow: /。GoogleのAI学習クローラーは全許可にしている(生成AIの学習素材としてOK)/edit/、/mb/、?sort=等)。アクセスが想定されていないパスへの巡回は明確にNG/jj/chintai/ichiran/自体はrobots.txtでDisallowされていないため、「クロール自体は技術的に許可されている」と解釈する向きもあります。しかし利用規約が上位ルールであり、robots.txtで許されていても規約で禁じられていれば違反になる点は変わりません。検知された後に起きること
SUUMOから取得できるデータと、ページ構造の基礎
一覧ページと詳細ページの構造
/jj/chintai/ichiran/FR301FC001/?ar=030&bs=040&ta=13&sc=13101&page=2/ms/shinchiku/ 配下/ms/chuko/ 配下/chumon/ 配下ar(地方エリア)、bs(建物種別)、ta(都道府県コード)、sc(市区町村コード)、page(ページ番号)など、構造化されています。実装者目線では便利ですが、これは同時に「予測可能なクロールパターン」を作ってしまうため、運営側のパターンマッチング検知に引っかかりやすい側面もあります。ページネーション・検索パラメータの仕組み
取得できる主なデータ項目
カテゴリ
項目例
取得難易度
賃料・初期費用
家賃、共益費・管理費、敷金、礼金、保証金
低(一覧から取得可)
物件基本情報
所在地、最寄駅・徒歩分、間取り、専有面積、築年数
低
建物属性
建物種別(マンション/アパート)、構造、階数、向き
中(一覧と詳細で粒度が異なる)
設備・条件
バス・トイレ別、エアコン、ペット可、楽器可
中(詳細ページが必要)
画像・地図
物件写真URL、間取図、地図座標
高(遅延読み込みやJS依存あり)
仲介業者情報
店舗名、担当者名、電話番号
高(個人情報保護法に注意)
静的レンダリングと動的レンダリングの違い
requests + BeautifulSoup級の素朴な構成でも一覧データ自体はパース可能、という前提です。ただし以下の点に注意してください。
r2abtest_cidCookieが発行され、ユーザーごとに微妙にDOM構造が変わる場合がある。クラス名やセレクタの安定性は保証されないPythonでSUUMOをスクレイピングする最小実装
requests とBeautifulSoupを使って、SUUMOの賃貸一覧から物件情報を取得する最小限の実装例を示します。cassetteitem、cassetteitem_price--rent等)は、2026年5月時点でChrome開発者ツールにて実機確認したものです。SUUMOのDOM構造はA/Bテスト・定期改修・運営側の対策強化などにより、予告なく変更されます。本記事公開後しばらく経ってからコードを動かす場合は、必ずChrome開発者ツールで最新のクラス名を確認してから実行してください。コピペでそのまま動く保証はありません。必要なライブラリと環境準備
requests(HTTPクライアント)とbeautifulsoup4(HTMLパーサ)の2つだけです。Python 3.10以降を前提にしています。
pip install requests beautifulsoup41ページ分の物件カードを取得するコード
SUUMOの賃貸一覧ページは、1つの建物(div.cassetteitem)の中に、複数の部屋(tr.js-cassette_link)がぶら下がる構造になっています。つまり、同じ建物の異なる部屋は別行として展開されます。これを反映して、建物情報と部屋情報をそれぞれ抽出する形にします。
import time
import random
import requests
from bs4 import BeautifulSoup
URL = (
"https://suumo.jp/jj/chintai/ichiran/FR301FC001/"
"?ar=030&bs=040&ta=13&sc=13101"
)
HEADERS = {
# SUUMOはデフォルトのpython-requests UAでアクセスすると環境によっては
# HTTP 403が返ることが報告されている。ブラウザ相当のUAを明示しておくと
# 弾かれにくい。学術用途等で正体を表明する場合は、連絡先を含むカスタムUA
# (例: YourOrgBot/1.0 (+https://example.com/contact))も検討する
"User-Agent": (
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/124.0.0.0 Safari/537.36"
),
}
def fetch_listing(url: str) -> BeautifulSoup:
resp = requests.get(url, headers=HEADERS, timeout=30)
resp.raise_for_status()
return BeautifulSoup(resp.content, "html.parser")
def parse_building(building) -> dict:
"""建物単位の情報(建物名・所在地・最寄駅・築年数)を抽出する"""
title = building.select_one(".cassetteitem_content-title")
label = building.select_one(".cassetteitem_content-label")
address = building.select_one(".cassetteitem_detail-col1")
stations = [
s.get_text(strip=True)
for s in building.select(".cassetteitem_detail-col2 .cassetteitem_detail-text")
]
age_floors = building.select_one(".cassetteitem_detail-col3")
return {
"building_name": title.get_text(strip=True) if title else "",
"category": label.get_text(strip=True) if label else "",
"address": address.get_text(strip=True) if address else "",
"stations": stations,
"age_floors": age_floors.get_text(" ", strip=True) if age_floors else "",
}
def parse_room(row) -> dict:
"""部屋単位の情報(家賃・管理費・敷礼・間取り・面積・詳細URL)を抽出する"""
rent = row.select_one(".cassetteitem_price--rent")
admin = row.select_one(".cassetteitem_price--administration")
deposit = row.select_one(".cassetteitem_price--deposit")
gratuity = row.select_one(".cassetteitem_price--gratuity")
madori = row.select_one(".cassetteitem_madori")
menseki = row.select_one(".cassetteitem_menseki")
link = row.select_one("a.js-cassette_link_href.cassetteitem_other-linktext")
return {
"rent": rent.get_text(strip=True) if rent else "",
"admin_fee": admin.get_text(strip=True) if admin else "",
"deposit": deposit.get_text(strip=True) if deposit else "",
"gratuity": gratuity.get_text(strip=True) if gratuity else "",
"layout": madori.get_text(strip=True) if madori else "",
"area": menseki.get_text(strip=True) if menseki else "",
"detail_url": (
"https://suumo.jp" + link["href"] if link and link.get("href") else ""
),
}
def main():
soup = fetch_listing(URL)
buildings = soup.select("div.cassetteitem")
print(f"建物件数: {len(buildings)}")
for building in buildings:
building_info = parse_building(building)
rooms = building.select("tr.js-cassette_link")
for row in rooms:
room_info = parse_room(row)
print({**building_info, **room_info})
if __name__ == "__main__":
main()このコードを実行すると、1ページ目に表示されている建物ごとに、各部屋の情報をフラットなdictとして出力します。1建物に部屋が3つあれば、出力は3行になります。CSV保存や分析に流す場合は、このdictをpandas.DataFrame や csv.DictWriter に渡すだけです。
ページネーションを回す
SUUMOの賃貸一覧は、URLのpage パラメータでページ番号を指定します。総ページ数は、ページネーション要素div.pagination_set-navの中の最大ページ番号から取得できますが、ページ数が固定でない検索条件もあるため、「次へ」が存在する間は次ページに進む実装が無難です。
from urllib.parse import urlparse, parse_qsl, urlencode, urlunparse
def with_page(url: str, page: int) -> str:
parts = list(urlparse(url))
query = dict(parse_qsl(parts[4]))
query["page"] = str(page)
parts[4] = urlencode(query)
return urlunparse(parts)
def has_next(soup: BeautifulSoup) -> bool:
"""ページネーション末尾に『次へ』リンクがあるか判定する"""
pagination = soup.select_one("div.pagination_set-nav")
if not pagination:
return False
# 「次へ」は最後の <p class="pagination-parts"> > a に入る
last_link = pagination.select("p.pagination-parts a")
return any("次へ" in a.get_text() for a in last_link)
def crawl_all_pages(base_url: str, max_pages: int = 5):
"""最大 max_pages ページまで巡回する。本番では十分なsleepを入れる"""
for page in range(1, max_pages + 1):
url = with_page(base_url, page)
soup = fetch_listing(url)
yield page, soup
if not has_next(soup):
print(f"page={page} で『次へ』が消えた。終了。")
break
# SUUMOのrobots.txtはbingbotにCrawl-delay: 30 を要求している
# 公開ページ向けの明示シグナルではないが、運営側の期待値として参考にする
time.sleep(random.uniform(10, 20))CSVに保存する
取得したdict列を、標準ライブラリのcsv.DictWriter に流すだけで保存できます。Excelで開く前提ならencoding="utf-8-sig"(BOM付きUTF-8)にしておくと文字化けしません。
import csv
FIELDS = [
"building_name", "category", "address", "stations", "age_floors",
"rent", "admin_fee", "deposit", "gratuity",
"layout", "area", "detail_url",
]
def save_csv(rows: list[dict], path: str = "suumo.csv") -> None:
with open(path, "w", newline="", encoding="utf-8-sig") as f:
writer = csv.DictWriter(f, fieldnames=FIELDS)
writer.writeheader()
for row in rows:
# stationsはリストなのでセミコロン区切りに整形
row = {**row, "stations": ";".join(row.get("stations", []))}
writer.writerow(row)動かない時のチェックリスト
最小実装でつまずいた場合、次の順序で原因を切り分けます。
- HTTPステータスコードを確認:
resp.status_codeが 200以外なら、まずそこを潰す。403ならUser-Agent・IP・Cookieの組み合わせを疑う、429ならリクエスト頻度を下げる - HTMLが想定通り返っているか確認:
print(resp.text[:2000])でHTMLの冒頭を見る。エラーページや空ページが返っていればアクセス側の問題 - セレクタが現行構造と一致しているか確認:Chromeの開発者ツールで実際のクラス名を確認し、コード内のセレクタと突き合わせる。SUUMOはA/Bテストや定期改修でクラス名が変わる可能性がある
- カードは取れるが空文字になる場合:セレクタは合っているが、子要素がさらに深くネストしている可能性。
building.prettify()で整形出力して構造を再確認する
スクレイピング時の技術的な注意点
仮にSUUMOへスクレイピングを実施する場合(個人の学習用途等)、最低限押さえておくべき技術的な配慮事項を整理します。これらは「適法にする」ためのものではなく、「最低限のマナーラインを越えないため」のチェックリストです。
リクエスト間隔(sleep)の設計
SUUMOのrobots.txtはbingbotに対してCrawl-delay: 30(30秒間隔)を明示しています。これを参考値として、人間がブラウザで操作するペースを大きく超えない間隔(最低でも数秒、安全側なら10〜30秒)を取るのが現実的です。固定値だとパターン検知されやすいため、ランダムな揺らぎを加えるのも定石です。
import time
import random
# 例: 5〜15秒のランダムなインターバル
time.sleep(random.uniform(5, 15))User-Agentと正体表明
python-requests/2.x やcurl/8.xのデフォルトUAは、過去の検証記事で403ブロックの対象となるケースが報告されています(本記事執筆時の検証では通る環境もありましたが、保証はありません)。少なくともブラウザ相当のUAを指定しておく方が、IP・アクセスパターン等の他の要因で弾かれる確率を下げられます。ただし「ブラウザに偽装する」ことは検知回避に近い設計であり、紛争時の説明責任が重くなります。学術研究や許諾調整中の調査であれば、連絡先を含むカスタムUA(例:YourOrgBot/1.0 (+https://example.com/contact))で正体を明らかにする方が誠実です。
robots.txtとCrawl-delayの遵守
robots.txtは法的拘束力を持つものではありませんが、これを無視するとサーバー負荷面でも紛争時の説明面でも不利になります。Pythonであればurllib.robotparser、Node.jsであればrobots-parser 等のライブラリで、自動的にチェックする設計が安全です。
取得頻度と並列度
sleep間隔と同等に重要なのが、同時並列リクエスト数です。10並列で1秒sleepすれば、サーバーから見れば0.1秒間隔と同じです。SUUMOのような大規模サイトでも、特定IPからの同時並列は明確な異常パターンとして検知されます。並列度は1〜2に抑え、必要なら複数日に分けて取得する設計が現実的です。
プロキシの利用判断
IP単位の遮断対策として、プロキシ(IPローテーション)を使う設計案が一般的に存在します。Bright Data、Decodo、Octoparseなどの商用プロキシサービスは数百万〜数千万単位の住居用IPを提供しており、検知される前にIPを切り替えながらアクセスする運用が可能です。一見すると「これで永久に取れる」と見えますが、技術的・法的に注意点があります。
まずプロキシは「検知回避を目的とした技術」と評価される側面があります。SUUMOのように利用規約で自動取得を実質禁止しているサイトに対して、プロキシでIPローテーションして突破する設計は、紛争時に「故意の検知回避」と評価されやすく、説明責任が重くなります。著作権法30条の4の「権利者の利益を不当に害する場合」に該当する余地も大きくなります。
プロキシが有効な典型シーンは、許諾済みのアクセス(運営側と契約・了承を得ている場合)で実IPだけでは取得帯域が足りないケース、地理的制約のあるサイトに正規ルートでアクセスする場合(海外IPが必要等)、自社所有サイトの監視を多地点から行うケースなどです。一方、「規約上グレーなサイトを物量で押し切る」目的でプロキシを導入すると、紛争時の説明責任が重くなる方向に作用するため、設計の前にユースケースとリスクの整合を取っておくのが安全です。
各プロキシサービスの料金体系・対応国・実装方式の違いは、別記事で詳しく整理しています。
マナーの本質:ボット対策は「攻撃的なボット」だけでなく、「マナーを知らない初心者の善意のボット」も一緒に弾くように設計されています。意図がなくても挙動が悪ければ、結果は変わりません。プロキシで物量的に押し切る前に、対象サイトが本当にスクレイピング向きの取得経路なのかを再評価する方が、結果的に早道になることが多いです。
よくあるエラーと原因
実装中に遭遇するエラーは、原因がアンチボット対策由来か、ページ構造変更由来かで対処方針が大きく変わります。代表的な4ケースを整理します。
HTTP 403 Forbidden
よくある原因の一つが、User-Agentが python-requests/2.x やcurl/8.x のデフォルト値のままであるケースです。ブラウザ相当のUAを設定することで解消することが多いです。ただしSUUMOのbot検知はUA単独ではなく、IPアドレス・直前のアクセスパターン・Cookieなど複数シグナルの組み合わせで動的に判定される構造のため、UAを変えても403が返る場合は、IP単位でブロックされている、Refererや特定のCookieが要求されている、短時間にアクセスを集中させすぎたなど他の要因を疑う必要があります。同じUAでも、別のIPからは通る・1日空けたら通るというケースは珍しくありません。
HTTP 429 Too Many Requests
短時間に大量リクエストを送った場合に返されるレートリミットエラーです。同一IPからのリクエスト頻度を下げる以外に根本対処はありません。Retry-Afterヘッダーが付いている場合は、その秒数だけ待ってから再開してください。429が頻発する状態で押し切ると、IP単位の長期遮断に格上げされるリスクがあります。
HTTP 400 / 空レスポンス
パラメータ不正やUA不正の複合で返されることがあります。URLのクエリパラメータが不完全(例えばta=のような空値)、Cookieが未送信、必須ヘッダーが欠落しているといった原因が考えられます。ブラウザの開発者ツールで実際のリクエストを観察し、ヘッダー・Cookie・パラメータの差分を埋めるのが基本対処です。
HTMLが想定と違う・データが取れない
レスポンスは200で返るのに、目的の物件カードが空になっているケース。これはアンチボット対策由来ではなく、ページ構造の変更がほぼ全ての原因です。A/Bテスト用Cookie(r2abtest_cid)の値によってもDOM構造が変動するため、過去にハードコードしたCSSセレクタは早晩動かなくなります。XPathやセレクタを汎用的にする・複数のフォールバックを持たせるなどの設計が必要です。
用途別に検討したい代替・併用データソース
ここまで実装と運用の設計を見てきましたが、すべてのユースケースでスクレイピングが最適とは限りません。特に過去の取引価格・統計的なエリア分析・相場推定モデルの学習といった用途は、公的なオープンデータの方が安定的かつ低コストでまかなえることがあります。スクレイピングと代替データソースは「どちらかを選ぶ」関係ではなく、用途に応じて使い分け・併用するのが現実的です。
国土交通省 不動産情報ライブラリ(最有力候補)
2024年4月から国土交通省が運用しているデータポータルで、公式APIが提供されています。2025年6月時点で個人・法人合わせて3,000以上の利用申請があり、不動産データの「公的な入手ルート」として最有力です。
- 不動産取引価格情報(成約価格ベース)
- 地価公示・地価調査
- 都市計画情報・防災情報
- 人口集中地区(DID)データ(2025年8月追加)
- API利用は申請制(APIキー発行)、利用規約への同意が必要
注意点として、SUUMOに掲載されているような「いま売り出し中の物件」のリアルタイム情報は対象外です。提供されるのは過去の取引価格・地価評価といった統計データ中心になります。「相場感」「エリア分析」「価格予測モデルの学習データ」用途であれば、SUUMOから無理に取るよりも遥かに安定したデータが揃います。
住宅・土地統計調査などの公的データ
総務省統計局の住宅・土地統計調査は5年に一度、全国の住宅ストック・空き家・住宅取得意向などの統計を公表しています。物件単位ではなく地域単位の集計データですが、不動産マーケティングや政策研究の用途では十分です。e-Stat(政府統計の総合窓口)からダウンロードでき、API経由でも取得できます。
業者向け正規ルート(REINS・各社IR資料)
REINS(指定流通機構)は、宅地建物取引業者専用の物件情報データベースです。一般には非公開で、宅建業者として加入する必要があります。仲介・売買を業として行う場合は、こちらが事実上の標準データソースです。また、上場している不動産関連企業のIR資料(決算説明会資料・有価証券報告書)には、エリア別の成約件数・賃料動向などのマクロデータが含まれます。
取得ルート比較表
| 手段 | 合法性・規約 | データの安定性 | コスト | 向く用途 |
|---|---|---|---|---|
| SUUMOをスクレイピング | 規約・運用上リスク高 | 低(仕様変更・遮断リスク) | 無料(保守コスト大) | 個人の短期検証(非推奨) |
| 不動産情報ライブラリ | 規約同意・API申請ベース | 高(公的提供) | 無料 | 取引価格・地価分析、相場推定モデル |
| 住宅・土地統計調査 | 公的統計、利用自由 | 高(5年周期) | 無料 | マーケット規模調査、政策研究 |
| REINS | 宅建業者限定の正規利用 | 高(業界標準) | 業者登録費用 | 仲介・売買業務 |
| データ提供元への個別許諾 | 契約に基づき条件明確化 | 高(契約次第) | 交渉次第 | 商用・再配布・長期運用 |
使い分けの目安:用途が「相場推定」「価格予測モデル」「エリア分析」など過去・統計データ中心であれば、不動産情報ライブラリ+住宅・土地統計調査で大部分の入力データが揃います。一方で「いま掲載されている物件のリアルタイム情報」が要件に入る場合は、SUUMOからの取得が技術的に最短ルートになることが多いので、本記事の実装パートで触れた配慮事項(sleep・User-Agent・並列度・規約解釈)を踏まえて設計するのが現実的です。
SUUMO含む不動産データのスクレイピング、実装まで進めませんか?
Wilicoでは、不動産・EC・メディアなど多様な領域でスクレイピング案件の要件整理・実装・運用監視・法務確認まで一貫してご支援しています。アンチボット対策の設計、構造変更時の保守、複数データソースの統合まで、自社内で抱え込まずに進めたい部分だけ切り出してお任せいただけます。
法務で押さえる4つの論点
スクレイピングの法的論点は、ひとつの法律だけで片付かないのが厄介な点です。代表的な4つの論点を、根拠条文と判例とセットで整理します。
著作権法とデータベース保護(30条の4を含む)
日本の著作権法では、「情報の選択又は体系的な構成によって創作性を有するデータベース」はデータベースの著作物として保護されます(著作権法12条の2)。SUUMOの物件データベースは、独自の項目設計(家賃・敷金礼金・専有面積・築年数等の組み合わせ)と検索体系を持つため、データベースの著作物として保護される可能性があります。
ただし、個々の物件情報(家賃◯万円、所在地◯区など)そのものは事実情報であり、著作権の対象外です。問題になるのは、データベース構造を丸ごと複製するような利用態様です。さらに、物件写真や物件説明文は通常の著作物として保護されるため、これらをそのまま転載することは別個の侵害になり得ます。
一方で、2018年改正で導入された著作権法30条の4は、「著作物に表現された思想又は感情の享受を目的としない利用」(情報解析等)について、権利者の許諾なく利用できると定めています。価格予測モデルの学習データとしてデータを処理する、エリアごとの相場分析を行う、といった情報解析目的の利用は、原則としてこの条項でカバーされます。ただし条文には「著作権者の利益を不当に害する場合」は適用外という但し書きがあり、SUUMOの代替サービスを作るような市場代替性のある利用は対象外と解されています。つまり、「自社の意思決定に使う情報解析」と「SUUMOと競合する公開サービスの構築」は別物として整理しておくと、本条項の恩恵を活かしやすくなります。
偽計業務妨害(刑法233条)と岡崎事件の教訓
偽計業務妨害は「虚偽の風説を流布し、又は偽計を用いて、人の信用を毀損し、又はその業務を妨害した者は、三年以下の懲役又は五十万円以下の罰金に処する」と定めています。スクレイピング文脈で必ず参照されるのが、岡崎市立中央図書館事件(2010年)です。
- 図書館の新着図書情報を取得するため、約1秒に1回というペースでクローラーを走らせた
- サーバー側のバグでアクセス障害が発生
- 偽計業務妨害容疑で逮捕、20日間勾留、最終的に起訴猶予
この事例から実務で学べるのは、攻撃意図の有無や「常識的な」アクセス間隔の設定だけでは刑事リスクを完全に排除できない、という点です。逆に言えば、アクセス頻度・サーバー応答時間の監視・障害発生時の即座な停止・運営側との対話チャネルの確保を設計に組み込めば、同種のリスクは大きく抑えられます。「相手のサーバー状態を観察しながら設計する」のがスクレイピング実装の基本作法、と捉えるのが現実的です。
個人情報保護法(仲介業者の連絡先が含まれる場合)
物件情報そのものは通常、個人情報には該当しません。しかしSUUMOの物件詳細ページには、仲介業者の担当者名・電話番号・店舗住所が含まれることがあります。これらは個人情報保護法における「個人情報」に該当し、取得・利用・第三者提供に法的規律がかかります。
- 個人情報の取得時には、利用目的を本人に通知または公表する必要がある(個情法17条・21条)
- 取得した個人情報を本来の目的を超えて利用する場合、本人の同意が必要
- 第三者提供(再配布・販売等)には別途同意が必要
スクレイピングで業者情報を含むデータベースを構築すると、これらの規律を満たさないまま個人情報を保有することになるため、特に注意が必要です。
不正競争防止法(限定提供データ)
2019年改正で導入された限定提供データ制度(不正競争防止法2条7項)は、特定の者に提供される業務上のデータを保護対象としています。要件は3つです。
- 限定提供性:業として特定の者に提供する情報
- 相当蓄積性:電磁的方法で相当量蓄積されている
- 電磁的管理性:ID/パスワード等で管理されている
重要なのは、不正競争防止法2条7項の括弧書きに「無償で公衆に利用可能となっている情報」を除外する規定があることです。SUUMOの一般公開ページは無料・無認証でアクセスできるため、通常は限定提供データには該当しません。会員限定・ログイン裏側のデータがあれば話は変わります。
「robots.txtでDisallowされていない=合法」「規約に書いていない=自由」という単純図式ではありません。規約(契約)・著作権(著作物性とデータベース保護)・刑事(業務妨害)・個情法・不競法を、利用態様ごとに別個に検討する必要があります。 個人学習・少量取得は、規約第2条(私的利用の範囲)と運用上のサーバー負荷の両面で、実務上問題視されにくいゾーンです。ただし「個人利用なら何をしても良い」わけではなく、サーバーへの負荷をかけない設計(sleepを十分に取る、並列度を上げない、深夜帯を避ける)と、取得データを再配布・公開しない運用を組み合わせることが前提になります。再現可能なスクリプトとして組む場合は、本記事の技術的な注意点セクションで触れた配慮事項を入れておくと安心です。 ヘッドレスブラウザで人間の操作を模倣しても、規約上の「自動化されたアクセス」「運営を妨げる行為」に該当する余地は変わりません。むしろ、検知回避に近い設計は紛争時の説明責任が重くなります。技術的にバレないことと、適法であることは別の話です。 コンシューマ向けの公式APIは公開されていません。リクルートグループの不動産事業者向けサービス(SUUMOビジネスインフォ等)は契約ベースで、個人開発者が利用できるものではありません。物件のリアルタイム情報を一般向けに提供する公式ルートは、2026年5月時点で存在しないと考えてください。 まずUser-Agentの設定を確認してください。curlやpython-requestsの標準UAでHTTP 403が返るケースは過去にも複数報告されています。UAがブラウザ相当でも動かない場合、IPアドレスがレピュテーション悪化で弾かれている可能性、ページがJavaScriptレンダリングに変わった可能性、HTML構造(クラス名・DOM)が変わった可能性、Cookieやセッション処理が必要になった可能性などが考えられます。サイト側の検知ロジックは段階的に強化されるため、過去動いた事実は将来の動作保証になりません。 「外部公開しなければ完全に問題ない」と言い切るのは難しいですが、社内分析用途は著作権法30条の4(情報解析の権利制限)の適用余地がある領域です。価格予測モデルの学習、エリアごとの相場分析、社内意思決定のための統計処理などは、原則としてこの条項の射程に入ります。一方で、SUUMOと競合する公開サービスを作るような市場代替性のある利用は適用外です。社内利用であっても、規約第3条(7)(商業目的利用)との関係で、取得規模・頻度・利用態様を文書化しておくと紛争時の説明がしやすくなります。 「これなら安全」という公式の閾値はありません。SUUMOのrobots.txtはbingbotに対してCrawl-delay:30(30秒間隔)を明示しています。これは運営側がbotに期待する間隔のシグナルと読めます。スクレイピングを実施する場合は最低でも数秒〜数十秒のインターバルを取り、ランダムな揺らぎを加え、深夜帯を避けるなどの配慮が現実的です。ただし間隔を空ければ適法というわけではない点に注意してください。 本記事は一般的な技術・法務観点の整理であり、個別案件の適法性や契約解釈の最終判断ではありません。商用利用・大規模収集・再配布が絡む場合は、必ず利用規約の原文確認と、必要に応じて弁護士への相談を行ってください。記載のSUUMOの仕様・規約・アンチボット動作・HTMLクラス名等の情報は、いずれも2026年5月時点で確認したものです。SUUMOのDOM構造・規約条項・robots.txt・アンチボット挙動は、運営側の都合により予告なく変更される可能性があるため、本記事公開後に時間が経過してから参照する場合は、必ず最新情報を一次ソース(公式サイト・実機)で再確認してください。よくある質問
個人利用・少量なら問題ない?
SeleniumやPlaywrightなどブラウザ自動化なら大丈夫?
SUUMOに公式APIや、データ提供サービスはある?
過去に動いていたスクレイピングコードが急に動かなくなった
取得した物件データを社内分析だけに使うのは合法?
sleepは何秒に設定すべき?
まとめ
免責事項・情報の鮮度について