Selenium очистить оперативную память
I am using selenium with Firefox to automate some tasks on Instagram. It basically goes back and forth between user profiles and notifications page and does tasks based on what it finds.
It has one infinite loop that makes sure that the task keeps on going. I have sleep() function every few steps but the memory usage keeps increasing. I have something like this in Python:
I never close the driver because that will slow down the program by a lot as it has a lot of queries to process. Is there any way to keep the memory usage from increasing overtime without closing or quitting the driver?
EDIT: Added explicit conditions but that did not help either. I am using headless mode of Firefox.
Try to avoid using sleep method, use Explicit Waits or Implicit Waits methods see this for more information selenium-python.readthedocs.io/waits.html
Solution
You can implement either/all of the generic/specific steps as follows:
- Upgrade Selenium to current levels Version 3.141.59.
- Upgrade GeckoDriver to GeckoDriver v0.24.0 level.
- Upgrade Firefox version to Firefox v65.0.2 levels.
- Clean your Project Workspace through your IDE and Rebuild your project with required dependencies only.
- If your base Web Client version is too old, then uninstall it and install a recent GA and released version of Web Client.
Some extensions allow you to block such unnecessary content, as an example:
-
allows you to hide ads on websites. allows you to selectively enable and disable all scripts running on websites.
If your Tests doesn't requires the CSS you can disable the CSS following the this discussion.
Итог . вы должны каким-то образом убить процесс, потому что разработчики его не встроили. Все другие способы могут оставить процесс запущенным, и этого достаточно, чтобы убить.
согласно Selenium API, вам действительно следует вызвать, browser.quit() поскольку этот метод закроет все окна и завершит процесс. Вы все равно должны использовать browser.quit() .
Однако : на моем рабочем месте мы заметили огромную проблему при попытке выполнить тесты chromedriver на платформе Java, где chromedriver.exe фактически все еще существует даже после использования browser.quit() . Чтобы противостоять этому, мы создали командный файл, подобный приведенному ниже, который просто принудительно закрывает процессы.
Поскольку chromedriver.exe не является большой программой и не потребляет много памяти, вам не нужно запускать ее каждый раз, а только тогда, когда она представляет проблему. Например, при запуске Project-> Clean в Eclipse.
Я не могу оправдать любой ответ, который рекомендует убивать процессы, не упомянув также о правильном способе нормального завершения этих процессов. Если вы правильно используете quit метод, это не должно быть проблемой. Насильственное уничтожение процессов должно быть только крайней мерой, и ваш ответ должен это отражать.
Обратите внимание на единственную проблему: когда вы отлаживаете и прерываете выполнение, процесс все равно остается. Даже если вы нажмете кнопку, X она все равно останется. это ЕДИНСТВЕННАЯ причина для этого командного файла. Очевидно, quit это правильный путь, однако в моем примере, если вы отлаживаете и останавливаете выполнение - он никогда не достигает quit .
Я отвечаю на один из вопросов: I hope there is a way I can write something to kill the chromedriver.exe process. . и да, это приятно! Java этого не делает
В зависимости от используемой вами тестовой среды, вы также можете столкнуться с фантомными процессами, если тесты не пройдут его «настройку». NUnit, например, не будет вызывать метод TestFixtureTearDown, если что-то в методе TestFixtureSetup завершится неудачно -> вы создаете браузер, выполняете некоторые действия, а затем запускаете тест. Если что-то пойдет не так, когда «ты делаешь что-то», то все, процесс остается.
Если вы используете интерфейс DriverService, удерживайте службу, пока не закончите работу с драйвером, а также вызовите DriverService.stop (). Для меня driver.quit () было недостаточно, потому что я также использовал DriverService.
browser.close() закроет только текущее окно Chrome.
browser.quit() должен закрыть все открытые окна, а затем выйти из webdriver.
ХОРОШО. Я пробовал browser = webdriver.Firefox() . Оба browser.close() и browser.quit() закроют все окна и освободят память. Однако хромодрайвер не сделал бы того же.
Привет, KLI. Здесь, где я работаю, мы заметили те же самые вещи, происходящие с хромодрайвером. Вот почему у нас есть командный файл, который мы запускаем только тогда, когда нам нужно. chromedriver.exe - небольшой процесс, но он представляет проблему, когда мы пытаемся запустить Project-> Clean, например
Теоретически вызов browser.Quit закроет все вкладки браузера и убьет процесс.
Однако в моем случае я не смог этого сделать - поскольку я запускал несколько тестов параллельно, я не хотел, чтобы один тест закрыл окна для других. Поэтому, когда мои тесты заканчиваются, остается много запущенных процессов "chromedriver.exe".
Если в этом текстовом поле уже есть текст, как я могу сказать селену, чтобы он очистил поле?
Это может быть проблема с конфликтующими версиями селена и хромодрайвера. Кажется маловероятным, что разработчики намеренно удалили эту функцию из chromedriver.
На данный момент этот ответ не работает правильно в приложениях React, поскольку clear не приведет к срабатыванию функции React onChange. Таким образом, ваш ввод будет очищен, и тесты продолжатся, а состояние вашего компонента останется таким, как было раньше. реагируют вопрос , селен вопрос
Ты можешь использовать
Если этот элемент является элементом ввода текста, это очистит значение.
Обратите внимание, что события, запускаемые этим событием, могут быть не такими, как вы ожидали. В частности, мы не запускаем никаких событий клавиатуры или мыши. Если вы хотите, чтобы события клавиатуры запускались, подумайте об использовании чего-то вроде sendKeys(CharSequence) . Например:
При использовании CTRL + 'a' учитывайте ситуацию, когда тест будет запущен на MacOS (другие сочетания клавиш). Кстати - хорошее предложение, решил мою проблему.
Моя проблема решена с помощью "Keys.BACK_SPACE". Я просто захватываю поле теста поиска, запускаю .click (), а затем внутри цикла for запускаю код. он удаляет всех фрахтователей, ранее имевшихся в поле поиска. затем отправьте новое значение в поле поиска. Просто функция .clear () у меня не работала.
Помогло только webElement.sendKeys(Keys.BACK_SPACE); //do repeatedly, e.g. in while loop в моем странном случае
В самой последней версии Selenium используйте:
Если этот элемент является элементом ввода текста, это очистит значение.
Это общий синтаксис
По моему опыту, это оказалось наиболее эффективным
Мы отправляем Ctrl + Backspace, чтобы удалить все символы из ввода, вы также можете заменить backspace на delete.
РЕДАКТИРОВАТЬ: удалена зависимость ключей
С помощью простого вызова clear () в DOM появляется, что соответствующий компонент input / textarea все еще имеет свое старое значение, поэтому любые последующие изменения в этом компоненте (например, заполнение компонента новым значением) не будут обработаны вовремя.
Если вы посмотрите исходный код селена, вы обнаружите, что метод clear () задокументирован со следующим комментарием:
/ ** Если этот элемент является элементом ввода текста, это очистит значение. Не влияет на другие элементы. Элементы ввода текста - это элементы INPUT и TEXTAREA. Обратите внимание, что события, запускаемые этим событием, могут быть не такими, как вы ожидали. В частности, мы не запускаем никаких событий клавиатуры или мыши. Если вы хотите, чтобы события клавиатуры запускались, попробуйте использовать что-то вроде с клавишей возврата. Чтобы убедиться, что вы получаете событие изменения, рассмотрите возможность последующего вызова с помощью клавиши табуляции. * /
Таким образом, используя этот полезный совет, чтобы очистить поле ввода / текста (компонент, который уже имеет значение) И присвоить ему новое значение, вы получите следующий код:
Извините, что этот код является Java, а не Python. Кроме того, мне пришлось пропустить дополнительный метод waitUntilPageIsReady (), который делал бы этот пост слишком длинным.
Я использую селен с Firefox для автоматизации некоторых задач в Instagram. В основном он перемещается между профилями пользователей и страницей уведомлений и выполняет задачи на основе того, что находит.
Он имеет один бесконечный цикл, который гарантирует, что задача будет продолжаться. У меня есть функция sleep() каждые несколько шагов, но использование памяти продолжает увеличиваться. У меня есть что-то вроде этого в Python:
Я никогда не закрываю драйвер, потому что это сильно замедляет работу программы, так как ей нужно обработать много запросов. Есть ли способ предотвратить чрезмерное увеличение использования памяти без закрытия или выхода из драйвера?
EDIT: добавлены явные условия, но это тоже не помогло. Я использую безголовый режим Firefox.
Старайтесь избегать использования метода ожидания, используйте методы явного ожидания или неявного ожидания, см. это для получения дополнительной информации селен-python.readthedocs.io/waits.html
Хорошо. Я постараюсь сделать это завтра и опубликую открытие здесь.
Изменение с sleep() на ожидание не изменится что-либо в отношении использования памяти. Причина неиспользования сна заключается в том, что это жестко задает интервал, в течение которого ваш скрипт ничего не делает, в надежде, что страница изменит свое состояние; а с *Wait интервал не жестко запрограммирован, а «как только произошло изменение». В вашем случае использования это звучит так, как будто вы используете sleep() в качестве разделителя между выполнениями, и работая в бесконечном цикле, вы не звучите так, как будто вам нужно сбрить несколько секунд.
В этой статье мы расскажем о хитростях и советах по Python, которые должны быть известны разработчику Python.
В одном из недавних постов я рассказал о том, как я использую навыки количественных исследований, которые я совершенствую в рамках программы TPQ.
Вы когда-нибудь хотели поделиться с кем-то файлом, но он содержал конфиденциальную информацию? Многие думают, что электронная почта безопасна, но это.
Недавно я столкнулся с интересной бизнес-задачей - визуализацией сбоев в цепочке поставок лекарств, которую могут просматривать врачи и.
Решение
Вы можете реализовать любой/все общие/конкретные шаги следующим образом:
- Обновите Селен до текущего уровня Версия 3.141.59.
- Обновите ГеккоДрайвер до уровня Геккондрайвер v0.24.0.
- Обновите версию Fire Fox до уровней Фаерфокс v65.0.2.
- Чистый ваш Рабочая область проекта через ваш IDE и Восстановить ваш проект только с необходимыми зависимостями.
- Если ваша базовая версия Веб-клиент слишком старая, удалите ее и установите последнюю общедоступную и выпущенную версию Веб-клиент.
Некоторые расширения позволяют блокировать такой ненужный контент, как пример:
-
позволяет скрыть рекламу на сайтах. позволяет выборочно включать и отключать все скрипты, работающие на веб-сайтах.
Если для вашего Тесты не требуется CSS, вы можете отключить CSS после это обсуждение.
Привет. Драйвер, Firefox и Selenium обновлены. Мое рабочее место было новым, но я снова его почистил и перестроил. На производительность вроде никак не повлияло. Я также избавился от time.sleep и, используя явные условия, предусмотренные в Selenium, я использую безголовый режим для Firefox, будут ли для этого иметь значение css/scripts?
@NaeemKhan Конечно, это важно. Ознакомьтесь с обсуждением отключения CSS в моем ответе.
Похоже, что в FirefoxOptions() нет функции add_experimental_option(). Как мне отключить его для Firefox?
@NaeemKhan Это не FirefoxOptions() , а FirefoxProfile() в моем ответе
Итак, я отключил css с помощью firefoxProfile.set_preference('permissions.default.stylesheet', 2) и изображений. Это все еще не имело значения. Использование Ram все еще растет. Я думаю, проблема может заключаться в интенсивном использовании Instagram javascript и AJAX?
Вы можете быть правы. Instagram активно использует JavaScript и AJAX. Мой ответ больше касается общей стратегии.
Это все еще не решило проблему, но было ближе всего к моей проблеме, поэтому я приму ответ.
На данный момент нет исправления для этого. Я предлагаю вам использовать подход driver.close(). Я также боролся с проблемой ОЗУ, и я подсчитал количество циклов, и когда количество циклов достигло определенного числа (для меня это было 200), я вызвал driver.close(), а затем снова запустил драйвер. а также сбросить счетчик. Таким образом, мне не нужно было закрывать драйвер каждый раз, когда цикл выполняется, и это также меньше влияет на производительность. Попробуй это. Возможно, это поможет и в вашем случае.
Это исправило это для меня. К сожалению, для меня это число было НАМНОГО меньше (~ 25), но я предполагаю, что это сильно зависит от сайта и вашей локальной машины.
Что ж, это серьезная проблема, с которой я сталкиваюсь уже несколько дней. Но я нашел решение. Вы можете добавить несколько флагов, чтобы оптимизировать использование памяти.
Это флаги, которые я добавил. До того, как я добавил флаги, использование ОЗУ продолжало увеличиваться после того, как оно превысило 4 ГБ (8 ГБ на моей машине), моя машина зависла. после того, как я добавил эти флаги, использование памяти не превысило 500 МБ. И, как отвечает ДебанджанБ, если вы запускаете for loop или while loop , пытаетесь заснуть на несколько секунд после каждого выполнения, это даст некоторое время, чтобы убить неиспользуемый поток.
Я почти уверен, что это было полезно, заслуживает большего количества голосов. Один вопрос. Вы сказали, что сохранили память ниже 50 МБ?? Для меня это постоянно ниже 500 МБ. Была ли у вас опечатка или как возможно использование памяти в 10 раз выше?
Здравствуйте.
На VPS стоит selenium, элементарно при запуске начинает кушать 400 метров оператики, если начинаю какие-то операции проводить с ним, то поднимается до гигабайта и выше.
В стою очередь на локальной машине потребляет 90 метров, хотя всё настроено одинаково.
В чём может быть проблема?
VPS
Локальная машина
Разные версии сервера, разные ОС, разное системное окружение и настройки, магнитная буря на Луне или щепаная буря на Марсе. Все это не важно, т.к. что-то подкрутить врятли получится. Примите как данность и продолжайте работать с тем что есть.
P.S. 400 метров не так много. Сам использую немного другое ПО - PhantomJS. В процессе работы 2-5Гб ОЗУ на один истанс вполне себе норма.
После 10-20 выполнений скриптов, все ядра загружены под максимум, сервер начинает ужасно лагать, приходится перезагружать. Если этого не было то пережил бы.
Запускаю по одной вкладке в браузере.
Алексей Сундуков: не понял. Но я так же это всё настроил ещё на одном сервере (не локальном). На нём так же всё в пределах разумного работает.
Влад Пасечник: Еще на одном сервере или еще на одном VPS? Хотя не так важно, т.к. видимо проблема конкретно у данного хостера. Решается переездом на "ещё на один сервер".
Ответы 5
- Используйте явные ожидания или неявные ожидания.
- Используйте driver.quit(), чтобы закрыть все окна браузера и завершить сеанс WebDriver, потому что если вы не используете quit() в конце программы, WebDriver сеанс не будет закрыт должным образом, и файлы не будут очищены выключена память. И это может привести к ошибкам утечки памяти.
Добавление явных ожиданий не помогло, все та же история. Использование памяти продолжает расти. Я нашел временный обходной путь, добавив внутренний цикл для запуска X раз перед закрытием / выходом из драйвера, а бесконечный цикл снова запускает драйвер и снова входит в этот цикл. Это предотвращает поглощение всей памяти, но это не правильное решение.
вы использовали driver.quit()?
Да. Делал driver.close(), затем driver.quit()
Создание нового профиля Firefox и его использование каждый раз при запуске тестовых случаев в Firefox в конечном итоге повысит производительность выполнения, так как без этого всегда будет создаваться новый профиль, и там будет выполняться кеширование информации, и если driver.quit не вызывается каким-либо образом раньше сбой, то в этом случае каждый раз, когда мы получаем новые профили, созданные с некоторой кэшированной информацией, которая будет потреблять память.
// ----------- Связывание профиля Firefox ------
Пожалуйста, поделитесь производительностью выполнения с сообществом, если вы планируете реализовать этот способ.
Я использую безголовый режим, хотя. Имеет ли значение использование другого профиля?
Я бы все равно сказал да, вы должны попробовать. потому что кэширование информации должно быть частью управления профилями и в автономном режиме. Кроме того, я хотел бы поделиться тем, что безголовый режим Mozilla Firefox работает на 3,68% лучше, чем версия с пользовательским интерфейсом. Это разочарование, поскольку безголовый режим Chrome обеспечивает > 30% лучшее время, чем режим пользовательского интерфейса.
Чтобы начать с Селен, у вас очень мало контроля над количеством ОЗУ, используемым Fire Fox. Как вы упомянули, Браузер-клиент, т. е. Мозилла, перемещается между профилями пользователей и страницей уведомлений на Инстаграм и выполняет задачи на основе того, что считает слишком широким, как один прецедент. Таким образом, первой и главной задачей будет разбить бесконечная петля, относящуюся к вашему прецедент, на более мелкие Тесты.
5 Answers 5
Well, This the serious problem I've been going through for some days. But I have found the solution. You can add some flags to optimize your memory usage.
These are the flags I added. Before I added the flags RAM usage kept increasing after it crosses 4GB (8GB my machine) my machine stuck. after I added these flags memory usage didn't cross 500MB. And as DebanjanB answers, if you running for loop or while loop tries to put some seconds sleep after each execution it will give some time to kill the unused thread.
I am pretty sure this was helpful, deserves more upvotes. One question. You said you kept the memory below 50 MB?? For me its constantly below 500 MB. Was yours a typo or how is it possible to have a 10 times higher memory usage?
To start with Selenium have very little control over the amount of RAM used by Firefox. As you mentioned the Browser Client i.e. Mozilla goes back and forth between user profiles and notifications page on Instagram and does tasks based on what it finds is too broad as a single usecase. So, the first and foremost task would be to break up the infinite loop pertaining to your usecase into smaller Tests.
Анализ
Были и предыдущие случаи, когда Fire Fox потреблял около 80% оперативной памяти.
Однако согласно это обсуждение некоторые пользователи считают, что чем больше памяти используется, тем лучше, потому что это означает, что вы не тратите оперативную память впустую. Firefox использует оперативную память, чтобы ускорить свои процессы, поскольку данные приложения передаются намного быстрее в оперативной памяти.
время сна()
Побуждение time.sleep() практически скрывает основную проблему. Однако при использовании Селен и Вебдрайвер для выполнения тестов через ваш Платформа автоматизации использование time.sleep() без каких-либо конкретных условий побеждает цель автоматизации следует избегать любой ценой. Согласно документации:
time.sleep(secs) suspends the execution of the current thread for the given number of seconds. The argument may be a floating point number to indicate a more precise sleep time. The actual suspension time may be less than that requested because any caught signal will terminate the sleep() following execution of that signal’s catching routine. Also, the suspension time may be longer than requested by an arbitrary amount because of the scheduling of other activity in the system.
time.sleep()
Inducing time.sleep() virtually puts a blanket over the underlying issue. However while using Selenium and WebDriver to execute tests through your Automation Framework, using time.sleep() without any specific condition defeats the purpose of automation and should be avoided at any cost. As per the documentation:
time.sleep(secs) suspends the execution of the current thread for the given number of seconds. The argument may be a floating point number to indicate a more precise sleep time. The actual suspension time may be less than that requested because any caught signal will terminate the sleep() following execution of that signal’s catching routine. Also, the suspension time may be longer than requested by an arbitrary amount because of the scheduling of other activity in the system.
Analysis
There were previous instances when Firefox consumed about 80% of the RAM.
However as per this discussion some of the users feels that the more memory is used the better because it means you don't have RAM wasted. Firefox uses RAM to make its processes faster since application data is transferred much faster in RAM.
Читайте также: