You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python爬取Airbnb多房源页面数据及可订状态?

Airbnb详情页数据爬取:设施、描述与可订状态实现方案

问题总结

你已经完成Airbnb搜索列表页的价格、名称、评分爬取,也掌握了分页获取房源链接的方法,现在需要:

  • 基于已有的房源链接,爬取每个详情页的房源描述、设施(比如睡眠区域)
  • 获取房源的可订状态

你尝试提取睡眠区域的代码因标签选择器不准确,未能拿到正确数据。

解决方案

1. 修正基础代码(避免重复初始化浏览器)

原代码重复初始化driver会打开多个浏览器窗口,先优化这部分:

from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from webdriver_manager.chrome import ChromeDriverManager
import pandas as pd
import time
import random

# 仅初始化一次浏览器
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
driver.maximize_window()

# 访问列表页获取房源链接
airbnb_url = 'https://www.airbnb.com/s/Thessaloniki--Greece/homes?tab_id=home_tab&flexible_trip_lengths%5B%5D=one_week&refinement_paths%5B%5D=%2Fhomes&place_id=ChIJ7eAoFPQ4qBQRqXTVuBXnugk&query=Thessaloniki%2C%20Greece&date_picker_type=calendar&search_type=unknown'
driver.get(airbnb_url)
time.sleep(5)  # 等待列表页加载完成

links = []
soup = BeautifulSoup(driver.page_source, 'lxml')
# 用更稳定的data属性选择器替代随机生成的class名
for card in soup.select('div[data-testid="card-container"]'):
    link_tag = card.select_one('a[href^="/rooms/"]')
    if link_tag:
        links.append('https://www.airbnb.com' + link_tag['href'])

2. 详情页核心数据爬取

用WebDriverWait替代固定延迟,提升稳定性;同时修正选择器适配Airbnb页面结构:

# 存储所有房源详情数据
all_property_data = []

for url in links:
    driver.get(url)
    # 等待详情页关键元素加载,避免空数据
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, "_14i3z6h")))
    
    soup = BeautifulSoup(driver.page_source, 'lxml')
    property_info = {}
    
    # 提取房源描述
    desc_section = soup.select_one('div[data-section-id="DESCRIPTION_DEFAULT"] div._14i3z6h')
    property_info['房源描述'] = desc_section.get_text(strip=True) if desc_section else '无描述'
    
    # 提取睡眠区域(设施分类)
    sleep_amenities = []
    amenities_section = soup.select_one('div[data-section-id="AMENITIES_DEFAULT"]')
    if amenities_section:
        # 遍历所有设施项,筛选睡眠相关内容
        for item in amenities_section.select('div._1fxyzhx'):
            item_text = item.get_text(strip=True)
            # 英文页面请替换为'bed'/'sleep'关键词
            if '床' in item_text or '睡眠' in item_text:
                sleep_amenities.append(item_text)
    property_info['睡眠区域'] = ', '.join(sleep_amenities) if sleep_amenities else '无睡眠区域信息'
    
    # 提取可订状态
    # 优先检查日历区域的可订提示
    availability_tag = soup.select_one('div[data-testid="booking-calendar"] span._1hxyyw3')
    if availability_tag:
        property_info['可订状态'] = availability_tag.get_text(strip=True)
    else:
        # 检查是否有不可预订的提示
        unavailable_tag = soup.select_one('div[data-testid="unavailable-message"]')
        property_info['可订状态'] = '不可预订' if unavailable_tag else '可预订'
    
    all_property_data.append(property_info)
    # 随机延迟,避免触发反爬机制
    time.sleep(random.randint(2, 4))

# 保存为CSV文件
df = pd.DataFrame(all_property_data)
print(df.head())
df.to_csv('airbnb_property_details.csv', index=False, encoding='utf-8-sig')

关键提示

  • 选择器优先用固定属性:Airbnb的class名是动态生成的,优先使用data-testid、data-section-id这类固定属性,比随机class更可靠
  • 反爬应对:频繁请求会被限制,建议添加随机延迟,必要时使用代理IP
  • 页面语言适配:如果是英文页面,把睡眠区域的筛选关键词改成bed/sleep,可订状态检查Available/Unavailable
  • 元素等待:尽量用WebDriverWait等待元素加载,替代固定延迟,效率更高且稳定

内容的提问来源于stack exchange,提问作者Lefteris Kyprianou

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 10:10:03