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

Python Selenium点击速卖通商品遇ElementClickInterceptedException问题求助

速卖通商品点击ElementClickInterceptedException异常排查与解决

问题场景

尝试点击速卖通搜索结果中的每个商品执行后续操作,但反复触发ElementClickInterceptedException异常。

已尝试的代码实现

方案一

for supplier in suppliers:
    driver.execute_script("arguments[0].scrollIntoView();", supplier)
    actions = ActionChains(driver)
    actions.move_to_element(supplier).click().perform()

for supplier in suppliers:

    driver.execute_script("arguments[0].scrollIntoView();", supplier)
    actions = ActionChains(driver)
    actions.move_to_element(supplier)

    wait.until(EC.visibility_of_element_located((By.XPATH, ".//*[@class='list--gallery--34TropR']//span/a")))

    try:
        supplier.click()
    except ElementClickInterceptedException:
        print('object not on screen')

方案二

for supplier in suppliers:
    try:
        supplier.click()
        print('Supplier clicked')
        time.sleep(1)
    except ElementClickInterceptedException:
        print('object not on screen')

驱动初始化及元素加载代码

search_key = "Motor+toy+boat"

suppliers = []

print("https://www.aliexpress.com/premium/"+search_key+".html?spm=a2g0o.best.1000002.0&initiative_id=SB_20221218233848&dida=y")

# create a webdriver object and set the path to the Chrome driver
service = Service('../venv/chromedriver.exe')
driver = webdriver.Chrome(service=service)

# navigate to the Aliexpress website
driver.get("https://www.aliexpress.com/")

# Wait for the page to load
wait = WebDriverWait(driver, 10)
wait.until(EC.presence_of_element_located((By.ID, "search-key")))

# wait for the page to load
driver.implicitly_wait(10)

driver.get("https://www.aliexpress.com/premium/"+search_key+".html?spm=a2g0o.best.1000002.0&initiative_id=SB_20221218233848&dida=y")

last_height = driver.execute_script("return document.body.scrollHeight")

while True:
    driver.execute_script("window.scrollBy(0, 800);")
    sleep(1)
    new_height = driver.execute_script("return document.body.scrollHeight")
    if new_height == last_height:
        print(new_height, last_height)
        break
    last_height = new_height

for element in driver.find_elements(By.XPATH, "//*[contains(@class, 'manhattan--container--1lP57Ag cards--gallery--2o6yJVt')]"):
    suppliers.append(element)

问题排查与解决方法

核心问题分析

  1. 元素定位偏差:当前定位的是商品外层容器,而非页面设计中真正可交互的点击区域(如商品图片/标题链接),点击容器容易被内部元素或遮罩层拦截。
  2. 滚动加载逻辑不可靠:仅通过页面滚动高度判断加载完成,无法适配速卖通的动态加载机制,可能导致部分商品未完全加载就停止滚动。
  3. 未处理弹窗干扰:速卖通页面频繁出现登录弹窗、优惠券弹窗,这些遮罩层会直接拦截点击操作,原代码无对应处理逻辑。
  4. 等待逻辑缺失:滚动到元素后未等待元素进入可点击状态,直接点击容易触发异常。

修正后的可行代码

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
from selenium.webdriver.common.action_chains import ActionChains
from selenium.common.exceptions import ElementClickInterceptedException, NoSuchElementException
import time
from selenium.webdriver.chrome.service import Service

search_key = "Motor+toy+boat"
suppliers = []

# 初始化驱动并最大化窗口
service = Service('../venv/chromedriver.exe')
driver = webdriver.Chrome(service=service)
driver.maximize_window()
wait = WebDriverWait(driver, 15)

# 访问目标搜索页面
driver.get(f"https://www.aliexpress.com/premium/{search_key}.html?spm=a2g0o.best.1000002.0&initiative_id=SB_20221218233848&dida=y")

# 关闭页面弹窗(登录/优惠券弹窗)
def close_popups():
    try:
        # 关闭登录弹窗
        close_btn = wait.until(EC.element_to_be_clickable((By.XPATH, "//div[@class='close-icon']")))
        close_btn.click()
        time.sleep(1)
    except (NoSuchElementException, ElementClickInterceptedException):
        pass
    try:
        # 关闭优惠券弹窗
        coupon_close = wait.until(EC.element_to_be_clickable((By.XPATH, "//button[@class='btn-close']")))
        coupon_close.click()
        time.sleep(1)
    except (NoSuchElementException, ElementClickInterceptedException):
        pass

# 滚动加载所有商品(通过商品数量判断是否加载完成)
last_product_count = 0
while True:
    close_popups()
    # 滚动至页面底部
    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
    time.sleep(2)
    # 获取当前已加载的商品链接数量
    current_products = driver.find_elements(By.XPATH, "//a[@class='manhattan--imgLink--1ITo7AG']")
    if len(current_products) == last_product_count:
        break
    last_product_count = len(current_products)

# 定位真正可点击的商品链接元素
suppliers = driver.find_elements(By.XPATH, "//a[@class='manhattan--imgLink--1ITo7AG']")

# 逐个点击商品并处理后续逻辑
for index, supplier in enumerate(suppliers):
    try:
        close_popups()
        # 滚动到元素并居中显示,避免被页面边缘遮挡
        driver.execute_script("arguments[0].scrollIntoView({block: 'center'});", supplier)
        # 等待元素进入可点击状态
        wait.until(EC.element_to_be_clickable(supplier))
        # 使用ActionChains模拟真实点击
        ActionChains(driver).move_to_element(supplier).click().perform()
        print(f"第{index+1}个商品点击成功")
        
        # 这里添加你的后续操作逻辑
        time.sleep(2)
        
        # 返回商品列表页并等待页面加载完成
        driver.back()
        wait.until(EC.presence_of_element_located((By.XPATH, "//a[@class='manhattan--imgLink--1ITo7AG']")))
    except ElementClickInterceptedException:
        # 若仍被拦截,使用JS强制点击
        driver.execute_script("arguments[0].click();", supplier)
        print(f"第{index+1}个商品通过JS点击成功")
        time.sleep(2)
        driver.back()
        wait.until(EC.presence_of_element_located((By.XPATH, "//a[@class='manhattan--imgLink--1ITo7AG']")))
    except Exception as e:
        print(f"第{index+1}个商品点击失败: {str(e)}")
        continue

driver.quit()

关键优化点

  • 精准定位可交互元素:直接定位商品的图片链接(速卖通页面中设计为可点击的核心区域),避免点击无效容器。
  • 弹窗自动处理:新增弹窗关闭逻辑,提前清除可能拦截点击的遮罩层。
  • 可靠的滚动加载:通过对比商品数量判断加载状态,比滚动高度更适配动态加载机制。
  • 多重点击策略:先模拟真人点击,失败则用JS强制点击,覆盖更多异常场景。
  • 页面切换后的等待:返回列表页后等待元素重新加载,确保后续操作的稳定性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 23:40:32