Tony Wang5 分で読めます2026年のAirbnbスクレイピング方法(API & Python)
2026年にAirbnbをスクレイピングする3つの方法 — 自前のPython、ノーコード、または検索・ルーム詳細・レビュー・空室状況を返す構造化API — を法的な基本とあわせて解説します。
2026年にAirbnbをスクレイピングする最速の方法は、AirbnbのJavaScriptやアンチボット対策をヘッドレスブラウザで突破するのではなく、正規化されたJSON(リスティング検索、ルーム詳細、レビュー、空室状況)を返す構造化されたAirbnb APIを呼び出すことです。自前のスクレイパーを作ることもできますが、AirbnbはWeb上でもっとも攻撃的に防御されているサイトの一つです。本ガイドでは3つのアプローチすべてについて、それぞれが何を返し、どこで壊れるのか、そして法的な基本を解説します。
なぜAirbnbをスクレイピングするのか?
短期賃貸データは、リサーチやプロダクトのまるごと一分野を支えています。
- マーケットインテリジェンス — 都市や地区ごとに供給量・宿泊単価・稼働率を追跡する。
- 収益・価格リサーチ — ホストや物件管理者向けに、類似リスティングや季節性をベンチマークする。
- 投資の採算評価 — 購入前に平均宿泊料と空室状況から利回りを見積もる。
- レビュー・センチメント分析 — ある市場全体でゲストが実際に何を語っているかを読む。
- 旅行・発見系プロダクト — 公開リスティングを対象に検索やレコメンドを動かす。
Airbnbのスクレイピングは合法か?
選択肢1: Pythonでの自前実装(そしてなぜ壊れるのか)
AirbnbはReactでリスティングをクライアントサイドにレンダリングし、攻撃的に防御しているため、ヘッドレスブラウザに手を伸ばすことになります。
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
page = p.chromium.launch().new_page()
page.goto("https://www.airbnb.com/s/Austin--TX/homes?checkin=2026-07-01&checkout=2026-07-05&adults=2")
# then wait for listing cards to render and parse the schema.org itemListElement blocks...
デモは動きますが、その後壊れます。AirbnbはWeb上でも屈指の難関ターゲットと評されています。
- Akamaiベースのボット対策。 Airbnbは挙動分析とフィンガープリンティングを備えた独自のWAFを運用しています。データセンターIPや素の
requestsではデータのない灰色の「スケルトン」ページが返るため、住宅用またはステルスなプロキシに加えてJavaScriptの完全なレンダリングが必要です。 - 頻繁に変わるCSSクラス名。 Airbnbはクラス名(例:
lxq01kf、atm_mk_h2mmj6)を自動生成し、予告なく変えるため、堅牢なスクレイパーはクラスセレクタを使えません。data-testid、schema.orgのitemprop、aria-labelのアクセシビリティ文字列に頼りますが、それらも変動します。 - データは内部のGraphQLの裏側にあります。 検索はAirbnbの
/api/v3/StaysSearch経由で、リスティング詳細は/api/v3/PdpPlatformSections経由で読み込まれるため、生のHTMLリクエストではプレースホルダーが返ります。ブラウザを動かすか、署名付きのGraphQL呼び出しをリバースエンジニアリングするかのどちらかです。 - 扱いにくいパラメータとロケール。 検索にはGoogleスタイルの
place_id、日付、items_offsetによるページネーション(1ページあたり約18件)が必要で、価格と評価はロケール固有のアクセシビリティテキストにしか現れません。そのためロケールを間違えると、静かにnullが返ってきます。
選択肢2: ノーコードツール
ビジュアル系の抽出ツールやマーケットプレイスの「Airbnbスクレイパー」アクターはCSV/JSONをエクスポートでき、単発の取得には向きます。しかし、フィールドが予測できるプロダクト内パイプラインには扱いにくく、同じレイアウトの変動で壊れます。
選択肢3: 構造化されたAirbnb API
繰り返し実行するワークフローには、AirbnbスクレイピングAPIが、動かすべきブラウザなしで正規化されたJSONを返します。地域で検索するには次のようにします。
curl "https://api.crawlora.net/api/v1/airbnb/search?location=Austin,%20TX&check_in=2026-07-01&check_out=2026-07-05&adults=2¤cy=USD" \
-H "x-api-key: $CRAWLORA_API_KEY"
PythonでルームIDから1件のリスティングの詳細を取得するには次のようにします。
import requests
room = requests.get(
"https://api.crawlora.net/api/v1/airbnb/room/964337233639659839",
headers={"x-api-key": "YOUR_API_KEY"},
).json()["data"]
print(room.get("title"), room.get("price"), room.get("rating"))
検索レスポンスはそのまま保存できる正規化されたJSONです(フィールドはあくまで例です。ドキュメントを確認してください)。
{
"code": 200,
"msg": "OK",
"data": {
"location": "New York, NY",
"page": 1,
"results": [
{
"id": "964337233639659839",
"title": "Cozy & Calm Studio",
"url": "https://www.airbnb.com/rooms/964337233639659839",
"image": "https://a0.muscache.com/image.jpeg",
"price": 717,
"rating": 4.47,
"review_count": 96,
"location": "Apartment in Union City",
"latitude": 40.77525,
"longitude": -74.02586
}
]
}
}
続いて各リスティングをエンリッチします。レビューと空室状況は同じルームIDで扱えます。
h = {"x-api-key": "YOUR_API_KEY"}
base = "https://api.crawlora.net/api/v1/airbnb"
results = requests.get(f"{base}/search", headers=h,
params={"location": "Austin, TX", "currency": "USD", "page": 1}).json()["data"]["results"]
room_id = results[0]["id"]
details = requests.get(f"{base}/room/{room_id}", headers=h).json()["data"]
reviews = requests.get(f"{base}/room/{room_id}/reviews", headers=h, params={"page": 1}).json()["data"]["reviews"]
calendar = requests.get(f"{base}/room/{room_id}/calendar", headers=h).json()["data"]["months"]
検索はpageでページネーションします。あなたの市場の通貨で価格を得るにはcurrencyを、実際の宿泊で価格を出すにはcheck_in/check_out/adultsを渡します。地図の範囲で絞った検索には、ne_lat/ne_lng/sw_lat/sw_lngのバウンディングボックスをzoomとともに設定します。レビューはpageでページネーションします。リスティングごとに1行を保存し、スケジュールに沿って再取得することで、価格と空室状況の推移を追跡できます。
収集できるもの
公開リスティングがそれらを露出している範囲で: ルームID、タイトル、リスティングURL、画像、宿泊単価、評価、レビュー件数、緯度・経度付きの所在地テキスト、ホスト、アメニティ、説明文。加えてリスティングごとのレビュー(投稿者、日付、評価、本文)。そしてカレンダーからの空室月。さらに、あなたがリクエストした検索やルームIDのコンテキストです。公開された事実フィールドにとどめてください。
制約とよくある課題
- 公開された公式APIがない。 Airbnbには一般向けのリスティングAPIがなく(そのAPIプログラムはパートナー限定です)、任意の公開リスティングを収集するにはスクレイピングが必要です。
- 屈指の難関ターゲット。 AkamaiベースのWAF、クライアントサイドのGraphQL、頻繁に変わるクラス名のため、自前実装にはステルスな住宅用プロキシ、本物のブラウザ、そして絶え間ないセレクタのメンテナンスが必要です。構造化APIは、これらを1つのキーの裏側で吸収します。
- 価格は動的で日付依存。 宿泊単価は日付、ゲスト数、宿泊日数、需要によって変わるため、
check_in/check_out/adultsを渡し、スケジュールに沿って再取得してください。指定した日付で価格がないリスティングはnullを返します。 - レビューとホスト名は個人データ。 投稿者名とレビュー本文はGDPR/CCPAのもとで個人データとして扱ってください。適法な根拠のもとで公開された事実フィールドのみを収集し、著作権のある写真や説明文を再掲載しないでください。
どこで使われているか
- 旅行・ホスピタリティ研究 — 市場をまたいでリスティング、価格、空室状況を追跡する。旅行・ホスピタリティ研究のユースケースをご覧ください。
- 不動産マーケットインテリジェンス — 短期賃貸の供給を、より広い住宅データと組み合わせる。不動産マーケットインテリジェンスをご覧ください。
- レビュー・レピュテーション監視 — レビュー・レピュテーション監視で、市場全体のゲストのセンチメントを読む。
出典
収集を始める
まずは無料で試す: 任意の公開URLを無料Webスクレイパーで実行するか、アンチボットチェッカーでサイトがボットをブロックするかどうかを確認できます。サインアップは不要です。
プレイグラウンドで検索エンドポイントを試し、APIドキュメントでスキーマを確認し、料金を確認してください。あわせて、物件側についてはZillowのスクレイピング方法、レビューの観点についてはTrustpilotのレビューのスクレイピング方法、WebスクレイピングAPIの選び方、そしてWebスクレイピングは合法かもご覧ください。
よくある質問
ブロックされずにAirbnbをスクレイピングできますか?
AirbnbはWeb上でも屈指の難関ターゲットです。挙動分析とフィンガープリンティングを備えたAkamaiベースのWAFを運用し、リスティングをクライアントサイドでレンダリングし、CSSクラス名を頻繁に変えるため、素のリクエストやデータセンターIPではデータのない灰色のスケルトンページが返ります。自前実装にはステルスな住宅用プロキシ、本物のブラウザ、そして絶え間ないセレクタの手入れが必要です。構造化APIは、プロキシとブラウザ実行を1つのキーの裏側で処理します。
Airbnbに公式APIはありますか?
公開されたものはありません。AirbnbのAPIプログラムはパートナー限定のため、任意の公開リスティングを収集するにはスクレイピングが必要です。CrawloraのAirbnbエンドポイントは、公開の検索・ルーム詳細・レビュー・空室状況を、1つのAPIキーから正規化されたJSONとして返します。
どんなAirbnbデータを収集できますか?
公開されているリスティングのフィールド: ルームID、タイトル、リスティングURL、画像、宿泊単価、評価、レビュー件数、緯度・経度付きの所在地、ホスト、アメニティ、説明文。加えてリスティングごとのレビュー(投稿者、日付、評価、本文)と空室月です。価格や所在地のような事実はリスクが最も低く、写真や説明文は著作権の対象になり得ます。
あるリスティングのレビューと空室状況はどうやって取得しますか?
地域を検索して(または既知のルームIDから始めて)リスティングIDを取得し、詳細には/airbnb/room/{id}、ゲストのレビューには/airbnb/room/{id}/reviews(pageでページネーション)、空室月には/airbnb/room/{id}/calendarを呼び出します。
別の都市を検索したり日付範囲を指定したりできますか?
はい。locationに加えてcheck_in/check_out/adultsとcurrencyを渡し、pageでページネーションします。厳密なエリア指定には、都市名の代わりにne_lat/ne_lng/sw_lat/sw_lngの地図バウンディングボックスをzoomとともに設定します。
Airbnbのレビューやホスト名は個人データですか?
はい。投稿者名やホスト名、レビュー本文はGDPR/CCPAのもとで個人データにあたります。適法な根拠のもとで公開された事実フィールドのみを収集し、著作権のある写真や説明文を再掲載しないでください。
どのくらいの頻度で更新できますか?
宿泊単価と空室状況は日付や需要によって変わるため、継続的にポーリングするのではなく、プランと責任ある利用の範囲内でスケジュールに沿って再取得してください。