В чем разница между `driver.execute_script (" ... ")` и `driver.get (" javascript: ... "` с geckodriver / Firefox? - PullRequest
7 голосов
/ 06 июня 2019

Я думаю, этот вопрос касается внутренней работы Selenium. В другом сообщении Referer отсутствует в заголовке HTTP запроса Selenium , становится очевидным, что существует разница между выполнением

driver.execute_script("window.location.href = '{}';".format(url))
*

и * 1006

driver.get("javascript: window.location.href = '{}'".format(url))

Последняя команда отправит заголовок Referer с запросом, первый не отправит.

На данном этапе не имеет значения, является ли это желаемым поведением или ошибкой, и обе команды должны отправлять Referer. Кроме того, window.location.href = ... является только примером.

Тем не менее, очевидно, что между выполнением JavaScript с помощью команд driver.execute_script("...") и driver.get("javascript: ..." должна быть разница, если они не дают одинакового результата. Поэтому вопрос скорее в том, что обе команды не вызывают внутри один и тот же код Selenium.

В чем разница между обеими командами?

Ответы [ 2 ]

5 голосов
/ 15 июня 2019

Ответ на ваш вопрос зависит от браузера, в котором работает ваш драйвер. Сам Selenium не реализует эти функции - он просто вызывает API базового драйвера.

Взгляните на источник WebDriver.execute_script и WebDriver.get - они оба просто вызывают self.execute, который выполняет запрос к веб-драйверу.

Например, Chrome не поддерживает URL 'javascript:' с WebDriver.get, начиная с 2013 , что можно увидеть в реализации веб-драйвера Chromium .

Фактическая разница между прямым запуском сценария JS и переходом к «URL-адресу javascript» глубоко заложена в реализации каждого браузера и может быть не очень простой. Возможной причиной упомянутой разницы может быть деталь реализации - возможно, браузер (который использовался, когда были получены упомянутые вами результаты) отправляет заголовок Referer, только когда он находится в контексте высокоуровневой команды навигации (driver.get), и, следовательно, не включили его в простую навигацию, инициированную JavaScript.

1 голос
/ 12 июня 2019

TL; DR: Мне было любопытно, и я начал отвечать.Затем уехал из города.

Я не пытаюсь переманивать очки или что-то из @Ni.Как он указывает, get и execute_script вызывают self.execute, что, в свою очередь, вызывает метод из класса Command.Например, Command.GET или Command.EXECUTE_SCRIPT.И вот тут след для меня остыл ...


исходный код

https://github.com/SeleniumHQ/selenium/blob/master/py/selenium/webdriver/remote/webdriver.py

def get(self, url):
    """
    Loads a web page in the current browser session.
    """
    self.execute(Command.GET, {'url': url})

и

def execute_script(self, script, *args):
    """
    Synchronously Executes JavaScript in the current window/frame.

    :Args:
     - script: The JavaScript to execute.
     - \*args: Any applicable arguments for your JavaScript.

    :Usage:
        driver.execute_script('return document.title;')
    """
    converted_args = list(args)
    command = None
    if self.w3c:
        command = Command.W3C_EXECUTE_SCRIPT
    else:
        command = Command.EXECUTE_SCRIPT

    return self.execute(command, {
        'script': script,
        'args': converted_args})['value']

, который указывает на

https://github.com/SeleniumHQ/selenium/blob/master/py/selenium/webdriver/remote/command.py

class Command(object):
    """
    Defines constants for the standard WebDriver commands.
    While these constants have no meaning in and of themselves, they are
    used to marshal commands through a service that implements WebDriver's
    remote wire protocol:
        https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol
    """

и

https://github.com/SeleniumHQ/selenium/blob/master/py/selenium/webdriver/remote/remote_connection.py#L142 показывает закрытый метод с именем self._commands, который представляет собой словарь, содержащийкоманды, которые отражают синтаксис, видимый в ..remote/webdriver.py

Например: Command.GET: ('POST', '/session/$sessionId/url') против self.execute(Command.GET, {'url': url})

Конечные точки в self._commands соответствуют https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#command-reference,, поэтому этоСлужба "используется для маршалинга команд" (?) или ее часть ...

(ruby эквивалент: https://github.com/SeleniumHQ/selenium/blob/master/rb/lib/selenium/webdriver/remote/commands.rb)

...