Selenium爬取表格商品首项后触发NoSuchElementException报错问题
问题根因
定位失败的核心原因是定位方式使用错误,具体如下:
By.CLASS_NAME定位器只支持传入单个类名,或是空格分隔的多个类名,不支持CSS选择器语法的点(.)拼接多类名写法。你代码里所有带.的多类名参数传进去后,Selenium会把包含.的整个字符串当做一个完整的类名去匹配,和元素实际的class属性完全不对应。- 首个商品能提取成功是特殊情况:该站点列表第一个位置是付费推广位,DOM结构和后续普通商品位有细微差异,刚好被你错误的定位规则误命中,后续普通商品位匹配不到对应元素,自然抛出
NoSuchElementException。 - 还有一处隐患:页面打开后没有等待加载完成就直接提取元素,可能拿到不完整的元素列表,遍历过程中也容易触发异常。
修复方案
- 所有多类名的定位场景,统一换用
By.CSS_SELECTOR定位器。CSS选择器原生支持点拼接多类名的写法,匹配逻辑和你预期的完全一致,只要在原有类名参数前加一个.代表类选择器即可。 - 增加显式等待逻辑,等页面表格主体完全加载后再提取元素,避免页面未渲染完成导致的匹配失败。
修正后可运行代码
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 driver = webdriver.Chrome() url = 'https://www.cardmarket.com/en/Pokemon/Products/Boosters' driver.get(url) wait = WebDriverWait(driver, 10) # 等待表格主体加载完成 table_body = wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'table-body'))) # 改用CSS选择器定位商品行 products = table_body.find_elements(by=By.CSS_SELECTOR, value='.row.no-gutters') for product in products: # 所有子元素定位统一改用CSS选择器 name = product.find_element(by=By.CSS_SELECTOR, value=".col-12.col-md-4.px-2.flex-column.align-items-start.justify-content-center") start_price = product.find_element(by=By.CSS_SELECTOR, value=".col-price.pr-sm-2") availability = product.find_element(by=By.CSS_SELECTOR, value=".col-availability.px-2") print(name.text, start_price.text, availability.text) driver.quit()
额外说明
如果运行时发现页面靠后的商品提取失败,是因为站点做了滚动懒加载,在遍历商品前增加页面滚动操作,等所有商品项都渲染到DOM树后再提取数据即可。
内容的提问来源于stack exchange,提问作者Jimmy Wilson
相关产品推荐
相关产品推荐

