用Python的Selenium遍历元素列表提取图片,src提取11次后停止求助
Selenium循环提前终止问题排查与解决
针对你爬取OLX印尼汽车页面时,循环仅执行11次就停止的问题,主要从以下几个方向排查修复:
1. 页面动态加载未触发
OLX的商品列表采用滚动加载机制,初始页面仅渲染10-12个元素,后续元素需要滚动页面才会加载。你一开始获取的li_elements只有已渲染的11个,自然循环到第11次就结束。
解决办法:在获取列表元素前,先滚动页面到底部,等待新元素加载,重复操作直到元素数量不再增加:
url = "https://www.olx.co.id/mobil_c86" driver.get(url) last_height = driver.execute_script("return document.body.scrollHeight") while True: # 滚动到底部 driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") # 等待加载 time.sleep(3) # 检查新的高度 new_height = driver.execute_script("return document.body.scrollHeight") if new_height == last_height: break last_height = new_height # 现在再获取所有列表元素 ul_element = driver.find_element(By.CSS_SELECTOR, "ul[data-aut-id='itemsList']") li_elements = ul_element.find_elements(By.CSS_SELECTOR, "li[data-aut-id='itemBox']")
2. 元素失效导致异常终止
循环过程中,页面可能因动态更新(比如广告加载、列表刷新)导致之前获取的li_elements变成失效元素(StaleElementReferenceException),这类异常没被你的代码捕获,直接导致循环停止。
解决办法:
- 扩大异常捕获范围,覆盖常见的元素操作异常
- 每次循环前重新定位当前元素,避免使用缓存的旧元素
修改后的循环代码示例:
# 循环时基于索引,每次重新获取元素 for idx in range(len(li_elements)): time.sleep(3) # 重新获取当前索引的li元素,避免失效 try: li_element = ul_element.find_elements(By.CSS_SELECTOR, "li[data-aut-id='itemBox']")[idx] except StaleElementReferenceException: continue try: link_element = li_element.find_element(By.CSS_SELECTOR, "a") link = link_element.get_attribute("href") links.append(link) except (NoSuchElementException, StaleElementReferenceException): links.append(None) try: image_element = li_element.find_element(By.CSS_SELECTOR, "img") image_source = image_element.get_attribute("src") image_sources.append(image_source) except (NoSuchElementException, StaleElementReferenceException): image_sources.append(None)
3. 用显式等待替代固定sleep
固定time.sleep()稳定性差,可能导致元素未加载完成就执行操作引发异常。建议用WebDriverWait显式等待,提高代码可靠性:
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC # 等待列表容器加载完成 ul_element = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CSS_SELECTOR, "ul[data-aut-id='itemsList']")) ) # 循环内等待目标元素出现 link_element = WebDriverWait(li_element, 5).until( EC.presence_of_element_located((By.CSS_SELECTOR, "a")) )
内容的提问来源于stack exchange,提问作者abbym
相关产品推荐
相关产品推荐

