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

Selenium循环10-15次后报Timed out receiving message from renderer错误

故障根因

抛出selenium.common.exceptions.TimeoutException: Message: timeout: Timed out receiving message from renderer: 300.000不是普通的元素等待超时,是Chrome渲染进程和WebDriver通信中断、进程僵死导致的,属于典型的长循环Selenium任务资源泄漏问题,跑10-15次才触发完全符合内存累积溢出的特征:

  • 每次循环直接调用driver.get()跳转页面,没有主动回收渲染进程、页面JS上下文、缓存的残留资源,循环次数叠加后Chrome内存占用持续上涨,最终渲染进程无响应,WebDriver等待300秒收不到渲染进程返回就抛出该异常。
  • 原有嵌套try/finally逻辑存在缺陷:如果定位回复框步骤抛出异常,代码依然会强制执行查找提交按钮并点击的逻辑,触发大量无效等待,进一步加速驱动僵死。
  • 原代码使用presence_of_element_located作为元素等待条件,仅判断元素存在于DOM树,不保证元素可交互,容易出现点击无效、流程卡住的问题;同时没有设置页面加载超时、异常兜底逻辑,页面偶发的第三方资源加载失败就会把整个进程卡成死锁状态。
修复方案

按以下步骤调整代码即可稳定运行,核心改动点见注释:

  1. 初始化Chrome驱动时添加防泄漏、降卡顿的启动参数,调整页面加载策略减少无效等待
  2. 修正错误的异常捕获逻辑,统一处理流程异常,出错时主动清理页面资源
  3. 增加定时重启浏览器的兜底逻辑,从根源解决长时间运行的内存累积问题

优化后的完整代码:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import time
from datetime import datetime
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

# Chrome启动配置,减少内存占用、避免渲染进程后台被挂起
chrome_options = Options()
chrome_options.add_argument("--disable-renderer-backgrounding")
chrome_options.add_argument("--disable-background-timer-throttling")
chrome_options.add_argument("--disable-backgrounding-occluded-windows")
chrome_options.add_argument("--disable-extension")
chrome_options.add_argument("--disk-cache-size=0")
chrome_options.add_argument("--media-cache-size=0")
# 页面加载策略改为eager,DOM就绪即可操作,无需等待图片、广告等第三方资源加载完成
chrome_options.page_load_strategy = 'eager'

def init_driver():
    """封装驱动初始化逻辑,方便重启时调用"""
    drv = webdriver.Chrome(options=chrome_options)
    drv.set_page_load_timeout(60)
    drv.set_script_timeout(30)
    return drv

driver = init_driver()
thread = "替换为你的目标帖子地址"
MAGENTA = "\033[35m" # 原有终端打印颜色常量

for i in range(100000000):
    now = datetime.now()
    current_time = now.strftime("%H:%M:%S")
    try:
        driver.get(thread)
        # 等待回复框可交互后再输入内容
        reply_box = WebDriverWait(driver, 30).until(EC.element_to_be_clickable((By.ID, "message")))
        reply_box.clear()
        reply_box.send_keys("random test string")
        # 等待提交按钮可点击后执行点击
        post_reply = WebDriverWait(driver, 30).until(EC.element_to_be_clickable((By.ID, "quick_reply_submit")))
        post_reply.click()
        # 等待提交按钮失效(页面跳转/刷新),确认回复提交成功
        WebDriverWait(driver, 30).until(EC.staleness_of(post_reply))
        print(MAGENTA + f"[{current_time}] Autobump #" + str(i + 1))
    except Exception as e:
        print(f"[{current_time}] 第{i+1}次执行出错: {str(e)},清理资源后继续")
        # 异常时清理残留标签页、cookie,回收僵死的渲染进程
        driver.execute_script("window.open('');")
        time.sleep(1)
        driver.switch_to.window(driver.window_handles[-1])
        driver.close()
        driver.switch_to.window(driver.window_handles[0])
        driver.delete_all_cookies()
        continue
    # 每执行10次操作强制重启浏览器,彻底清除内存累积,是长稳运行的核心兜底
    if (i + 1) % 10 == 0:
        print(f"[{current_time}] 已完成10次操作,重启浏览器清理内存")
        driver.quit()
        time.sleep(2)
        driver = init_driver()
    time.sleep(1860)

关键注意点

  • 不要依赖Chrome启动参数完全解决内存泄漏问题,Chrome在长时间执行Selenium自动化操作时必然会出现内存上涨,定时重启是工业界通用的最稳妥方案,没有之一。
  • 替换元素等待条件为element_to_be_clickable,可以避免90%以上的元素存在但点击无效的偶发问题。
  • 异常分支的资源清理逻辑可以避免单次出错导致整个循环终止,不需要人工介入即可自动恢复运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 18:36:21