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

如何防止Python Selenium点击存在但已禁用的页面元素

问题根因

现有代码的翻页判断逻辑存在三个明显缺陷,才会触发最后一页点击报错:

  1. 仅用is_displayed()判断下一页按钮状态,这个方法只能识别元素是否在可视区域渲染,无法识别元素的禁用状态。TripAdvisor最后一页的下一页按钮会保留在DOM中、正常可见,但会被添加disabled类名与禁用属性,此时强行调用click()必然触发交互异常。
  2. 下一页按钮元素在循环外仅获取一次,翻页后页面DOM刷新,预先存储的元素引用会失效,同时here变量在循环外赋值后从未更新,会直接导致死循环。
  3. 评论存储列表在循环内部初始化,最终只会保存最后一页的爬取结果,无法拿到全量评论。
修复逻辑
  • 将评论标题、评论内容的列表初始化移到循环外部,避免每翻一页就清空之前爬取的数据
  • 把下一页按钮的元素查找、状态判断逻辑移到循环内部,每次翻页后重新获取最新的DOM元素,避免引用失效
  • 替换原有可见性判断:检查下一页按钮是否存在,且元素class中不包含disabled标识、is_enabled()返回True时,才执行点击操作
  • 翻页后用显式等待替代固定时长sleep,等新一页的评论加载完成后再执行解析,提升爬取稳定性
  • 补充元素交互异常捕获,避免偶发的元素加载问题导致爬虫直接中断
修复后完整代码
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.common.exceptions import ElementNotInteractableException, StaleElementReferenceException, NoSuchElementException
from bs4 import BeautifulSoup
import time
import pandas as pd
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# 目标酒店URL
url = 'https://www.tripadvisor.com/Hotel_Review-g46833-d256905-Reviews-Knights_Inn_South_Hackensack-South_Hackensack_New_Jersey.html#REVIEWS'

driver = webdriver.Chrome()
driver.get(url)
wait = WebDriverWait(driver, 20)

# 存储全量评论的列表,移到循环外初始化
Titles = []
reviews = []

while True:
    # 等当前页评论加载完成
    wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, 'q.QewHA.H4._a')))
    time.sleep(1)
    soup = BeautifulSoup(driver.page_source, 'html.parser')

    # 解析当前页评论标题
    for title in soup.find_all('a', {'class': 'Qwuub'}):
        Titles.append(title.text.strip())
    # 解析当前页评论内容
    for review in soup.find_all('q', {'class': 'QewHA H4 _a'}):
        reviews.append(review.text.strip())
    
    # 每次循环重新获取下一页按钮,避免DOM刷新后元素引用失效
    try:
        next_btn = driver.find_element(By.CSS_SELECTOR, 'a.ui_button.nav.next.primary')
        # 判断按钮是否被禁用:class包含disabled、或者元素不可点击时直接终止循环
        btn_class = next_btn.get_attribute('class')
        if 'disabled' in btn_class or not next_btn.is_enabled():
            break
        # 按钮可用时执行点击
        next_btn.click()
        # 等待翻页后旧元素失效,确认新页面加载
        wait.until(EC.staleness_of(next_btn))
    except (NoSuchElementException, ElementNotInteractableException, StaleElementReferenceException):
        # 找不到按钮、按钮不可点、元素失效时直接终止循环
        break

# 结果导出
comment_dict = {'Review Title': Titles, 'Reviews/Feedback': reviews}
datafr = pd.DataFrame.from_dict(comment_dict)
datafr.to_csv('hotels1.855.csv', index=False, header=True)
driver.quit()

注:原代码中大量未使用的导入项已经清理,原硬编码的动态ID定位方式已经替换为稳定的CSS选择器,避免TripAdvisor动态生成组件ID导致定位失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 10:03:22