动态网页爬取问题:无法获取点击元素后生成的链接
问题解决:Selenium爬取里约热内卢活动场地详情链接
问题背景
需要爬取里约热内卢活动场地网站,获取各场地的详情页链接及位置信息。详情页链接未直接嵌入HTML,需模拟点击场地标题跳转后获取。尝试循环点击时遇到两个问题:
- 点击后获取的仍是原页面链接
- 第二次循环触发
ElementClickInterceptedException,提示元素被q-loading__backdrop遮挡
解决方案
1. 修复URL未更新问题
原代码中wait.until(EC.url_changes)未传入初始URL参数,Selenium无法识别需要等待的URL变化。需改为传递当前页面的初始URL,确保等待页面完成跳转。
2. 解决点击拦截与元素失效问题
- 页面返回后,遮罩层
q-loading__backdrop未完全消失就尝试点击,导致拦截,需等待该遮罩层不可见 - 提前一次性获取的元素列表,在页面返回后会变成失效元素(Stale Element),需每次循环重新定位元素
- 直接调用
click()可能遇到元素未完全加载的情况,需用WebDriverWait等待元素可点击后再操作
修改后的完整代码
from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.chrome.options import Options # 设置ChromeDriver路径 chrome_path = '/usr/local/bin/chromedriver' service = Service(executable_path=chrome_path) # 配置Chrome选项 options = Options() options.add_argument("--headless") options.add_argument("--disable-gpu") # 增加窗口大小,避免headless模式下元素定位问题 options.add_argument("--window-size=1920,1080") driver = webdriver.Chrome(service=service, options=options) url = "https://visit.rio/congressos-eventos/encontre-o-espaco-ideal" driver.get(url) wait = WebDriverWait(driver, 20) # 等待页面初始加载完成,等待场地列表容器出现 wait.until(EC.presence_of_element_located((By.XPATH, "//div[contains(@class, 'row') and contains(@class, 'venue-item')]"))) # 获取场地总数,用于循环 venue_count = len(driver.find_elements(By.XPATH, "//div[@class='col-12 text-h2']")) for i in range(venue_count): # 每次循环重新定位元素,避免stale element问题 venues = wait.until(EC.presence_of_all_elements_located((By.XPATH, "//div[@class='col-12 text-h2']"))) current_venue = venues[i] # 等待元素可点击,同时等待遮罩层消失 wait.until(EC.invisibility_of_element_located((By.CLASS_NAME, "q-loading__backdrop"))) wait.until(EC.element_to_be_clickable((By.XPATH, f"(//div[@class='col-12 text-h2'])[{i+1}]"))) # 获取场地名称 venue_name = current_venue.text print(f"场地名称: {venue_name}") # 点击场地标题 current_venue.click() # 等待URL变化 wait.until(EC.url_changes(url)) detail_url = driver.current_url print(f"详情链接: {detail_url}") # 这里可以添加获取位置信息的代码,比如定位地址元素 # location = wait.until(EC.presence_of_element_located((By.XPATH, "定位地址的XPATH"))).text # print(f"位置信息: {location}") # 返回列表页 driver.back() # 等待列表页加载完成,遮罩层消失 wait.until(EC.invisibility_of_element_located((By.CLASS_NAME, "q-loading__backdrop"))) wait.until(EC.presence_of_element_located((By.XPATH, "//div[@class='col-12 text-h2']"))) driver.quit()
关键优化点
- 每次循环重新定位场地元素,解决页面返回后元素失效问题
- 增加等待
q-loading__backdrop遮罩层消失的逻辑,避免点击拦截 - 正确传递
url_changes的参数,确保等待页面跳转完成 - 增加窗口大小配置,避免headless模式下元素不可见的问题
内容的提问来源于stack exchange,提问作者Bianca Flores
相关产品推荐
相关产品推荐

