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

Python Selenium:多次循环后WebDriverWait崩溃问题求助

问题描述

我尝试爬取某网页的所有分类内容,流程是点击分类按钮,等待分类内容显示后进行爬取。用以下代码实现等待逻辑:

driver = webdriver.Chrome()

driver.get('https://xxxxxxxxxx.com/xxxxxxx')

content = driver.page_source
soup = BeautifulSoup(content)

categories = driver.find_elements(By.XPATH, "//li[@data-yy='category']")

for category in categories:
  category.click()

  WebDriverWait(driver, timeout=30, poll_frequency=2).until(EC.visibility_of_element_located((By.XPATH, "//div[@data-yy='item']")))

  content = driver.page_source
  soup = BeautifulSoup(content)

  # 后续的BeautifulSoup处理代码...

这段代码处理前15个分类时正常,但处理第16个分类时,页面加载过程中程序崩溃——不管分类顺序如何,第16个总会触发崩溃,且不会超时,抛出如下异常:

from unknown error: cannot determine loading status
from tab crashed

Stacktrace:
0   chromedriver                        0x0000000104b8d598 chromedriver + 4404632
1   chromedriver                        0x0000000104b14fa3 chromedriver + 3911587
2   chromedriver                        0x00000001047c1d20 chromedriver + 425248
...
26  chromedriver                        0x0000000104b948fe chromedriver + 4434174
27  libsystem_pthread.dylib             0x00007ff80c1294e1 _pthread_start + 125
28  libsystem_pthread.dylib             0x00007ff80c124f6b thread_start + 15

WebDriverException                        
Traceback (most recent call last)
scraping_attributes.ipynb Cellule 6 in <cell line: 4>()
     10   continue
     12 category.click()
---> 14 WebDriverWait(driver, timeout=30, poll_frequency=2).until(EC.visibility_of_element_located((By.XPATH, "//div[@data-yy='item']")))
     16 content = driver.page_source
     17 soup = BeautifulSoup(content)

File /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/selenium/webdriver/support/wait.py:81, in WebDriverWait.until(self, method, message)
     79 while True:
     80     try:
---> 81         value = method(self._driver)
     82         if value:
     83             return value

File /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/selenium/webdriver/support/expected_conditions.py:125, in visibility_of_element_located.<locals>._predicate(driver)
    123 def _predicate(driver):
    124     try:
---> 125         return _element_if_visible(driver.find_element(*locator))
    126     except StaleElementReferenceException:
    127         return False

File /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/selenium/webdriver/remote/webdriver.py:856, in WebDriver.find_element(self, by, value)
    853     by = By.CSS_SELECTOR

如果改用time.sleep(10)替代WebDriverWait,程序能正常运行,但耗时太长。我有几个疑问:

  • 这是不是内存问题?毕竟总是在第16个分类时崩溃
  • 还是和网站本身有关?
  • 有没有人用Python Selenium时遇到过这类问题?

解决方案分析

1. 核心原因:大概率是内存泄漏问题

ChromeDriver在频繁切换分类、更新DOM的场景下,容易出现内存泄漏——每次分类切换后,旧的元素引用、页面缓存未被及时释放,累计到第16次时达到Chrome进程的内存阈值,直接导致标签页崩溃。你可以打开Chrome任务管理器(Shift+Esc)观察内存变化,会发现每次切换分类后内存持续上涨。

2. 网站因素的可能性极低

少数情况下网站会针对高频操作做限制,但不会稳定在第16次触发。若怀疑网站问题,可留意第16个分类是否加载了异常大的资源(比如超大图片、上万条数据),但这种情况占比极低。

3. 同类问题的普遍性

这个问题在Selenium用户中很常见,尤其是循环操作页面元素、频繁切换内容的场景,核心都是ChromeDriver的内存管理缺陷导致的。

可行解决办法

(1)定期重启浏览器

每处理15个分类就关闭当前driver,重新初始化实例,避免内存累计:

options = webdriver.ChromeOptions()
# 可添加内存优化参数,见下文
driver = webdriver.Chrome(options=options)
driver.get('https://xxxxxxxxxx.com/xxxxxxx')
categories = driver.find_elements(By.XPATH, "//li[@data-yy='category']")

for idx, category in enumerate(categories):
    # 每15个分类重启一次浏览器
    if idx % 15 == 0 and idx != 0:
        driver.quit()
        driver = webdriver.Chrome(options=options)
        driver.get('https://xxxxxxxxxx.com/xxxxxxx')
        # 重新获取分类列表,旧driver的元素引用已失效
        categories = driver.find_elements(By.XPATH, "//li[@data-yy='category']")
        category = categories[idx]
    
    category.click()
    WebDriverWait(driver, 30, 2).until(EC.visibility_of_element_located((By.XPATH, "//div[@data-yy='item']")))
    # 后续处理代码...

(2)优化等待逻辑

结合staleness_of判断旧内容是否消失,避免DOM更新时查询元素的冲突:

# 点击分类前记录当前的内容容器
old_items = driver.find_elements(By.XPATH, "//div[@data-yy='item']")
category.click()
# 先等旧内容消失,再等新内容出现
WebDriverWait(driver, 30).until(EC.staleness_of(old_items[0]))
WebDriverWait(driver, 30).until(EC.visibility_of_element_located((By.XPATH, "//div[@data-yy='item']")))

(3)添加Chrome启动优化参数

通过参数限制内存、关闭不必要的功能:

options = webdriver.ChromeOptions()
options.add_argument('--disable-extensions')
options.add_argument('--disable-gpu')
options.add_argument('--disable-dev-shm-usage')  # 解决Linux下共享内存不足问题
options.add_argument('--memory-pressure-off')  # 关闭内存压力检测
options.add_argument('--max-old-space-size=512')  # 限制V8引擎内存(单位MB)
driver = webdriver.Chrome(options=options)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 16:10:29