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

如何用Selenium WebDriver/Python点击无超链接楼层并遍历获取信息

解决Selenium点击楼层元素失效的问题

问题背景

作为网页爬取新手,想要从指定页面获取可用公寓信息,计划用Selenium依次点击每个楼层提取动态数据(公寓编号、租金等),但当前代码的点击操作无法生效。

给出的楼层元素HTML结构:

<li id="floor-item-42349" role="option" aria-selected="false" aria-label="Floor 21 selected, 1 of 19 stories. 2 Units available." tabindex="-1" class="css-1ge3v7g-itemStyles">
    <span class="primary-font css-1an6fko-floorStyles">21</span>
    <span class="css-1cygnfi-countStyles">
        <span class="css-1gmg8q9-numberStyles">2</span>
        <span class="css-1c0jwqn-unitLabelStyles">Units</span>
    </span>
</li>

当前失效的代码:

floors = wait.until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, "#floor-vertical-select > li ")))
for floor in floors:
    if floor.text != "0":
        print("Floor: " + floor.text)
        floor.click()

失效原因分析

  1. 元素不可交互:楼层元素的tabindex="-1"意味着它默认不可被聚焦,普通的click()方法可能因为元素无法接收焦点而失效。
  2. Stale元素问题:点击楼层后页面动态更新,之前获取的floors列表可能变成过期元素,后续点击会报错。
  3. 元素未完全在视口内:楼层列表可能较长,部分元素不在当前视口,直接点击会失败。
  4. 选择器判断逻辑问题:floor.text != "0"的判断不准确,楼层文本是楼层号(比如21),可用单元数在子元素里,这个条件会过滤掉所有非0的楼层号,逻辑错误。

另外,aria-label是无障碍辅助标签,用于给屏幕阅读器提供描述,不是点击失效的关键,但可以用来提取楼层的额外信息(比如可用单元数)。

解决方案

修改后的代码示例

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time

# 初始化浏览器
driver = webdriver.Chrome()
driver.get("https://sightmap.com/embed/rx1p8y12vd6")
wait = WebDriverWait(driver, 10)

# 等待楼层选择器加载完成
wait.until(EC.presence_of_element_located((By.ID, "floor-vertical-select")))

# 获取楼层总数,避免循环中元素过期
floor_total = len(wait.until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, "#floor-vertical-select li"))))

for index in range(floor_total):
    # 每次循环重新定位所有楼层,防止元素过期
    floors = wait.until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, "#floor-vertical-select li")))
    current_floor = floors[index]
    
    # 提取楼层号和可用单元数
    floor_num = current_floor.find_element(By.CSS_SELECTOR, ".css-1an6fko-floorStyles").text
    available_units = current_floor.find_element(By.CSS_SELECTOR, ".css-1gmg8q9-numberStyles").text
    
    # 只处理有可用单元的楼层
    if available_units != "0":
        print(f"楼层: {floor_num},可用单元数: {available_units}")
        
        # 滚动到当前楼层元素,确保在视口内
        driver.execute_script("arguments[0].scrollIntoView({block: 'center'});", current_floor)
        time.sleep(0.5)  # 给页面滚动留缓冲时间
        
        # 使用JavaScript点击,绕过元素不可聚焦的限制
        driver.execute_script("arguments[0].click();", current_floor)
        
        # 等待当前楼层的公寓信息加载完成
        time.sleep(1)
        
        # 提取当前楼层的公寓信息
        units = wait.until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, "[class*='unitStyles']")))
        for unit in units:
            # 从aria-label提取公寓编号、户型等信息
            unit_info = unit.get_attribute("aria-label")
            # 提取租金(如果存在)
            rent_elem = unit.find_elements(By.CSS_SELECTOR, "[class*='priceStyles']")
            rent = rent_elem[0].text if rent_elem else "暂无租金信息"
            
            print(f"  公寓详情: {unit_info},租金: {rent}")

# 关闭浏览器
driver.quit()

关键优化点

  1. 重新定位元素:每次循环重新获取楼层列表,避免因页面更新导致的StaleElementReferenceException。
  2. JS点击替代普通点击:driver.execute_script("arguments[0].click();", element)可以绕过元素tabindex="-1"的不可聚焦限制,确保点击生效。
  3. 滚动到元素可见:用scrollIntoView将元素滚动到视口中央,避免因元素被遮挡导致点击失败。
  4. 修正判断逻辑:通过子元素提取可用单元数,只处理有可用公寓的楼层,避免无效点击。
  5. 利用aria-label提取信息:单元元素的aria-label通常包含公寓编号、户型等详细内容,可以直接提取使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 00:23:17