【问题标题】:How to open a new window on a browser using Selenium WebDriver for python?如何使用 Selenium WebDriver for python 在浏览器上打开一个新窗口?
【发布时间】:2013-06-23 22:05:16
【问题描述】:

我正在尝试使用 selenium for python 在浏览器中打开一个新选项卡或一个新窗口。打开新标签页或新窗口并不重要,重要的是打开浏览器的第二个实例。

我已经尝试了几种不同的方法,但都没有成功。

  1. 切换到一个不存在的窗口,希望它能在找不到该窗口时打开一个新窗口:

    driver.switch_to_window(None)

  2. 遍历打开的窗口(虽然目前只有一个)

    for handle in driver.window_handles:
        driver.switch_to_window(handle)
    
  3. 试图模拟键盘按键

    from selenium.webdriver.common.keys import Keys
    driver.send_keys(Keys.CONTROL + 'T')
    

这个问题尤其是似乎不可能将密钥直接发送到浏览器,只能发送到这样的特定元素:

driver.find_element_by_id('elementID').send_keys(Keys.CONTROL + 'T')

但是,当这样的命令被发送到一个元素时,它似乎什么都不做。我试图找到页面上最顶层的 HTML 元素并将密钥发送到该元素,但再次失败:

driver.find_element_by_id('wrapper').send_keys(Keys.CONTROL + 'T')

我在网上找到了另一个版本,但无法验证其有效性或缺乏,因为我不确定需要导入哪个类/模块

act = ActionChains(driver)
act.key_down(browserKeys.CONTROL)
act.click("").perform()
act.key_up(browserKeys.CONTROL)

非常相似但语法不同的东西(我不确定其中一种或两种语法是否正确)

actions.key_down(Keys.CONTROL)
element.send_keys('t')
actions.key_up(Keys.CONTROL)

【问题讨论】:

  • 这仅适用于工作头浏览器、Firefox、Chrome 等。例如 PhantomJS 没有键绑定,您需要使用正确的 javascript 代码调用 execute_script()。如果您需要传递项目/cookie,只需创建一个 target=_blank 链接然后单击它。
  • 几乎与Open web in new tab Selenium + Python - Stack Overflow 重复——除了它在新标签页中打开;然而,大多数时候选项卡/窗口都是由 selenium 处理的

标签: python selenium selenium-webdriver window


【解决方案1】:

你要不要做这样的事情

driver = webdriver.Firefox() #First FF window
second_driver = webdriver.Firefox() #The new window you wanted to open

根据您要与之交互的窗口,您相应地发送命令

print driver.title #to interact with the first driver
print second_driver.title #to interact with the second driver

对于所有反对的选民:


OP 要求“it is only important that a second instance of the browser is opened.”。这个答案不包括每个人的用例的所有可能要求。 下面的其他答案可能适合您的特定需求。

【讨论】:

  • 完美!如此简单,但它完全达到了我的要求,谢谢。但是,有没有一种方法可以概括该命令,以便无论使用何种浏览器,它都能正常工作?也许是一种派生第一个驱动程序中使用的浏览器以打开第二个驱动程序的方法?
  • @"也许有一种方法可以派生第一个驱动程序中使用的浏览器来打开第二个驱动程序?" - 我不确定这会增加什么价值。即使确实如此。对不起,我不知道该怎么做。无论如何,如果您发现此答案有帮助,您可以将其标记为答案,这就是 - meta.stackexchange.com/questions/5234/…
  • 这实际上打开了 Firefox 的第二个实例。 “现有浏览器中的新窗口”与“全新的浏览器应用程序”之间的区别对于某些测试用例可能很重要。
  • 当您打开多个浏览器实例时,它可能会占用大量内存。每个实例将占用超过 100 MB。我建议不要这样做。
  • 如果您需要在共享会话时打开一个新窗口等怎么办?如果您真的只需要 2 个窗口并且根本不关心用户将如何与浏览器进行实际交互,则此答案有效。否决票,因为“如何使用 Selenium WebDriver for python 打开一个新窗口在浏览器上?”建议他们想要一个来自现有浏览器或驱动程序的新窗口。这就是我在谷歌中寻找的东西,而你的答案根本没有这样做。也许您也应该包括其他方法来执行此操作?
【解决方案2】:

您可以使用execute_script打开新窗口。

driver = webdriver.Firefox()
driver.get("https://linkedin.com")
# open new tab
driver.execute_script("window.open('https://twitter.com')")
print driver.current_window_handle

# Switch to new window
driver.switch_to.window(driver.window_handles[-1])
print " Twitter window should go to facebook "
print "New window ", driver.title
driver.get("http://facebook.com")
print "New window ", driver.title

# Switch to old window
driver.switch_to.window(driver.window_handles[0])
print " Linkedin should go to gmail "
print "Old window ", driver.title
driver.get("http://gmail.com")
print "Old window ", driver.title

# Again new window
driver.switch_to.window(driver.window_handles[1])
print " Facebook window should go to Google "
print "New window ", driver.title
driver.get("http://google.com")
print "New window ", driver.title

【讨论】:

  • 这里没有提到 Jquery 的加载,你假设它是由上一个用 PhantomJS 加载的 url 加载的。此外,javascript 代码是相同的,所以只需 driver.execute_script("window.open('https://twitter.com')") 即可。
  • 注意:这可能会在新标签或新窗口中打开,取决于 Firefox 设置。详情请参阅my answer
【解决方案3】:

我建议在 Firefox 上使用CTRL + N 命令来减少内存使用量,而不是创建新的浏览器实例。

import selenium.webdriver as webdriver
from selenium.webdriver.common.keys import Keys

browser = webdriver.Firefox()
body = browser.find_element_by_tag_name('body')
body.send_keys(Keys.CONTROL + 'n')

Dhiraj已经提到了切换和控制窗口的方式。

【讨论】:

  • 这是最好的解决方案,因为窗口是在同一个驱动程序中打开的。但这不适用于 XML 页面。
  • @fx-kirin 在firefox浏览器中不起作用?
  • 是的,它停止工作了。见*.com/questions/28431765/…
【解决方案4】:
driver = webdriver.Chrome()
driver.execute_script("window.open('');")
driver.get('first url')

driver.switch_to.window(driver.window_handles[1])
driver.get('second url')

【讨论】:

    【解决方案5】:

    在 JavaScript 中,窗口和选项卡没有区别。

    driver.window_handles 认为两者相同。

    但是,如果需要打开一个新窗口,有几种方法:(有关所需的导入,请参阅[3])

    1. 模拟 ctrl+N。 不适用于新版本。见this comment

      (
              ActionChains(driver)
              .key_down(Keys.CONTROL)
              .send_keys('n')
              .key_up(Keys.CONTROL)
              .perform()
              )
      

      body = driver.find_element_by_tag_name('body')
      body.send_keys(Keys.CONTROL + 'n')
      
    2. 按住 shift 键,然后单击页面上的链接 -- 仅当页面上有任何链接时才有效。

      (
              ActionChains(driver)
              .key_down(Keys.SHIFT)
              .click(driver.find_element_by_tag_name("a"))
              .key_up(Keys.SHIFT)
              .perform()
              )
      

      如果没有,可以创建一个...(修改当前页面!)

      driver.execute_script('''{
          let element=document.createElement("a");
          element.href="about:home";
          element.id="abc"
          element.text="1";
          document.body.appendChild(element);
          element.scrollIntoView();
          }''')
      
      (
              ActionChains(driver)
              .key_down(Keys.SHIFT)
              .click(driver.find_element_by_id("abc"))
              .key_up(Keys.SHIFT)
              .perform()
              )
      

      ... 或导航到一个页面。 (如果你在会话开始时这样做, 或打开一个新标签来执行此操作并稍后关闭它,这不是问题)

      driver.get("data:text/html,<a href=about:blank>1</a>")
      (
              ActionChains(driver)
              .key_down(Keys.SHIFT)
              .click(driver.find_element_by_tag_name("a"))
              .key_up(Keys.SHIFT)
              .perform()
              )
      

      看起来像个黑客。

    3. (对于 Firefox)关闭“在选项卡中打开链接而不是新窗口”选项, 然后执行window.open()

      来自Settings to open browser links in new tab, and external links in new window | Firefox Support Forum | Mozilla SupportBrowser.link.open_newwindow - MozillaZine Knowledge Base

      browser.link.open_newwindow - 用于 Firefox 标签中的链接

      3 = 将新窗口转移到新标签页(默认)
      2 = 允许链接打开一个新窗口
      1 = 强制新窗口进入同一个标签页

      此选项应设置为 2。[2]

      注意,根据https://github.com/SeleniumHQ/selenium/issues/2106#issuecomment-320238039-permalink 不可能使用FirefoxProfile [1] 设置选项。

      options=webdriver.FirefoxOptions()
      options.set_preference("browser.link.open_newwindow", 2)
      driver=Firefox(firefox_options=options)
      
      driver.execute_script("window.open()")
      
    4. 对于 Selenium 4.0.0(预发布。目前您可以使用例如pip install selenium==4.0.0b4 安装它),可以这样做:

      driver.execute(
          selenium.webdriver.remote.command.Command.NEW_WINDOW,
          {"type": "window"}
      )
      

      技术取自this answer


    [1]:在当前版本中,出于某种原因,这可行并将browser.link.open_newwindow 设置为2

    fp = webdriver.FirefoxProfile()
    fp.set_preference("browser.link.open_newwindow", 3)
    fp.default_preferences["browser.link.open_newwindow"]=3
    fp.DEFAULT_PREFERENCES["browser.link.open_newwindow"]=3
    driver=Firefox(firefox_profile=fp)
    

    虽然这使选项值保持在 3

    driver=Firefox()
    

    [2]:如果值设置为3window.open() 将在新选项卡而不是新窗口中打开。

    [3]:所有必需的导入:

    from selenium import webdriver
    from selenium.webdriver import Firefox, FirefoxProfile
    from selenium.webdriver.common.keys import Keys
    from selenium.webdriver.common.action_chains import ActionChains
    

    [4]:此答案仅涵盖如何打开新窗口。要切换到该新窗口并返回,请使用WebDriverWaitdriver.switch_to.window(driver.window_handles[i])。参考 https://*.com/a/51893230/5267751了解更多详情。

    【讨论】: