我认为,这个问题与硒的内部运作有关。在另一篇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代码。
这两个命令有什么区别?
答案 0 :(得分:5)
问题的答案取决于驱动程序正在运行的浏览器。 Selenium本身不实现这些功能-它仅调用底层驱动程序的API。
看看WebDriver.execute_script
和WebDriver.get
的来源-它们都只调用self.execute
,它向Webdriver执行请求。
例如,Chrome自2013开始不支持带有WebDriver.get
的'javascript:'网址,就像在Chrome的网络驱动程序implementation中看到的蜜蜂一样。
直接运行JS脚本与导航到“ javascript URL”之间的实际区别嵌入在每个浏览器的实现中,并且可能不是很简单。您提到的差异的可能原因可能是实现细节-可能是浏览器(在产生您提到的结果时使用的浏览器)仅在高级导航命令的上下文中发送Referer
标头(driver.get
),因此没有在普通的javascript触发的导航中包含一个。
答案 1 :(得分:1)
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,因此这是“用于编组命令”(?)或其中一部分的服务...
(红宝石当量:https://github.com/SeleniumHQ/selenium/blob/master/rb/lib/selenium/webdriver/remote/commands.rb)