Оптимизация высокоскоростного взаимодействия браузера с Selenium / Puppeteer - PullRequest
1 голос
/ 05 августа 2020

I wi sh, чтобы создать сценарий, который может взаимодействовать с любой веб-страницей с минимально возможной задержкой, за исключением задержки сети. Это должно использоваться для арбитражной торговли, поэтому любые советы в этом направлении приветствуются.

Мой текущий подход заключается в использовании Selenium с Python, поскольку я новичок в парсинге веб-страниц. Однако я исследовал некоторые подходы, и из моих выводов кажется, что Selenium имеет значительную задержку (см. Результаты тестов ниже) Я упоминаю и другие вещи помимо этого в этом вопросе, но основное внимание уделяется на Selenium.

В общем, мне нужно отправить запрос на ПОКУПКУ или ПРОДАЖУ любому брокеру, с которым я сейчас работаю. Используя клиент веб-браузера, я нашел несколько подходов для этого:

1. Actually clicking the button  
    a. Use Selenium to Click the button with the corresponding request      
    b. Use Puppeteer to Click  
    c. Use Pynput or other direct mouse input manipulation

2. Reverse-engineering the request and sending it directly without clicking any buttons

Теперь задержку отправки этого запроса необходимо минимизировать насколько возможно. Сетевая задержка находится вне нашего контроля с целью этой оптимизации. Я проверил подходы для 1., открыв страницу стандартным способом, либо с кукловодом и селеном, а затем подождав несколько секунд. Пока сценарий ждет, я ввел в браузер следующий код: $x('//*[@id="id_demo_webfront"]/iframe')[0].contentDocument.body.addEventListener('click', (data => console.log(new Date().getTime())), true); Цель этого кода - войти в консоль в текущее время, когда щелчок зарегистрирован браузером. Затем я вхожу в свой python (Selenium, pynput) / javascript (Puppeteer) скрипт текущего времени прямо перед тем, как нажать. Я использую Ubunutu 18.04, а не Windows, поэтому мои системные часы должны иметь хорошее разрешение. Дополнительные сведения об этом здесь и здесь .

Фактические результаты, все они были запущены на одной и той же веб-странице несколько раз, примерно для 10 кликов при каждом запуске: 1. a. ~80ms 1. b. ~10-30ms 1. c. ~5-10ms

Для 2. задержку достоверно не проверял. Идея этого подхода состоит в том, чтобы внедрить функцию, которая при запуске будет отправлять запрос, в точности напоминающий запрос, который будет отправлен при нажатии кнопки. Я не тестировал задержку между выдачей команды для запуска такой внедренной функции и ее фактическим запуском, однако я ожидаю, что этот подход будет еще быстрее, в основном создавая свой собственный клиент для взаимодействия с любым API брокера. имеет на бэкэнде.

Из результатов довольно ясно, что запуск команд мыши кажется самым быстрым, но мне также труднее всего реализовать его надежно. Кроме того, мне кажется, что кукловод работает быстрее по всем направлениям, но я предпочитаю селен в python для простоты разработки, и мне было интересно, есть ли какие-нибудь советы и идеи, чтобы ускорить те задержки, с которыми я сталкиваюсь.

Итоги:

Почему у Selenium с Python такая задержка для выдачи команд и можно ли ее улучшить? Почему у Puppeteer меньше задержка при взаимодействии с одним и тем же браузером?

Некоторые фрагменты кода моего подхода:

class DMMPageInterface:

    # These are part of the interface script, self.page is the webpage after initialization
    def __init__(self, config):
        self.bid_price = self.page.get_element('xpath goes here')
        ...

    # Mostly only the speed of this operation matters, sending the trade request
    def bid_click(self):
        logger.debug("Clicking bid")
        if USE_MOUSE:
            mouse.position = (720,390)
            mouse.click(Button.left, 1)
        else:
            self.bid_price.click()

1 Ответ

1 голос
/ 05 августа 2020

Довольно много вопросов!

«Почему у Selenium с Python такая задержка для выдачи команд»

I у нас нет никаких прямых ссылочных доказательств для этого, но задержка селена, вероятно, связана с объемом работы, которую он должен выполнить. Он был создан для тестирования, а не для производительности. Разница в том, что самая ценная часть теста - это то, что он ДОЛЖЕН выполняться надежно, если он медленнее и выполняет больше проверок, чтобы сделать его более надежным, чем так оно и есть. Вы по-прежнему получаете значительный прирост производительности по сравнению с ручным тестированием, и это то, что мы заменяем.

Здесь вам понадобится надежность - и я вижу, вы упоминаете об этом в своем вопросе. Замечательно, если у вас есть торговый скрипт, который может завершить действие за <1 с, но что, если он терпит неудачу в 5% случаев? Насколько это вызовет проблемы? </p>

Selenium также должен отображать GUI, а затем, в зависимости от того, как вы идентифицируете свои объекты, ему необходимо сканировать всю DOM для того, что вы хотите. Локаторы Generi c логически займут больше времени.

Большая сила Selenium - это простота и возможность синхронизации. Во многих статьях SO много говорится о webdriverwait (что отлично подходит для синхронизации внутристраничных скриптов c), но есть также хорошее распознавание времени ожидания загрузки страницы. т.е. нет смысла нажимать кнопку до того, как весь исходный код будет загружен.

«Почему у Puppeteer меньше задержка при взаимодействии с тем же браузером?» Puppeteer работает с chrome devtools - селен работает с DOM. Таким образом, эти двое взаимодействуют по-разному. Очевидно, кукловод предназначен только для chrome, но селен может go практически для любого браузера. Для вас это может не быть проблемой, если вам не важны возможности кроссбраузерности.

Однако - насколько это на самом деле быстрее?

В таймингах выполнения вы также можете захотеть до фактор всего жизненного цикла того, что вы стремитесь сделать, а именно: время загрузки браузера и время отображения страницы. Из вашего рассказа вы хотите что-то купить или продать. Итак, вы запускаете сценарий - сколько времени проходит от нажатия GO до конечного результата. Скорее всего, вам потребуется синхронизация, и именно здесь кукловод может быть не таким сильным (или вам потребуется гораздо больше времени, чтобы разобраться в этом). задержка насколько возможно », , но сначала нужно перейти на страницу и привести ее в нужное состояние. Меня бы не волновали миллисекунды на действие. Открытие chrome не является самым быстрым действием само по себе, и ваш общий миллисекундный тест становится от> секунд до минут.

Когда у вас есть полный сценарий селена, занимающий 65 секунд, и сценарий кукольника, занимающий 64 секунды, общее рассмотрение Изменения: -)

Некоторые другие варианты, о которых стоит подумать, если вам действительно нужна скорость:

  • Попробуйте запустить selenium без головы - нет gui, меньше ресурсов, работает быстрее. (google it): -)
  • Попробуйте другие браузеры
  • Если вы все о скорости - полностью откажитесь от GUI. Создайте сценарий API или начните исследовать использование сценариев производительности (например, jmeter или loadrunner).
  • Другой вариант, который не является селеном или кукловодом, - это javascript напрямую в браузере
  • Попробуйте свои тесты скорости с помощью других бесплатных веб-инструментов, например cypress или драматурга Microsoft - они напрямую взаимодействуют с JS в браузере и хвастаться некоторыми превосходными встроенными функциями стабильности.

Если бы это был я, и речь шла об одном действующем действии - мой первый порт вызова выполнял бы его на уровне API. Есть много ресурсов и сайтов для практики, которые помогут вам начать работу, и нет браузера для рендеринга, почти нет ничего, кроме сетевой задержки. Это реальный способ сохранить его в виде субсекундного скрипта.

Последняя мысль, когда вы спрашиваете: « можно ли улучшить »: если у вас есть код, могут быть другие способы сделать его быстрее. Поделитесь своим сценарием, и я уверен, что люди с удовольствием потратят свои 2 цента на то, как вы можете его оптимизировать: -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...