Как ускорить selenium python
Перейти к содержимому

Как ускорить selenium python

Как ускорить парсинг данных с Python/Selenium?

В текущем варианте парсинг осуществляется с chromedriver. Практически имею около 100.000 ссылок, по которым находятся таблицы. У каждой таблицы имеется кнопка «Подробнее», которую сейчас нажимает парсер, копирует содержимое попапа, закрывает его и т.д.
В общем чтобы пропарсить наверное миллион таких строк у меня уйдет месяц непрерывной работы селениума. Ищу способ как-то ускорить это.

Проблема, установил небольшие задержки, которые нужны в аккурат дать подгрузиться попапу и дать ему закрыться, иначе возникают ошибки element is not found.

В общем, спасайте. Подскажите как это реально делается, чтобы ускорить работу хотя бы в 10 раз. (за пол часа он прошел около 400 страниц, спарсив около 2000 строк). Это как пройтись мне самому, нажать на каждую ссылку «Подробнее», но копирование отдать скрипту. Это вряд ли можно назвать полной автоматизацией. тем более с такими объемами (не оцениваю их как большие).

Существуют ли «реальные» бустеры таких операций? Я понимаю, что селениум сделан для тестирования или хотя бы для парсинга страниц, где нет кучи попапов, которые все надо прокликать.

upd: после постинга продолжил гуглить и в одном обсуждении нашел следующее:

  • Вопрос задан более трёх лет назад
  • 5464 просмотра
  • Facebook
  • Вконтакте
  • Twitter

alekciy

На 100к ссылок, особенно если требуется их обходить достаточно часто (или на сервере ресурсов мало), есть уже смысл задумать о более кастомных (читай, напилить руками низкоуровневый механизм), но более быстрых механизмах. Как-то запросы на получение AJAX данных через curl. Или если данные получаться в рамтайме на клиенте через замудренный JS, то применить SpiderMonkey, V8 либо другие серверных движки.

Делал на кластере из PhantomJS парсер который должен был за 15 минут обходит чуть больше 1к страниц и парсить из них разные хитрые таблички. Требовалось что-то около десяти инстансов PhantomJS, 20 Гб ОЗУ и 16 ядер ЦПУ. На таком кластере 100к за сутки переварит реально.
Когда требование по времени ужесточилось до 5 минут, напилил на SpiderMonkey.

Нужно использовать wait(). Тогда дальше код будет выполняться когда на странице появиться нужный элемент.

Наличие/отсутствие попапов не играет роли. Все, что появляется в DOM, все можно отработать. Регулярно тягаю данные с яндекс ворстата. Много там разных хитрых обработчиков. Но все силами PhantomJS-а через webdriver решается рано или поздно.

  • Facebook
  • Вконтакте
  • Twitter

«Требовалось что-то около десяти инстансов PhantomJS»
Можете показать кусок кода (или направить на реализацию подобного решения), о котором вы говорите? Если я запускаю «тупо» 2 одинаковых скрипта (естественно на разный список ссылок), то я вижу, что первый работает нормально, а второй «плетется», иногда подтормаживая, или вообще останавливаясь. Не знаю точно в чем проблема: соединение, настройки удаленного сервера, или какие-то другие факторы.

«Нужно использовать wait().»
Расставил везде где нужно по time.sleep(1) или wait.until. Запинаний не было.

«Наличие/отсутствие попапов не играет роли. Все, что появляется в DOM, все можно отработать.». Это понятно, что все появляется в DOM. Сейчас в моем примере сервер отдает целый шаблон с html-тегами (а не просто массив данных), который при открытии появляется или наоборот удаляется. Все это ведь надо прокликать, так или иначе. Иначе как дать появится данным в дереве?

«Возможно. Но так ли это в вашем контексте ни кто кроме эксперимента не скажет.»
В общем я сделал прокликивание ссылок через селениум, а парсинг данных через bs4. Работает, как и обещали — быстрее. В 2 с небольшим раза (т.е. не 5 часов, а 2.7 где-то). Это уже хорошо.

В общем, думаю, что ничего волшебного не бывает, т.к. все зависит от независящих от меня факторов: как быстро сервер отдает информацию, скорость канала и т.д. Единственное решение: максимально быстроработающий код и многопоточность. Насколько я понял. С первым я более-менее разобрался, а вот как увеличить ресурсы — пока нет. Парсинг происходит уже 2-й день.

alekciy

Bjornie: >Можете показать кусок кода (или направить на реализацию подобного решения), о котором вы говорите?

У меня PHP. На python-е думаю отличий будет не сильно много. Архитектура такая. Есть класс который запускает заданное количество PhantomJS. Поскольку последний может из коробки работать через webdriver, то интансы запускаются в фоном режиме, при этом каждый из них слушает строго свой заданный локальный порт. Кроме того каждый из них запускается строго через прокси (что бы были заходы с разных IP + на случай бана), у каждого своя прокся. После чего приложение когда нужно соединяется с этим фантомами и отправляет в них требуемые задания. Задачи на загрузку складываются в очередь redis, скрипт который заполняет очередь запускается строго в одном экземпляре (гарантируется через семафоры) и заполняет очередь только если она пустая (тогда задачи не дублируются). Это скрипт запускается кроном. Если другой скрипт (назовем его воркер). Он так же пускается по крону каждую минуту. Он забирает из очереди redis одно задание, отправляет его фантому, парсит страницу, складывает результат в базу, завершает работу. Кусок кода (кластер стартует через startWebDriverCluster):

Как ускорить парсинг веб-страниц в Python с помощью Selenium и Beautiful Soup?

Я написал сценарий для очистки сайта Vivino, используя библиотеки Beautiful Soup и Selenium.

На этом сайте я хочу хранить информацию об определенных винах.

Мне нужно использовать Selenium для динамической очистки, так как к обзорам можно получить доступ, только нажав кнопку «Показать больше отзывов» на веб-странице, которая появляется после прокрутки вниз до верхней части страницы.

Я адаптировал код только для одного вина, чтобы вы могли видеть, если нужно, сколько времени это займет:

Сценарий, который я написал, выполняет следующие шаги:

1) С определенной ссылкой на вино (например: https://www.vivino.com/vinilourenco-pai-horacio-grande-reserva/w/5154081?year=2015&price_id=21118981), я могу получить доступ к этой веб-странице с помощью драйвера Selenium.

2) Затем я прокручиваю вниз до нижней части веб-страницы.

3) Нахожу и нажимаю кнопку «Показать больше отзывов»

4) После нажатия на эту кнопку появляется всплывающая страница с обзорами вин.

5) Я прокручиваю вниз в этих всплывающих окнах, пока не достигнет определенного количества отзывов

6) Я извлекаю нужную информацию из отзывов (каждый отзыв является объектом супа из Beautiful Soup)

Проблема в том, что, если я захочу пересмотреть информацию о тысячах вин, это займет вечность. Для одного вина с 99 отзывами это займет 35 секунд.

How To Speed Up Selenium Test Cases Execution?

view count110216 Views

Read time19 Min Read

The primary intent of Selenium test automation is to expedite the testing process. In the majority of the cases, automation tests using Selenium perform exceptionally better than the manual counterparts. However, there might be possibilities to speed up Selenium tests using Selenium test automation best practices to its truest potential. I have come across umpteen cases in my career where there was potential to speed up selenium tests.

There are choices for using different types of waits, different types of web locators, different browser preferences, and making the wisest choices can aid in speeding up the Selenium tests. When looking to speed up Selenium tests, you should also look at optimizing the Selenium test infrastructure as that can significantly boost the speed of test execution.

In this blog, we cover Selenium web testing best practices primarily from a speed and performance point of view. By the end of it, you would be better positioned to accelerate the Selenium tests to achieve faster test results.

Best Practices To Speed Up Selenium Tests

The process of maintaining and upgrading Selenium tests starts getting overly complicated with major updates in the product. Rather than keeping Selenium test performance at bay, it is essential to speed up Selenium tests from the very beginning.

Irrespective of the scenario under test, here is what a Selenium test is supposed to do:

  1. Open the URL under test using local Selenium WebDriver or Remote Selenium WebDriver.
  2. Locate the required WebElements using the most appropriate web Selenium locators (i.e., XPath, CssSelector, Linktext, etc.).
  3. Perform necessary actions on the located WebElements. Make assertions on the page under test.
  4. Free the resources used by the WebDriver.

Though the “30,000-foot view” of every Selenium test is the same, its performance largely depends on the structure and internals of the test methods. In this section, we look at some of the Selenium web testing best practices to speed up Selenium test case execution:

Choose The Appropriate Web Locators

Web Locators in Selenium are considered the essential building blocks of any test scenario. For automating the interaction with any web element, first, we locate the WebElement using a suitable web locator and then perform appropriate action on the element.

Here are some of the widely used Web Locators in Selenium (in no particular order):

  • XPath
  • CSS Selector
  • Name
  • LinkText
  • Partial LinkText
  • TagName
  • ClassName

Appropriate Web Locators are used in conjunction with the find_element [or find_elements] method. The question is ‘Which web locator is fastest in locating elements in Selenium?’.

In terms of the speed for locating WebElements, ID is the fastest Web Locator since the ID locator in Selenium WebDriver is unique for every element on the page. The ID locator returns WebElement that matches with the specified value (or string). If more than one element with the same ID exists on the page, the document.getElementById() returns the first matching element.

Popular web browsers optimize the document.getElementById() method, thereby helping in providing the WebElement from the DOM at a faster pace.

In case the WebElement does not have an ID attribute, it is recommended to go with the NAME attribute. In case the WebElement neither has the ID or NAME attribute, you should go for the CSS Selector Web Locator. The CSS Engine is consistent across all the major browsers, and their performance is tuned for better performance with CSS Selectors in Selenium.

This also means that you would face fewer browser compatibility issues with this particular Web Locator. CSS Selector provides faster element identification and reduced test execution time. Also, CSS Selector is best suited for retired browsers like Internet Explorer and also provides better readability in comparison to XPath.

XPath is the slowest web locator, and you might have XPath consistency issues when moving from one browser to another. Use XPath for locating Web Elements only when you do not have a choice to use other reliable Web Locators in Selenium WebDriver.

Listed below are the Web Locators in ascending order of the execution speed:

  • ID
  • Name
  • CSS Selector
  • XPath

Use Fewer Web Locators

Now that you have identified the best-suited web locators to speed up Selenium tests, the next step should be to keep the number of locators to the minimum.

Every usage of the find_element(By) or find_elements(By) method for locating the desired Web Element(s) performs access to the DOM tree. More the number of accesses to the DOM tree more will be the execution time of the Selenium script. Using fewer web locators is one of the Selenium web testing best practices, especially if you target the Selenium script’s optimum execution speed.

This practice also improves the test script readability, thereby minimizing the time involved in the maintenance of the scripts.

Avoid Thread.sleep() at all costs

A website or web application can comprise of content that is static or dynamic in nature. Modern-day websites use AJAX (Asynchronous JavaScript And XML) for the dynamic loading of content on the web page. Hence, WebElements on the page might load at different intervals, thereby posing difficulties when performing operations on elements that are not yet in the DOM.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *