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
相关产品推荐
相关产品推荐

