Chromedriver не удаляет scoped* dir во временной папке после завершения теста

В последнем файле chromedriver.exe возникают проблемы с нехваткой места на диске, так как chromedriver не удаляет папку с именем scoped_* в конце выполнения. Он занимает почти 20 ГБ места для 400 тестов. Я попробовал с 2.28 и 2.29 версиями chromedriver. Я корректно завершаю работу драйвера с помощью driver.close() и driver.Quit(). Версия браузера Chrome - 57.

7 ответов

Мне удалось это, добавив удаление временных папок, которое начинается с "scoped_dir" после выхода из драйвера, например:

 public static void teardown_()
        {
            // quit driver
            if (driver != null)
                driver.Quit();

            // delete all "scoped_dir" temp folders 
            string tempfolder = System.IO.Path.GetTempPath();
            string[] tempfiles = Directory.GetDirectories(tempfolder, "scoped_dir*", SearchOption.AllDirectories);
            foreach (string tempfile in tempfiles)
            {
                try
                {
                    System.IO.DirectoryInfo directory = new System.IO.DirectoryInfo(tempfolder);
                    foreach (System.IO.DirectoryInfo subDirectory in directory.GetDirectories()) subDirectory.Delete(true);
                }
                catch (Exception ex)
                {
                    writeEx("File '" + tempfile + "' could not be deleted:\r\n" +
                            "Exception: " + ex.Message + ".");
                }
            }
        } 

Надеюсь, поможет!

Это известная ошибка, которая будет исправлена ​​в Chromedriver 2.30 https://bugs.chromium.org/p/chromedriver/issues/detail?id=644

Похоже, что это состояние гонки между ChromeDriver и Chrome. ChromeDriver создает эти временные каталоги для использования Chrome, и в конце ChromeDriver пытается удалить эти каталоги. ChromeDriver ожидает завершения основного процесса Chrome, прежде чем выполнять удаление, но некоторые дочерние процессы Chrome могут все еще работать и удерживать эти каталоги, что приводит к сбою удаления. В настоящее время ChromeDriver не повторяет удаление.

Удаление временных файлов, как упомянул Дэниел, может быть временным решением, но я бы удалил его, как только выйдет Chromedriver 2.30.


Обновить

Chromedriver 2.30 вышел и должен решить эту проблему.

Используя последнюю версию chromedriver 2.30.1 не решил проблему для меня - у меня не хватало места в моем %TEMP% каталог при выполнении параллельных заданий селена.

Лучшее решение - это контролировать userDataDir через Chrome Options и распоряжайтесь каталогом самостоятельно после driver.quit()

Если ваш процесс является синхронным, то решение @ cdzar, описанное выше, будет работать, но для параллельных заданий вам действительно нужно контролировать каталог, создайте / утилизируйте его самостоятельно.

Вы можете проверить другие параметры командной строки Chromium здесь.

Было сообщено и исправлено. Оформить заказ 2.30 или 2.31

UPD. по крайней мере, работает для нашей сетки. Если у вас все еще есть проблемы, лучше сообщить о них в любой ветке scope_dir на productforums.google.com. Кроме того, до его исправления мы использовали скрипт PS, который очищал все файлы в.. * \ AppData \ Local \ Temp

UPD. проверьте, что браузер Chrome завершил процесс обновления. Наряду с этим исправлением у нас была проблема, заключающаяся в том, что браузер сохраняет состояние "требуется перезагрузка для завершения обновления" даже после перезагрузки. Может быть, и браузер и драйвер должны быть обновлены для исправления, чтобы работать - не могу сказать наверняка.

UPD2. Я вижу, что у некоторых людей все еще есть проблема. (может быть, они переиздали его?) Вот пример сценария PS, который использовался на машине Win в то время, когда у нас была проблема. Cleaner.ps1

#infinite loop for calling  function   
$ScriptPath = $MyInvocation.MyCommand.Definition

# 2030 year error
$timeout = new-timespan -end (get-date -year 2030 -month 1 -day 1)
$sw = [diagnostics.stopwatch]::StartNew()
while ($sw.elapsed -lt $timeout){
    if (-Not (test-path  $ScriptPath)){
        write-host "v been renamed, quiting!"
        return
        }

    start-sleep -seconds 60
    # logic
$time=Get-Date
$maxdate = $time.AddMinutes(-120)
Get-WmiObject -Class Win32_UserProfile  | Foreach-Object {
    $path =  $_.LocalPath 
    if (-Not $path.Contains('Windows')){
    echo $path
    $Files = Get-ChildItem "$($path)\..\*\AppData\Local\Temp" -recurse | ?  {$_.LastWriteTime -lt $maxdate } |
     remove-item -force -recurse
    echo $Files 

    }
}   
}

run.bat

#PowerShell -Command "Set-ExecutionPolicy Unrestricted" >> "%TEMP%\StartupLog.txt" 2>&1 
PowerShell C:\path2CleanerFolder\Cleaner.ps1

GL

Это решение работает на Selenium 3.141.59. Прежде чем делать driver.quit() в вашем методе разрыва, используйте driver.close(), Selenium WebDriver автоматически удалит папки scoped_dir, которые он создает во время выполнения.

Мы запускаем несколько ChromeDriver с высокой степенью параллелизма, и я получил большое улучшение, используя идею Cornel об использовании добавления driver.close() перед driver.quit() в тесте. Может быть, это дает Chrome немного больше времени, чтобы завершить свои процессы перед выходом, предотвращая возникновение состояния гонки / блокировки?

Если окажется, что нам нужно сделать больше, я постараюсь кодировать ответ, аналогичный тому, который предоставил Дэниел, но из-за нашего уровня параллелизма я попытаюсь удалить определенные папки, созданные каждым экземпляром драйвера.

Название каталога можно получить следующим образом:

Capabilities caps = driver.getCapabilities();
Map<String, String> chromeReturnedCapsMap = (Map<String, String>) caps.getCapability("chrome");
LOG.debug("  Chrome Driver Temp Dir   : " + chromeReturnedCapsMap.get("userDataDir"));

Это напечатает что-то вроде
Каталог драйверов Chrome: C:\Users\Metal666\AppData\Local\Temp\scoped_dir35344_14668

Однако создается впечатление, что созданы два каталога - они отличаются по имени после того, как будут подчеркнуты последними. Так, например, каталоги могут быть названы:

C: \ Users \ Metal666 \ AppData \ Local \ Temp \ scoped_dir35344_14668 C: \ Users \ Metal666 \ AppData \ Local \ Temp \ scoped_dir35344_28790

поэтому код должен был бы обслуживать удаление обоих файлов.

Протестировано с использованием Selenium 3.141.59, Chrome 74.0.., ChromeDriver 74.0..

Исправление как для синхронных, так и для параллельных хромированных драйверов , которое в настоящее время работает у меня, запускает 5 драйверов, Python (через pycharm или терминал):

Сначала объявите, добавьте собственный и уникальный идентификатор для каждого драйвера:

      options.add_argument('--**foo**')

Также убедитесь, что вы указываете его на жесткий диск из-за перезаписи констант:

      options.add_argument("--user-data-dir=**X:/path/to/dir**")

Использование psutil для отслеживания и уничтожения каждого драйвера на основе его уникального идентификатора, а затем Shutil для удаления папок:

      def kill_driver():
    while True:
        running_processes = []
        for proc in psutil.process_iter(['pid', 'cmdline']):
            if proc.info['cmdline'] and **'--foo'** in proc.info['cmdline']:
                running_processes.append(proc)
        for process in running_processes:
            process.kill()
            print(process, ' got shot')
        if not running_processes:
            print('tudo fechado')
            shutil.rmtree(**'X:/path/to/dir'**) # shutil to delete the folder
            print('pasta excluida')
            break

Я использую это в конце каждого выполнения и в исключениях:

      if __name__ == '__main__':
    while True:
        try:
            get_openings()
            gc.collect()
            print('marcano 10 - secundários')
            kill_driver()
            random_delay()
        except Exception as e:
            gc.collect()
            logging.exception(f"An error occurred: {str(e)}")
            print(f"An error occurred: {str(e)}")
            kill_driver()
            random_delay()

Желаем удачи и не забывайте об импорте!

Другие вопросы по тегам