Selenium循环多次成功迭代后随机冻结问题求助
问题描述
运行循环爬取时,前几次迭代次数随机(5-15次不等)正常,但程序会随机无限挂起。代码示例如下:
for url in links: driver.get(url) print(url) li_elements = driver.find_elements(By.CLASS_NAME, "css-sfcl1s") price_elements = driver.find_elements(By.CLASS_NAME, "css-t9ee1.er34gjf0") # 处理Python列表的相关操作
目标站点为OLX类房产站点。
已尝试的无效方案:
- 使用
driver.command_executor.set_timeout(10),无效果; - 添加try-except块,except块的print语句可执行,但在
driver.get(url)处触发ReadTimeoutError; - 重启WebDriver仅暂时有效,数次迭代后仍会停止,无法适配900个站点的爬取需求;
- 改用
WebDriverWait(driver, 15).until(EC.presence_of_all_elements_located((By.CLASS_NAME, "css-sfcl1s")))等待元素,问题依旧。
有效解决方案
1. 修改WebDriver页面加载策略
默认加载策略会等待所有资源加载完成,极易导致超时挂起。改成eager或none策略,让WebDriver在DOM加载完成后就继续执行:
from selenium import webdriver from selenium.webdriver.chrome.options import Options options = Options() # eager:等待DOMContentLoaded事件触发后继续;none:不等待任何加载完成 options.page_load_strategy = 'eager' driver = webdriver.Chrome(options=options)
2. 为页面请求添加重试与自动重启机制
捕获ReadTimeoutError时先尝试刷新页面,多次失败则自动重启WebDriver,避免进程彻底挂死:
from selenium.common.exceptions import ReadTimeoutError max_retries = 3 for idx, url in enumerate(links): retry_count = 0 success = False while retry_count < max_retries and not success: try: driver.set_page_load_timeout(10) driver.get(url) success = True except ReadTimeoutError: retry_count += 1 if retry_count == max_retries: # 重试耗尽,重启WebDriver driver.quit() driver = webdriver.Chrome(options=options) else: driver.refresh() if not success: print(f"无法加载URL: {url},已跳过") continue # 后续元素定位与处理逻辑 li_elements = driver.find_elements(By.CLASS_NAME, "css-sfcl1s") price_elements = driver.find_elements(By.CLASS_NAME, "css-t9ee1.er34gjf0") # 处理Python列表的相关操作
3. 模拟人类行为降低反爬触发概率
站点反爬机制可能因请求频率过高限制访问,导致页面加载异常:
import random import time # 每次请求后添加1-3秒随机延迟 time.sleep(random.uniform(1, 3)) # 模拟滚动页面,进一步降低爬虫特征 driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") time.sleep(random.uniform(0.5, 1.5))
4. 定期清理缓存与Cookie
长时间运行后,缓存和Cookie堆积会影响WebDriver性能,每爬取20个页面左右清理一次:
if idx % 20 == 0: driver.delete_all_cookies() driver.execute_script("window.localStorage.clear();") driver.execute_script("window.sessionStorage.clear();")
5. 轮换代理IP(可选)
如果站点对单一IP请求频率做了严格限制,轮换代理IP可避免被限流导致的加载挂起:
proxy_list = ["http://proxy1:port", "http://proxy2:port", ...] # 每次重启WebDriver时随机切换代理 proxy = random.choice(proxy_list) options.add_argument(f'--proxy-server={proxy}') driver = webdriver.Chrome(options=options)
内容的提问来源于stack exchange,提问作者Poor_econ_student
相关产品推荐
相关产品推荐

