В статье описывается мой опыт работы с Selenium, включая основные трудности и ошибки, с которыми я столкнулся в процессе разработки. Я делюсь практичекими рекомендациями по ускорению разработки и повышению эффективности работы с этим инструментом.

Я начал использовать Selenium для парсинга сайтов. Начинал я с Requests + BeautifulSoup4, но их не всегда хватало. Одной из первых задач было спарсить более 1000 шаблонных сайтов клиентов (сайты располагались на нашем хостинге и обслуживались нами), для сбора данных с целью дальнейшей обработки.
Тогда я отлавливал каждый селектор в процессе запуска сессии Selenium и проверял правильно ли он находится (особенно доставляло удовольствие искать элементы в нескольких всплывающих окнах и iframe). Для этого при поиске каждого селектора я каждый раз перезапускал сессию webdriver, что занимало очень много времени. Еще тогда мне казалось что должен быть способ искать селекторы постепенно, не перезапуская сессию.

Решение с серверной обработкой на Django
В какой-то момент я поднял сервер на django, в котором была открыта сессия webdriver и были настроены функции для действий, в которые я POST-запросом передавал значения, которые обрабатывал django и передавал в функцию, которая работала с Selenium.
По мимо всей обработки в django функция выглядела примерно так:
def find_by_id(pk):
driver.find_element_by_id(pk)
Синтаксис работы с Selenium отличался от современного, сейчас бы он выглядел:
def find_by_id(pk):
driver.find_element(By.ID, pk)
Это позволяло не перезапускать сессию при каждом поиске селектора, но это все еще было нагромождением кода, которое хоть и ускоряло разработку, все еще оставалось медленным и проблемным.
Сейчас бы я написал подобное с использованием FastAPI, например так я писал кастомное API (адаптер) к ChatGTP, который через Selenium обращался к настоящему ChatGPT и возвращал его ответ.
Решение с использованием режима отладки Chrome
Хоть в обычных задачах я и предпочитаю Firefox, для Selenium Chrome оказался для меня удобнее. Всё что нам сейчас нужно - это открыть Chrome в режиме удаленной отладки и подключаться к нему с помощью webdriver.
Chrome с версией 115 и выше не требует отдельной установки драйвера для Selenium, поэтому установить нужно только Selenium:
pip install selenium
Запускаем Chrome в режиме удаленной отладки:
import os
import socket
import threading
class DebugChrome():
def __init__(self, chrome_path: str = 'None'):
if chrome_path == 'None':
# Путь для Chrome по умолчанию
# если используется другой - нужно передать путь к Chrome
# аргументом при вызове класса
self.chrome_path = r'"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe"'
else:
self.chrome_path = chrome_path
# Вызываем функцию поиска свободного порта
free_port = self._find_available_port()
# Запускаем Chrome в режиме удаленной отладки
self._launch_chrome_with_remote_debugging(free_port,
'https://www.google.com')
def _find_available_port(self):
# Находим свободный порт
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind(('', 0))
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
return s.getsockname()[1]
def _launch_chrome_with_remote_debugging(self, port, url):
# Запуск Chrome в режиме удаленной отладки
def open_chrome():
chrome_cmd = f"{self.chrome_path} --remote-debugging-port={port} --user-data-dir=remote-profile {url}"
os.system(chrome_cmd)
chrome_thread = threading.Thread(target=open_chrome)
chrome_thread.start()
print(f"port: {port}")
После запуска кода Chrome будет открыт в режиме удаленной отладки. В консоли отображается порт для подключения, копируем его и записываем его в вызове драйвера:
# Этот код нужно прописать в файле, где идет работа с Selenium
from selenium import webdriver
def setup_webdriver(port):
chrome_options = webdriver.ChromeOptions()
chrome_options.add_experimental_option("debuggerAddress", f"127.0.0.1:{port}")
driver = webdriver.Chrome(options=chrome_options)
return driver
# Указать порт
driver = setup_webdriver("Укажите порт")
Теперь при обращении к driver мы будем обращаться к Chrome, запущенному в режиме отладки. Можно выполнять любую последовательность, сколько угодно выискивать подходящие селекторы, править код в файле работы с Selenium и повторно обращаться к сессии webdriver. Можно спокойно пройти весь путь, который нужно сделать используя Selenium без перезапусков сессий и отладить процесс работы программы.