使用geckodriver / Firefox的`driver.execute_script(“ ...”)`和driver.get(“ javascript:...”`)有什么区别?

时间:2019-06-06 09:14:49

标签: python selenium webdriver geckodriver http-referer

我认为,这个问题与硒的内部运作有关。在另一篇Referer missing in HTTP header of Selenium request中,很明显跑步与跑步之间存在差异

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

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

后一个命令将与请求一起发送Referer标头,前一个则不会。

这是否是所需的行为还是错误,并且两个命令都应发送Referer并不重要。另外,window.location.href = ...仅是示例。

但是,显然,如果使用命令driver.execute_script("...")driver.get("javascript: ..."运行JavaScript不会产生相同的结果,那么它们之间肯定会有区别。因此,问题更多的是两个命令内部没有调用相同的Selenium代码。

这两个命令有什么区别?

2 个答案:

答案 0 :(得分:5)

问题的答案取决于驱动程序正在运行的浏览器。 Selenium本身不实现这些功能-它仅调用底层驱动程序的API。

看看WebDriver.execute_scriptWebDriver.get的来源-它们都只调用self.execute,它向Webdriver执行请求。

例如,Chrome自2013开始不支持带有WebDriver.get的'javascript:'网址,就像在Chrome的网络驱动程序implementation中看到的蜜蜂一样。

直接运行JS脚本与导航到“ javascript URL”之间的实际区别嵌入在每个浏览器的实现中,并且可能不是很简单。您提到的差异的可能原因可能是实现细节-可能是浏览器(在产生您提到的结果时使用的浏览器)仅在高级导航命令的上下文中发送Referer标头(driver.get),因此没有在普通的javascript触发的导航中包含一个。

答案 1 :(得分:1)

TL; DR:我对此很好奇,正在开始回答。然后出城了。

我不是要从@Ni偷取分数或任何东西。正如他指出的那样,getexecute_script调用self.execute,而后者依次调用Command类中的方法。例如,Command.GETCommand.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,因此这是“用于编组命令”(?)或其中一部分的服务...

(红宝石当量:https://github.com/SeleniumHQ/selenium/blob/master/rb/lib/selenium/webdriver/remote/commands.rb