杀死 Chromium 和 Selenium WebDriver 创建的不必要的 chrome 进程

Killing unnecessary chrome processes created by Chromium and Selenium WebDriver

提问人: 提问时间:7/18/2023 更新时间:7/18/2023 访问量:121

问:

我正在尝试运行一个需要很长时间才能完成的 Selenium WebDriver 脚本。问题是,在我的服务器上执行上述脚本时,大约一个半小时后,以前需要 10 秒才能完成的操作现在需要大约 2 分钟,这使得执行速度非常慢。分析可能的问题是什么,我看到在执行过程中创建了几个 crhome 进程。例如,当我第一次创建执行时,我有 4 个 chrome 进程,而当执行花费几个小时执行时,已经创建了 24 个进程。

我有以下脚本,如果在执行过程中抛出异常,它会尝试重新运行脚本,并尝试删除不必要的 chrome 进程以每小时释放一次资源,但这似乎不起作用,因为这不是我想做的,而是扼杀了主要的 chrome 进程, 这意味着它会导致脚本停止,并且必须从 shell 重新运行它(因此只会执行 10 小时,每次尝试一次)。有没有办法只摆脱此脚本中不必要的 chrome 进程?

max_attempts=10
attempt=1
log_file="../logs/execution_log_$(date +"%d%m%Y").txt"
while [ $attempt -le $max_attempts ]; do
  # Kill any running instances of python3, chromedriver, chrome and google-chrome-stable
  pkill -f "python3"
  pkill -f "chromedriver"
  pkill -f "chrome"
  pkill -f "google-chrome-stable"

  # Run script with nohup
  nohup python3 main.py >> "$log_file" 2>&1 &

  # Store the process ID of the script
  script_pid=$!

  start_time=$(date +%s)

  # Wait for the script to finish or check if it is still running
  while ps -p $script_pid > /dev/null; do
    sleep 5
    # Check if the elapsed time exceeds 1 hour (3600 seconds)
    current_time=$(date +%s)
    elapsed_time=$((current_time - start_time))
    if [ $elapsed_time -ge 3600 ]; then
        echo "$(date) Killing zombie Chrome processes..."
        # Kill all chrome processes except for the oldest
        pkill -f "chrome --type=zygote"
        pkill -f "chrome --type=renderer"
        pkill -f "chrome --type=gpu-process"
        pkill -f "chrome --type=utility"
        break
    fi
  done
  echo "$(date) The command has stopped"

  exit_code=$?
  # Check if exit code is different from 0 and if the execution log file's last line is equal to the literal String to break the loop
  if [ $exit_code -ne 0 ] && [ "$(tail -n 1 "$log_file")" = "ENDOF SCRIPT" ]; then
    echo "$(date) Script completed successfully with exit code 0."
    break
  else
    echo "$(date) Script exited with code $exit_code."
    # If it's the last attempt, print a failure message and exit
    if [ $attempt -eq $max_attempts ]; then
      echo "$(date) Maximum attempts reached. Script failed."
      # Kill any running instances of python3, chromedriver, chrome and google-chrome-stable
      pkill -f "python3"
      pkill -f "chromedriver"
      pkill -f "chrome"
      pkill -f "google-chrome-stable"
      exit 1
    fi

    echo "$(date) Restarting command..."
    attempt=$((attempt + 1))
  fi
done
selenium-webdriver chromium chrome-web-driver

评论

0赞 pcalkins 7/19/2023
现代浏览器通过将域保存在单独的线程中来隔离域......(这是安全问题......您可能只是检查是否有任何额外的窗口/选项卡。听起来这可能正在发生,但网站将加载各种域外资源......(广告、跟踪器、JS、CSS、第三方登录等)很难说您可以在驱动程序中设置什么样的选项来提供帮助,而不知道为什么会访问这么多域/线程。我通常设置的一件事是关闭 DNS-Prefetch,但不确定它在这里会有所帮助。

答:

0赞 BernardV 7/18/2023 #1

我不确定你是否已经在这样做了,但如果没有,你可以将你的 Selenium 脚本与单元测试运行器结合起来。将脚本与测试运行程序结合使用时,可以在测试运行之前和之后执行有用的操作。例如,即使在发生错误后,也应该正确关闭/处置 Selenium 资源。(另外,我不确定您的 Selenium 脚本是用哪种语言编写的,所以我只是添加了一个 Python 示例......setUptearDown

import unittest

from selenium import webdriver

class Tests(unittest.TestCase):
    def setUp(self):
        # create a new Chrome session
        self.driver = webdriver.Chrome()
        self.driver.implicitly_wait(30)
        self.driver.maximize_window()
        # navigate to the application home page
        self.driver.get("https://www.google.com/")

    def test(self):
        # your test code

    def tearDown(self):
        # close the browser window
        self.driver.quit()