Python: Selenium Speed Scraping
Sometimes in my work I should use selenium for scraping the different websites, but this tool is too slow.
This life hack is blowing in the wind, but for the last two years I have worked with many scrapers, written by others, and I never saw anyone using it.
As you may know, the main reason why the selenium works slow is nasty parser, so the first thing that comes to mind is to change parser in selenium.
To show you how it works, I will use selenium with chromedriver, beautifulsoup4 and this page in Wikipedia, which contains the table with some information about U.S. states.
So, for beginning I made the script which use only selenium for extracting data from the table:
If you run this script, you will see that the implementation took 27.177188 seconds.
Now let’s try to change standart selenium parser to BeautifulSoup. Simply, exctract html markup from webdriver and send it to BeautifulSoup:
As a result we will get this code:
And after running we see… 07.664240 seconds! The result is 3 times faster!
So selenium is a cool tool if you need to simulate user’s actions, but if you work with big or huge arrays of data from webpage(s), then the best way is to delegate this task to faster parsers.
optimize python selenium webscraping
i have this code below that is extracting information from a website using selenium the code works fine but is pretty slow i was wondering if there is any thing i could change to make the program go faster
1 Answer 1
Don’t create a new driver instance for each iteration. There is hardly any time taken by your script to extract the data. The majority of it is spent only on opening the browser and loading the URL again and again.
Here’s what I did with your code —
1) Placed the driver initialization and the driver.quit() outside the loop.
2) Used selenium webdriver itself to scrape the data instead of beautiful soup as the results of the latter were not consistent and reliable since the data is coming from javascript. (Plus there is no need of an external library, you can get all your data from selenium itself.)
3) Used javascript to open urls so that we could wait only for the relevant stuff (using WebDriverWait ) in your website to appear instead of it to load in its entirety.
The final code took less than half time than your original code to scrape the data. (Measured via this method for 3 iterations)
EDIT —
There are some pages like this which does not have required statistics. In that case below line will throw a TimeoutException —
So you can simply handle that exception and instead check whether No Statistics available» element is present or not (using is_displayed() ).
Как ускорить парсинг данных с Python/Selenium?
В текущем варианте парсинг осуществляется с chromedriver. Практически имею около 100.000 ссылок, по которым находятся таблицы. У каждой таблицы имеется кнопка «Подробнее», которую сейчас нажимает парсер, копирует содержимое попапа, закрывает его и т.д.
В общем чтобы пропарсить наверное миллион таких строк у меня уйдет месяц непрерывной работы селениума. Ищу способ как-то ускорить это.
Проблема, установил небольшие задержки, которые нужны в аккурат дать подгрузиться попапу и дать ему закрыться, иначе возникают ошибки element is not found.
В общем, спасайте. Подскажите как это реально делается, чтобы ускорить работу хотя бы в 10 раз. (за пол часа он прошел около 400 страниц, спарсив около 2000 строк). Это как пройтись мне самому, нажать на каждую ссылку «Подробнее», но копирование отдать скрипту. Это вряд ли можно назвать полной автоматизацией. тем более с такими объемами (не оцениваю их как большие).
Существуют ли «реальные» бустеры таких операций? Я понимаю, что селениум сделан для тестирования или хотя бы для парсинга страниц, где нет кучи попапов, которые все надо прокликать.
upd: после постинга продолжил гуглить и в одном обсуждении нашел следующее:
- Вопрос задан более трёх лет назад
- 6343 просмотра
- Вконтакте
На 100к ссылок, особенно если требуется их обходить достаточно часто (или на сервере ресурсов мало), есть уже смысл задумать о более кастомных (читай, напилить руками низкоуровневый механизм), но более быстрых механизмах. Как-то запросы на получение AJAX данных через curl. Или если данные получаться в рамтайме на клиенте через замудренный JS, то применить SpiderMonkey, V8 либо другие серверных движки.
Делал на кластере из PhantomJS парсер который должен был за 15 минут обходит чуть больше 1к страниц и парсить из них разные хитрые таблички. Требовалось что-то около десяти инстансов PhantomJS, 20 Гб ОЗУ и 16 ядер ЦПУ. На таком кластере 100к за сутки переварит реально.
Когда требование по времени ужесточилось до 5 минут, напилил на SpiderMonkey.
Нужно использовать wait(). Тогда дальше код будет выполняться когда на странице появиться нужный элемент.
Наличие/отсутствие попапов не играет роли. Все, что появляется в DOM, все можно отработать. Регулярно тягаю данные с яндекс ворстата. Много там разных хитрых обработчиков. Но все силами PhantomJS-а через webdriver решается рано или поздно.
- Вконтакте
«Требовалось что-то около десяти инстансов PhantomJS»
Можете показать кусок кода (или направить на реализацию подобного решения), о котором вы говорите? Если я запускаю «тупо» 2 одинаковых скрипта (естественно на разный список ссылок), то я вижу, что первый работает нормально, а второй «плетется», иногда подтормаживая, или вообще останавливаясь. Не знаю точно в чем проблема: соединение, настройки удаленного сервера, или какие-то другие факторы.
«Нужно использовать wait().»
Расставил везде где нужно по time.sleep(1) или wait.until. Запинаний не было.
«Наличие/отсутствие попапов не играет роли. Все, что появляется в DOM, все можно отработать.». Это понятно, что все появляется в DOM. Сейчас в моем примере сервер отдает целый шаблон с html-тегами (а не просто массив данных), который при открытии появляется или наоборот удаляется. Все это ведь надо прокликать, так или иначе. Иначе как дать появится данным в дереве?
«Возможно. Но так ли это в вашем контексте ни кто кроме эксперимента не скажет.»
В общем я сделал прокликивание ссылок через селениум, а парсинг данных через bs4. Работает, как и обещали — быстрее. В 2 с небольшим раза (т.е. не 5 часов, а 2.7 где-то). Это уже хорошо.
В общем, думаю, что ничего волшебного не бывает, т.к. все зависит от независящих от меня факторов: как быстро сервер отдает информацию, скорость канала и т.д. Единственное решение: максимально быстроработающий код и многопоточность. Насколько я понял. С первым я более-менее разобрался, а вот как увеличить ресурсы — пока нет. Парсинг происходит уже 2-й день.

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

There are two ways to test any program’s quality and performance, the old manual testing method and the convenient method of automating the test. When it comes to automating the tests, Selenium finds its way quickly. The whole point of using selenium for automating the test cases is to make your testing project end quickly. The very idea of using Selenium in any project is to make the testing process quicker and accurate. If you are looking to achieve the maximum speed and for selenium python, here we are providing a few tips to succeed in this regard.
Parallel testing
The best feature of Selenium is its parallel testing capabilities. By using this feature, any developer can automate the testing across multiple devices at once. You can execute the testing even on remote computers. Parallel testing is the easiest and fastest way to complete the testing process quickly. This is a must to do for the developers since most of the projects demand testing on multiple browsers and operating systems. It allows the developers to make the testing quicker and efficient.
With this feature, if you have ten test cases to execute, you can execute each test case on different devices simultaneously. Suppose one test case takes 10 minutes to complete the full testing. Hence you can complete all of them within ten minutes rather than spending a hundred minutes using a single device.
Make your codes shorter.
If you want to accelerate the testing speed, one point to remember is that every selenium test should use to test single functionality. The tip for making your Selenium testing faster is by reducing the number of steps in each trial. It is not recommended to use over 20 steps to make the testing lengthy and consume more time. This is essential because even if you have parallel testing, you must ensure a single test must execute on a single device. The practice of making your tests sort comes with another advantage, i.e., if you end up with any error, finding out the error step becomes comfortable with shortcodes. In the lengthy codes, debugging becomes an annoying thing.
Only use explicit waits.
If you use explicit waits in your test cases, the Selenium web driver waits until a specific condition occurs before starting the execution of other test scripts. So, as far as possible, use explicit wait commands to eliminate the delays in running your test cases. Predefining the explicit wait commands are more than necessary for some aspects on websites where it takes a longer time to load. If you employ the implicit wait command, your browser will wait for a specific time before loading every web element. The application of explicit wait commands eliminates these types of unnecessary delays.
Always use fast selectors in your test scripts.
Of course, selenium offers a wide variety of selectors to provide versatility to your test scripts. But there are a few selectors works smoothly and fast. If you build your test cases using those selectors, your test performs better with less time. Some selectors, including XPath selectors, name selectors, and others, make your testing faster.
Other factors
- Your Virtual Machine, computer, and container hardware resources also matter for increasing or decreasing the test speed. If the hardware is not robust, the tests bund to run slowly.
- Along with hardware, the hosting server hardware also makes your testing slow if the server hardware is not powerful.
- The number of concurrent users also impacts the testing speed.
Hence, the complete understanding of what works well and what causes low performance helps you make your selenium testing speed and accuracy.