Повторное использование существующего сеанса браузера в Selenium
Сравнение Selenium и UFT
Для тех, кто имеет опыт работы с QTP / UFT, возможность протестировать один и тот же браузер после разрыва соединения обычно несложно.
1. systemutil.run "iexplore.exe"
2. x = 2/0
3. Browser("index:=0").navigate ("http://www.google.com")
Если мы запустим приведенный выше код в QTP / UFT, он выдаст ошибку в строке № 2, и мы сможем повторно запустить код из строки № 3, и он будет работать и перемещаться внутри браузера, который мы открыли ранее.
UFT также работает, когда браузер запускается вручную, а не через скрипт. Однако в Selenium это невозможно из-за архитектурных различий.
Поскольку разработчики Selenium не видят в этом особого смысла, они категорически против добавления этого в код Selenium.
В этой статье мы увидим более чистый и эффективный способ добиться повторного использования браузера.
Запуск браузера в Selenium
Чтобы запустить браузер в Selenium с использованием Python, мы просто импортируем веб-драйвер и запускаем браузер.
from selenium import webdriver
driver = webdriver.Chrome()
Если мы запустим приведенный выше код, он запустит браузер и выйдет. Поскольку созданный нами объект браузера был уничтожен, мы больше не можем управлять этим браузером с помощью скрипта. Это зомби-браузер с точки зрения Selenium.
Теперь, когда мы создаем объект WebDriver (Firefox, сhromer или любой другой браузер) в Selenium, происходит несколько вещей:
- Запускается предполагаемый агент браузера (chromedriver для chrome, geckodriver для Firefox и т. Д.)
- Создается исполнитель команд. Этот объект отвечает за отправку команд агенту.
- Устанавливается новый сеанс с агентом, который, в свою очередь, связывается с браузером.
session_id
создается для идентификации сеанса.
Информация из шагов №2 и №3 важна для нас, чтобы мы могли воссоздать объект драйвера. Итак, давайте обновим наш скрипт, чтобы вывести эту информацию.
from selenium import webdriver
driver = webdriver.Chrome()
executor_url = driver.command_executor._url
session_id = driver.session_id
print session_id
print executor_url
driver.get("http://tarunlalwani.com")
Пример вывода приведенного выше кода приведен ниже:
7397a385-7661-0449-9e0a-902355617485
http://127.0.0.1:51259
Создание драйвера с использованием идентификатора сеанса и Command Executor
Итак, теперь у нас есть session_id
и executor_url
. Попробуем воссоздать сеанс.
Моей первой попыткой было создать драйвер с помощью RemoteWebDriver
или WebDriver
from selenium import webdriver
driver = webdriver.Chrome()
executor_url = driver.command_executor._url
session_id = driver.session_id
driver.get("http://tarunlalwani.com")
print session_id
print executor_url
driver2 = webdriver.Remote(command_executor=executor_url, desired_capabilities={})
driver2.session_id = session_id
print driver2.current_url
Когда мы запускаем приведенный выше код, он печатает URL-адрес в конце. Это означает, что мы смогли воссоздать объект драйвера для браузера Chrome.http://tarunlalwani.com
Тестирование в браузере Firefox
Мы протестировали наш предыдущий подход в браузере Chrome. Давайте также протестируем наше решение в Firefox:
from selenium import webdriver
driver = webdriver.Firefox()
executor_url = driver.command_executor._url
session_id = driver.session_id
driver.get("http://tarunlalwani.com")
print session_id
print executor_url
driver2 = webdriver.Remote(command_executor=executor_url, desired_capabilities={})
driver2.session_id = session_id
print driver2.current_url
Ошибка в нашем скрипте в следующем:
driver2 = webdriver.Remote(command_executor=executor_url, desired_capabilities={})
Traceback (most recent call last):
File "/Users/tarun.lalwani/Desktop/tarunlalwani.com/tarunlalwani/content/code/selenium_enumerator.py", line 101, in <module>
driver2 = webdriver.Remote(command_executor=executor_url, desired_capabilities={})
File "/usr/local/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py", line 98, in __init__
self.start_session(desired_capabilities, browser_profile)
File "/usr/local/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py", line 188, in start_session
response = self.execute(Command.NEW_SESSION, parameters)
File "/usr/local/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py", line 252, in execute
self.error_handler.check_response(response)
File "/usr/local/lib/python2.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 194, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: Session is already started
Ошибка возникает в response = self.execute(Command.NEW_SESSION, parameters)
. Проблема в том, что снова geckodriver
не поддерживает newSession
. Следовательно, нужен способ переопределить функцию выполнения при создании драйвера.
Мы создаем новую функцию, которая возвращает фиктивный ответ на newSession с нашим sessionId. Обновленный код приведен ниже:
from selenium import webdriver
driver = webdriver.Firefox()
executor_url = driver.command_executor._url
session_id = driver.session_id
driver.get("http://tarunlalwani.com")
print session_id
print executor_url
def create_driver_session(session_id, executor_url):
from selenium.webdriver.remote.webdriver import WebDriver as RemoteWebDriver
# Save the original function, so we can revert our patch
org_command_execute = RemoteWebDriver.execute
def new_command_execute(self, command, params=None):
if command == "newSession":
# Mock the response
return {'success': 0, 'value': None, 'sessionId': session_id}
else:
return org_command_execute(self, command, params)
# Patch the function before creating the driver object
RemoteWebDriver.execute = new_command_execute
new_driver = webdriver.Remote(command_executor=executor_url, desired_capabilities={})
new_driver.session_id = session_id
# Replace the patched function with original function
RemoteWebDriver.execute = org_command_execute
return new_driver
driver2 = create_driver_session(session_id, executor_url)
print driver2.current_url
Этот код отлично работает. Единственное предостережение в том, что мы теряем фактические возможности, которые браузер возвращал при запуске. В большинстве случаев это не должно иметь большого значения.
Браузер в режиме ожидания
В одном из наших проектов парсинга мы хотим завершить наш скрипт и оставить браузер в режиме ожидания. При повторном запуске скрипта он повторно использует последний браузер и продолжает работу. Это может стать важным фактором при очистке сайтов с более высокой степенью защиты.
Функциональность фреймворка
Одна из наших платформ автоматизации, позволяющая пользователям выполнять коды автоматизации из любой точки. Для реализации такой функции было важно иметь возможность воссоздать последний драйвер сеанса.