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

Selenium执行driver.quit()后仍CPU占用100%问题排查与优化

问题

我使用Selenium搭配Chromedriver爬取batdongsan.com.vn网站数据,需程序连续运行6小时以上。初期driver.quit()可正常关闭所有标签页,但运行约5-6小时后CPU占用率升至100%,出现10-15个无法关闭的Chrome标签页。我同时在本地Jupyter Notebook和Colab运行代码,前者5小时后过载,后者12小时后运行缓慢。代码如下:

# setup chrome options
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--headless') # ensure GUI is off
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-dev-shm-usage')
chrome_options.add_argument("--nogpu")
chrome_options.add_argument("--disable-gpu")
chrome_options.add_argument("--window-size=1280,1280")
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--enable-javascript")
chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
chrome_options.add_experimental_option('useAutomationExtension', False)
chrome_options.add_argument('--disable-blink-features=AutomationControlled')

while page < len(listed):
  print(page)
  ua = UserAgent()
  userAgent = ua.random
  # set path to chromedriver as per your configuration
  chromedriver_autoinstaller.install()
  # set the target URL
  url = 'https://batdongsan.com.vn' + listed[page]
  # set up the webdriver
  driver = webdriver.Chrome(options=chrome_options)
  driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})")
  driver.execute_cdp_cmd('Network.setUserAgentOverride', {"userAgent": userAgent})

  driver.get(url)

  # Wait for the page to load
  driver.implicitly_wait(10)

  # Get the page source
  html_data = driver.page_source

  # Parse the HTML data using BeautifulSoup
  soup = BeautifulSoup(html_data, 'html.parser')

  # Close the web driver
  driver.quit()
  page += 1

请问是我的代码存在问题,还是Selenium本身占用大量CPU?有没有方法降低Selenium的CPU占用率,或确保每次会话后所有标签页都被关闭?

分析与解决方案

你的代码存在多处可优化的问题,这些问题是导致CPU过载、进程残留的主要原因,结合Selenium本身的特性,可通过以下方式解决:

一、修复代码中的核心问题

1. 移除重复的Chromedriver安装

每次循环执行chromedriver_autoinstaller.install()会反复检查版本、写入文件,既浪费资源也可能引发进程锁定,只需在循环外执行一次即可:

chromedriver_autoinstaller.install()  # 移到循环前,仅执行一次
ua = UserAgent()  # UserAgent实例也无需每次循环创建
while page < len(listed):
    # 后续循环逻辑

2. 用异常处理确保driver必关闭

如果页面加载失败、解析出错,driver.quit()可能不会执行,导致Chrome进程残留。用try...finally块强制关闭driver:

while page < len(listed):
    print(page)
    userAgent = ua.random
    url = 'https://batdongsan.com.vn' + listed[page]
    driver = None
    try:
        driver = webdriver.Chrome(options=chrome_options)
        driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})")
        driver.execute_cdp_cmd('Network.setUserAgentOverride', {"userAgent": userAgent})
        
        driver.get(url)
        driver.implicitly_wait(10)
        html_data = driver.page_source
        soup = BeautifulSoup(html_data, 'html.parser')
        # 此处添加数据处理逻辑
    except Exception as e:
        print(f"处理页面{page}出错: {str(e)}")
    finally:
        if driver is not None:
            driver.quit()  # 无论是否出错,都关闭driver
    page += 1

3. 优化Chrome启动参数

移除重复、冗余参数,添加更节省资源的配置:

chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--headless=new')  # 新版headless模式,资源占用更低
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-dev-shm-usage')
chrome_options.add_argument("--disable-gpu")
chrome_options.add_argument("--window-size=800,600")  # 缩小窗口,减少渲染开销
chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
chrome_options.add_experimental_option('useAutomationExtension', False)
chrome_options.add_argument('--disable-blink-features=AutomationControlled')
# 添加资源优化参数
chrome_options.add_argument('--disable-images')  # 无需图片时禁用加载
chrome_options.add_argument('--disable-plugins')
chrome_options.add_argument('--disable-extensions')
chrome_options.add_argument('--disable-background-networking')

二、降低CPU占用的进阶措施

1. 复用单个driver实例

每次循环创建新driver会带来大量进程开销,可复用一个driver,通过切换标签页完成爬取:

chromedriver_autoinstaller.install()
ua = UserAgent()
driver = webdriver.Chrome(options=chrome_options)
driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})")

try:
    while page < len(listed):
        print(page)
        userAgent = ua.random
        driver.execute_cdp_cmd('Network.setUserAgentOverride', {"userAgent": userAgent})
        url = 'https://batdongsan.com.vn' + listed[page]
        
        # 打开新标签页并切换
        driver.execute_script(f"window.open('{url}');")
        driver.switch_to.window(driver.window_handles[-1])
        driver.implicitly_wait(10)
        html_data = driver.page_source
        soup = BeautifulSoup(html_data, 'html.parser')
        # 数据处理逻辑
        
        # 关闭当前标签页并切回主窗口
        driver.close()
        driver.switch_to.window(driver.window_handles[0])
        page += 1
finally:
    driver.quit()  # 最后统一关闭driver

2. 添加请求间隔

高频请求会同时消耗本地和服务器资源,也容易触发反爬,在循环末尾添加间隔:

import time
# 循环末尾添加
time.sleep(1)  # 可根据实际情况调整间隔时长

3. 优先使用非浏览器爬取

如果目标页面无需执行JavaScript,直接用requests+BeautifulSoup爬取,完全避免浏览器的资源开销,仅在必须处理JS渲染时使用Selenium。

三、强制清理残留进程

如果仍有Chrome进程残留,可在driver.quit()后手动清理(仅本地环境适用,Colab不建议):

import psutil

def kill_chrome_processes():
    for proc in psutil.process_iter(['name']):
        try:
            if proc.name() in ['chrome.exe', 'chromedriver.exe', 'chrome']:
                proc.kill()
        except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
            pass

# 在finally块中调用
finally:
    if driver is not None:
        driver.quit()
    kill_chrome_processes()

内容的提问来源于stack exchange,提问作者Huy Nguyễn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 22:31:10