
本文详解如何通过 selenium 精准定位并点击动态生成的楼层导航元素,等待真实内容加载完成,从而可靠抓取隐藏在 javascript 渲染后的公寓单元信息(如房号、户型、面积、价格等),避免因 dom 未就绪导致“无可用房源”的误判。
本文详解如何通过 selenium 精准定位并点击动态生成的楼层导航元素,等待真实内容加载完成,从而可靠抓取隐藏在 javascript 渲染后的公寓单元信息(如房号、户型、面积、价格等),避免因 dom 未就绪导致“无可用房源”的误判。
在爬取类似 https://www.php.cn/link/c7fddc94d0081819e0e6153ff2f9fb09 这类高度依赖前端 JavaScript 渲染的房产页面时,常见误区是仅等待元素“存在”(presence_of_element_located)就执行点击或读取操作——但此时页面可能尚未完成状态切换与数据渲染,导致 #unit-list-items 中仍为空或显示默认提示语。
关键问题在于:
- 页面使用 Swiper 轮播组件实现楼层导航,点击 标签后需触发 JS 逻辑更新右侧单元列表;
- data-js-hook="available-unit-count" 的 显示实时可租单元数,是判断该楼层是否值得点击的可靠依据;
- 必须等待目标单元列表 真正可见且非空(而非仅存在),才能安全提取数据。
以下为经过验证的完整解决方案:
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
url = 'https://www.php.cn/link/c7fddc94d0081819e0e6153ff2f9fb09'
driver = webdriver.Chrome()
driver.maximize_window()
driver.get(url)
wait = WebDriverWait(driver, 10)
# 定位所有楼层标签(含 data-js-hook="available-unit-count" 的 span)
floors = wait.until(
EC.visibility_of_all_elements_located((By.CSS_SELECTOR, "#mobile-floor-carousel-list > a span[data-js-hook='available-unit-count']"))
)
for floor_span in floors:
# 获取该楼层的可租单元数(文本内容)
avail_count = floor_span.text.strip()
if not avail_count.isdigit() or int(avail_count) == 0:
continue
# 获取对应楼层号(父级 <a> 标签的 data-floor 属性)
floor_link = floor_span.find_element(By.XPATH, "./ancestor::a")
floor_num = floor_link.get_attribute("data-floor")
print(f"Floor: {floor_num}, Available units: {avail_count}")
# 点击楼层链接(确保元素可点击)
floor_link.click()
# 关键:等待单元列表项可见且至少有一个 </a><a> 元素(即真实数据已加载)
unit_links = wait.until(
EC.visibility_of_all_elements_located((By.CSS_SELECTOR, "#unit-list-items > a"))
)
for unit in unit_links:
# 提取单元文本信息(自动包含房号、户型、浴室数、面积、价格等)
print(unit.text.strip())
print("-" * 40)
print("\n" + "="*50 + "\n")</a>
✅ 核心优化点说明:
- 使用 visibility_of_all_elements_located 替代 presence_of_element_located:确保元素不仅存在于 DOM,而且实际渲染在视口内、尺寸非零;
- 直接定位 span[data-js-hook='available-unit-count'],避免 XPath 硬编码索引(如 a[11]),提升健壮性;
- 通过 .find_element(By.XPATH, "./ancestor::a") 安全获取父级链接,规避因 DOM 结构微调导致的定位失败;
- 在点击后,严格等待 #unit-list-items > a 可见——这是页面 JS 渲染完成的真实信号,比等待 #unit-list-items 容器本身更精准。
⚠️ 注意事项:
- 若页面启用反爬策略(如检测自动化工具),建议添加 options.add_argument('--disable-blink-features=AutomationControlled') 并配合 navigator.webdriver = false 注入脚本;
- 遇到频繁超时,可适当延长 WebDriverWait 超时时间(如设为 15 秒),或增加重试逻辑;
- 生产环境建议封装成函数,加入异常捕获(如 NoSuchElementException, TimeoutException)并记录日志。
此方案已实测稳定运行,能准确抓取全部有房楼层的结构化单元数据,为后续清洗与存储提供可靠基础。











