Python Selenium抓取doveconviene.it商品弹窗信息遇点击拦截问题
我想用Python脚本抓取doveconviene.it网站上的超市传单商品信息,比如Lidl、Eurospin、Penny这些品牌的传单。这些商品点击后会弹出模态框显示名称和价格,但模态框得点击商品才会加载内容。
我用Selenium遍历商品并点击时遇到了ElementClickInterceptedException错误,Chrome检查器选中的商品div没法点击。
商品HTML结构:
<div class = "css-0 e5l4rtr2"> <div class = "css-XXXXX e5l4rtr0"> <div role = "button"> </div> </div> <div class = "css-XXXXX e5l4rtr1"> <!-- Chrome检查器选中的Div --> </div> </div>
初始化页面代码:
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 options = webdriver.ChromeOptions() options.add_argument('--headless=new') # 以无头模式运行Chrome driver = webdriver.Chrome() driver.get("https://www.doveconviene.it/discount/penny/volantino/ultime-offerte-penny?flyerId=1117478&flyerPage=1") driver.maximize_window()
尝试点击元素的代码:
productDiv = WebDriverWait(driver, 5).until(EC.visibility_of_element_located((By.XPATH, "//div[contains(@class, 'e5l4rtr1')]"))) WebDriverWait(driver, 10).until(EC.invisibility_of_element_located(productDiv)) productDiv.click()
报错信息:
selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element
is not clickable at point (1331, 666).
我试过移除等待不可见元素的代码,也试过点击带role="button"的div,都没成功。请问该怎么实现需求?应该点击哪个元素触发模态框?
解决方案
1. 定位正确的可点击元素
从HTML结构来看,真正触发模态框的是嵌套在e5l4rtr0类div下的role="button"元素,而非你选中的e5l4rtr1 div。调整定位方式,直接锁定这个按钮:
product_button = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.XPATH, "//div[contains(@class, 'e5l4rtr0')]/div[@role='button']")) )
2. 绕过元素遮挡,用JavaScript执行点击
如果直接调用click()仍被拦截,说明元素被上层节点遮挡,此时可以用JavaScript强制触发点击,绕过Selenium的可见性校验:
driver.execute_script("arguments[0].click();", product_button)
3. 优化无头模式配置
无头模式下窗口尺寸默认较小,可能导致元素渲染位置异常,添加以下参数优化:
options = webdriver.ChromeOptions() options.add_argument('--headless=new') options.add_argument('--window-size=1920,1080') # 模拟桌面窗口尺寸 options.add_argument('--disable-gpu') options.add_argument('--no-sandbox') driver = webdriver.Chrome(options=options)
4. 等待模态框加载并提取数据
点击按钮后,必须等待模态框完全加载再提取信息,示例如下(需替换为实际的模态框元素选择器):
# 等待商品名称元素可见 product_name = WebDriverWait(driver, 10).until( EC.visibility_of_element_located((By.CSS_SELECTOR, ".modal-product-name")) ).text # 等待商品价格元素可见 product_price = WebDriverWait(driver, 10).until( EC.visibility_of_element_located((By.CSS_SELECTOR, ".modal-product-price")) ).text print(f"商品名称: {product_name}, 价格: {product_price}")
5. 遍历所有商品的注意事项
如果要遍历页面所有商品,需要先获取所有按钮元素,再逐个处理,避免页面刷新导致元素失效:
# 获取所有商品按钮 product_buttons = WebDriverWait(driver, 10).until( EC.presence_of_all_elements_located((By.XPATH, "//div[contains(@class, 'e5l4rtr0')]/div[@role='button']")) ) for button in product_buttons: driver.execute_script("arguments[0].click();", button) # 提取数据... # 关闭模态框(如果需要) close_btn = WebDriverWait(driver, 5).until(EC.element_to_be_clickable((By.XPATH, "//button[@aria-label='关闭']"))) close_btn.click()
内容的提问来源于stack exchange,提问作者Alessio Iacono

