Python 如何切换到 Selenium 中的活动选项卡?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28715942/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 03:38:57  来源:igfitidea点击:

How do I switch to the active tab in Selenium?

pythonseleniumgoogle-chrome-extension

提问by Uri

We developed a Chrome extension, and I want to test our extension with Selenium. I created a test, but the problem is that our extension opens a new tab when it's installed, and I think I get an exception from the other tab. Is it possible to switch to the active tab I'm testing? Or another option is to start with the extension disabled, then login to our website and only then enable the extension. Is it possible? Here is my code:

我们开发了一个 Chrome 扩展,我想用 Selenium 测试我们的扩展。我创建了一个测试,但问题是我们的扩展程序在安装时打开了一个新选项卡,我想我从另一个选项卡中得到了一个异常。是否可以切换到我正在测试的活动选项卡?或者另一种选择是从禁用扩展程序开始,然后登录我们的网站,然后才启用扩展程序。是否可以?这是我的代码:

def login_to_webapp(self):
    self.driver.get(url='http://example.com/logout')
    self.driver.maximize_window()
    self.assertEqual(first="Web Editor", second=self.driver.title)
    action = webdriver.ActionChains(driver=self.driver)
    action.move_to_element(to_element=self.driver.find_element_by_xpath(xpath="//div[@id='header_floater']/div[@class='header_menu']/button[@class='btn_header signature_menu'][text()='My signature']"))
    action.perform()
    self.driver.find_element_by_xpath(xpath="//ul[@id='signature_menu_downlist'][@class='menu_downlist']/li[text()='Log In']").click()
    self.driver.find_element_by_xpath(xpath="//form[@id='atho-form']/div[@class='input']/input[@name='useremail']").send_keys("[email]")
    self.driver.find_element_by_xpath(xpath="//form[@id='atho-form']/div[@class='input']/input[@name='password']").send_keys("[password]")
    self.driver.find_element_by_xpath(xpath="//form[@id='atho-form']/button[@type='submit'][@class='atho-button signin_button'][text()='Sign in']").click()

The test fails with ElementNotVisibleException: Message: element not visible, because in the new tab (opened by the extension) "Log In" is not visible (I think the new tab is opened only after the command self.driver.get(url='http://example.com/logout')).

测试失败ElementNotVisibleException: Message: element not visible,因为在新选项卡(由扩展程序打开)中“登录”不可见(我认为新选项卡仅在命令之后打开self.driver.get(url='http://example.com/logout'))。

Update: I found out that the exception is not related to the extra tab, it's from our website. But I closed the extra tab with this code, according to @aberna's answer:

更新:我发现异常与额外选项卡无关,它来自我们的网站。但根据@aberna 的回答,我用此代码关闭了额外的选项卡:

def close_last_tab(self):
    if (len(self.driver.window_handles) == 2):
        self.driver.switch_to.window(window_name=self.driver.window_handles[-1])
        self.driver.close()
        self.driver.switch_to.window(window_name=self.driver.window_handles[0])

After closing the extra tab, I can see my tab in the video.

关闭额外标签后,我可以在视频中看到我的标签。

采纳答案by aberna

Some possible approaches:

一些可能的方法:

1- Switch between the tabs using the send_keys (CONTROL + TAB)

1- 使用 send_keys (CONTROL + TAB) 在选项卡之间切换

self.driver.find_element_by_tag_name('body').send_keys(Keys.CONTROL + Keys.TAB)

2- Switch between the tabs using the using ActionsChains (CONTROL+TAB)

2- 使用 ActionsChains (CONTROL+TAB) 在选项卡之间切换

actions = ActionChains(self.driver)      
actions.key_down(Keys.CONTROL).key_down(Keys.TAB).key_up(Keys.TAB).key_up(Keys.CONTROL).perform()

3- Another approach could make usage of the Selenium methods to check current window and move to another one:

3- 另一种方法可以使用 Selenium 方法来检查当前窗口并移动到另一个窗口:

You can use

您可以使用

driver.window_handles

to find a list of window handles and after try to switch using the following methods.

查找窗口句柄列表,然后尝试使用以下方法进行切换。

- driver.switch_to.active_element      
- driver.switch_to.default_content
- driver.switch_to.window

For example, to switch to the last opened tab, you can do:

例如,要切换到上次打开的选项卡,您可以执行以下操作:

driver.switch_to.window(driver.window_handles[-1])

回答by Avaricious_vulture

This actually worked for me in 3.x:

这实际上在 3.x 中对我有用:

driver.switch_to.window(driver.window_handles[1])

window handles are appended, so this selects the second tab in the list

附加了窗口句柄,因此这将选择列表中的第二个选项卡

to continue with first tab:

继续第一个选项卡:

driver.switch_to.window(driver.window_handles[0])

回答by CONvid19

The accepted answer didn't work for me.
To open a new tab and have selenium switch to it, I used:

接受的答案对我不起作用。
要打开一个新选项卡并将 selenium 切换到它,我使用了:

driver.execute_script('''window.open("https://some.site/", "_blank");''')
sleep(1) # you can also try without it, just playing safe
driver.switch_to.window(driver.window_handles[-1]) # last opened tab handle  
# driver.switch_to_window(driver.window_handles[-1]) # for older versions

if you need to switch back to the main tab, use:

如果您需要切换回主选项卡,请使用:

driver.switch_to.window(driver.window_handles[0])


Summary:

概括:

The window_handlescontains a list of the handlesof opened tabs, use it as argument in switch_to.window()to switch between tabs.

window_handles包含的列表handles中打开tabs,用它作为参数在switch_to.window()标签之间切换。

回答by Talmtikisan

Pressing ctrl+tor choosing window_handles[0]assumes that you only have one tab open when you start.

ctrl+t或选择window_handles[0]假定您在开始时只打开一个选项卡。

If you have multiple tabs open then it could become unreliable.

如果您打开了多个选项卡,则它可能会变得不可靠。

This is what I do:

这就是我所做的:

old_tabs=self.driver.window_handles
#Perform action that opens new window here
new_tabs=self.driver.window_handles
for tab in new_tabs:
     if tab in old tabs:
          pass
     else:
          new_tab=tab
driver.switch_to.window(new_tab)

This is something that would positively identify the new tab before switching to it and sets the active window to the desired new tab.

这是在切换到新选项卡之前肯定会识别它并将活动窗口设置为所需的新选项卡的东西。

Just telling the browser to send ctrl+tabdoes not work because it doesn't tell the webdriver to actually switch to the new tab.

只是告诉浏览器发送ctrl+tab不起作用,因为它不会告诉 webdriver 实际切换到新选项卡。

回答by Gus Bustillos

Found a way using ahk library. Very easy for us non-programmers that need to solve this problem. used Python 3.7.3

找到了一种使用 ahk 库的方法。对于我们需要解决这个问题的非程序员来说非常容易。使用 Python 3.7.3

Install ahk with. pip install ahk

安装ahk。pip安装ahk

import ahk
from ahk import AHK
import selenium
from selenium import webdriver
from selenium.webdriver.chrome.options import Options


options = webdriver.ChromeOptions()
options.add_experimental_option("excludeSwitches", ['enable-automation']); #to disable infobar about chrome controlled by automation. 
chrome_options.add_argument('--start-maximized') 
chromeDriver = webdriver.Chrome('C:\new_software\chromedriver.exe', chrome_options = options) #specify your chromedriver location

chromeDriver.get('https://www.autohotkey.com/')#launch a tab

#launch some other random tabs for testing. 
chromeDriver.execute_script("window.open('https://developers.google.com/edu/python/introduction', 'tab2');")

chromeDriver.execute_script("window.open('https://www.facebook.com/', 'tab3');")

chromeDriver.execute_script("window.open('https://developer.mozilla.org/en-US/docs/Web/API/Window/open', 'tab4');"`)
seleniumwindow = ahk.active_window #as soon as you open you Selenium session, get a handle of the window frame with AHK. 
seleniumwindow.activate() #will activate whatever tab you have active in the Selenium browser as AHK is activating the window frame 
#To activate specific tabs I would use chromeDriver.switchTo()
#chromeDriver.switch_to_window(chromeDriver.window_handles[-1]) This takes you to the last opened tab in Selenium and chromeDriver.switch_to_window(chromeDriver.window_handles[1])to the second tab, etc.. 

回答by Gus Bustillos

Here is the full script.

这是完整的脚本。

Note:Remove the spaces in the two lines for tiny URL below. Stack Overflow does not allow the tiny link in here.

注意:删除下面两行中的微小 URL 中的空格。Stack Overflow 不允许这里的小链接。

import ahk
import win32clipboard
import traceback
import appJar
import requests
import sys
import urllib
import selenium
import getpass
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import socket
import time 
import urllib.request
from ahk import AHK, Hotkey, ActionChain # You want to play with AHK. 
from appJar import gui

try:                                                                                                                                                                         
    ahk = AHK(executable_path="C:\Program Files\AutoHotkey\AutoHotkeyU64.exe")    

except:                                                                                                                                                                         
    ahk = AHK(executable_path="C:\Program Files\AutoHotkey\AutoHotkeyU32.exe")    

finally:                                                                                                                                                                         
    pass 

chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--start-maximized')
chrome_options.add_experimental_option("excludeSwitches", ['enable-automation']);
chromeDriver = webdriver.Chrome('C:\new_software\chromedriver.exe', chrome_options = chrome_options)

def  ahk_disabledevmodescript():
    try:                                                                                                                                                                         
        ahk = AHK(executable_path="C:\Program Files\AutoHotkey\AutoHotkeyU64.exe")                                                                                                                                                                           
    except:                                                                                                                                                                         
        ahk = AHK(executable_path="C:\Program Files\AutoHotkey\AutoHotkeyU32.exe")                                                                                                                                                                         
    finally:                                                                                                                                                                         
        pass   
    ahk_disabledevmodescriptt= [
    str('WinActivate,ahk_exe chrome.exe'),
    str('Send {esc}'),
    ]
    #Run-Script
    for snipet in  ahk_disabledevmodescriptt:
        ahk.run_script(snipet, blocking=True )
    return 

def launchtabsagain():

    chromeDriver.execute_script("window.open('https://developers.google.com/edu/python/introduction', 'tab2');")
    chromeDriver.execute_script("window.open('https://www.facebook.com/', 'tab3');")
    chromeDriver.execute_script("window.open('https://developer.mozilla.org/en-US/docs/Web/API/Window/open', 'tab4');")
    chromeDriver.execute_script("window.open('https://www.easyespanol.org/', 'tab5');")
    chromeDriver.execute_script("window.open('https://www.google.com/search?source=hp&ei=EPO2Xf3EMLPc9AO07b2gAw&q=programming+is+not+difficult&oq=programming+is+not+difficult&gs_l=psy-ab.3..0i22i30.3497.22282..22555...9.0..0.219.3981.21j16j1......0....1..gws-wiz.....6..0i362i308i154i357j0j0i131j0i10j33i22i29i30..10001%3A0%2C154.h1w5MmbFx7c&ved=0ahUKEwj9jIyzjb_lAhUzLn0KHbR2DzQQ4dUDCAg&uact=5', 'tab6');")
    chromeDriver.execute_script("window.open('https://www.google.com/search?source=hp&ei=NvO2XdCrIMHg9APduYzQDA&q=dinner+recipes&oq=&gs_l=psy-ab.1.0.0i362i308i154i357l6.0.0..3736...0.0..0.179.179.0j1......0......gws-wiz.....6....10001%3A0%2C154.gsoCDxw8cyU', 'tab7');")

    return  
chromeDriver.get('https://ebc.cybersource.com/ebc2/')
compoanionWindow = ahk.active_window

launchtabs = launchtabsagain()
disabledevexetmessage = ahk_disabledevmodescript()



def copyUrl(): 
    try:                                                                                                                                                                         
        ahk = AHK(executable_path="C:\Program Files\AutoHotkey\AutoHotkeyU64.exe")                                                                                                                                                                           
    except:                                                                                                                                                                         
        ahk = AHK(executable_path="C:\Program Files\AutoHotkey\AutoHotkeyU32.exe")                                                                                                                                                                         
    finally:                                                                                                             

        pass 
    snipet = str('WinActivate,ahk_exe chrome.exe')
    ahk.run_script(snipet, blocking=True )  
    compoanionWindow.activate() 
    ahk_TinyChromeCopyURLScript=[

        str('WinActivate,ahk_exe chrome.exe'),
        str('send ^l'),
        str('sleep 10'),
        str('send ^c'),
        str('BlockInput, MouseMoveoff'),
        str('clipwait'),
    ] 

    #Run-AHK Script
    if ahk:
        for snipet in  ahk_TinyChromeCopyURLScript:
            ahk.run_script(snipet, blocking=True )  
    win32clipboard.OpenClipboard()
    urlToShorten = win32clipboard.GetClipboardData()
    win32clipboard.CloseClipboard()   


    return(urlToShorten)


def tiny_url(url):
    try:

        apiurl = "https: // tinyurl. com / api - create. php? url= " #remove spaces here
        tinyp = requests.Session()
        tinyp.proxies = {"https" : "https://USER:PASSWORD." + "@userproxy.visa.com:443", "http" : "http://USER:PASSWORD." + "@userproxy.visa.com:8080"}
        tinyUrl = tinyp.get(apiurl+url).text
        returnedresponse = tinyp.get(apiurl+url)
        if returnedresponse.status_code == 200: 
            print('Success! response code =' + str(returnedresponse))
        else:
            print('Code returned = ' + str(returnedresponse))
            print('From IP Address =' +IPadd)


    except:
        apiurl = "https: // tinyurl. com / api - create. php? url= " #remove spaces here
        tinyp = requests.Session()
        tinyUrl = tinyp.get(apiurl+url).text
        returnedresponse = tinyp.get(apiurl+url)
        if returnedresponse.status_code == 200: 
            print('Success! response code =' + str(returnedresponse))
            print('From IP Address =' +IPadd)
        else:
            print('Code returned = ' + str(returnedresponse))

    return tinyUrl

def tinyUrlButton():

    longUrl = copyUrl()
    try:                                                                                                                                                                         
        ahk = AHK(executable_path="C:\Program Files\AutoHotkey\AutoHotkeyU64.exe")                                                                                                                                                                           
    except:                                                                                                                                                                         
        ahk = AHK(executable_path="C:\Program Files\AutoHotkey\AutoHotkeyU32.exe")                                                                                                                                                                         
    finally:                                                                                                                                                                         
        pass
    try:
        shortUrl = tiny_url(longUrl)
        win32clipboard.OpenClipboard()
        win32clipboard.EmptyClipboard()
        win32clipboard.SetClipboardText(shortUrl)
        win32clipboard.CloseClipboard()
        if ahk:
            try:
                if str(shortUrl) == 'Error':
                    ahk.run_script("Msgbox,262144 ,Done.,"+ shortUrl + "`rPlease make sure there is a link to copy and that the page is fully loaded., 5.5" )
                else:
                    ahk.run_script("Msgbox,262144 ,Done.,"+ shortUrl + " is in your clipboard., 1.5" )
                # ahk.run_script("WinActivate, tinyUrl" )
            except:
                traceback.print_exc()
                print('error during ahk script')

                pass

    except:
        print('Error getting tinyURl')
        traceback.print_exc()

def closeChromeTabs(): 
        try: 
            try:                                                                                                                                                                          
                ahk = AHK(executable_path="C:\Program Files\AutoHotkey\AutoHotkeyU64.exe")                                                                                                                                                                          
            except:                                                                                                                                                                          
                ahk = AHK(executable_path="C:\Program Files\AutoHotkey\AutoHotkeyU32.exe")                                                                                                                                                                  
            finally:                                                                                                                                                                          
                    pass   
            compoanionWindow.activate()  
            ahk_CloseChromeOtherTabsScript = [ 

                str('WinActivate,ahk_exe chrome.exe'), 
                str('Mouseclick, Right, 30, 25,,1'), 
                str('Send {UP 3} {enter}'), 
                str('BlockInput, MouseMoveOff'), 
                ] 
                #Run-Script 
            if ahk: 
                for snipet in  ahk_CloseChromeOtherTabsScript: 
                        ahk.run_script(snipet, blocking=True ) 
            return(True) 
        except: 
            traceback.print_exc() 
            print("Failed to run closeTabs function.") 
            ahk.run_script('Msgbox,262144,,Failed to run closeTabs function.,2') 
            return(False)         



        # create a GUI and testing this library.

window = gui("tinyUrl and close Tabs test ", "200x160")
window.setFont(9)
window.setBg("blue")
window.removeToolbar(hide=True)
window.addLabel("description", "Testing AHK Library.")
window.addLabel("title", "tinyURL")
window.setLabelBg("title", "blue")
window.setLabelFg("title", "white")
window.addButtons(["T"], tinyUrlButton)
window.addLabel("title1", "Close tabs")
window.setLabelBg("title1", "blue")
window.setLabelFg("title1", "white")
window.addButtons(["C"], closeChromeTabs)
window.addLabel("title2", "Launch tabs")
window.setLabelBg("title2", "blue")
window.setLabelFg("title2", "white")
window.addButtons(["L"], launchtabsagain)
window.go()

if window.exitFullscreen():
    chromeDriver.quit()


def closeTabs():
    try:
        try:                                                                                                                                                                         
            ahk = AHK(executable_path="C:\Program Files\AutoHotkey\AutoHotkeyU64.exe")                                                                                                                                                                           
        except:                                                                                                                                                                         
            ahk = AHK(executable_path="C:\Program Files\AutoHotkey\AutoHotkeyU32.exe")                                                                                                                                                                         
        finally:                                                                                                                                                                         
                pass   

        compoanionWindow.activate()     
        ahk_CloseChromeOtherTabsScript = [

            str('WinActivate,ahk_exe chrome.exe'),
            str('Mouseclick, Right, 30, 25,,1'),
            str('Send {UP 3} {enter}'),
            str('BlockInput, MouseMoveOff'),
            ]
            #Run-Script
        if ahk:
            for snipet in  ahk_CloseChromeOtherTabsScript:
                    ahk.run_script(snipet, blocking=True )
        return(True)
    except:
        traceback.print_exc()
        print("Failed to run closeTabs function.")
        ahk.run_script('Msgbox,262144,Failed,Failed to run closeTabs function.,2')
        return(False)

回答by Ajjax

The tip from the user "aberna" worked for me the following way:

来自用户“aberna”的提示按以下方式对我有用:

First I got a list of the tabs:

首先,我得到了一个选项卡列表:

  tab_list = driver.window_handles

Then I selectet the tab:

然后我选择选项卡:

   driver.switch_to.window(test[1])

Going back to previous tab:

返回上一个选项卡:

    driver.switch_to.window(test[0])

回答by Amar Kumar

if you want to close only active tab and need to keep the browser window open, you can make use of switch_to.window method which has the input parameter as window handle-id. Following example shows how to achieve this automation:

如果您只想关闭活动选项卡并需要保持浏览器窗口打开,您可以使用 switch_to.window 方法,该方法的输入参数为窗口句柄 ID。以下示例显示了如何实现此自动化:

from selenium import webdriver
import time

driver = webdriver.Firefox()
driver.get('https://www.google.com')

driver.execute_script("window.open('');")
time.sleep(5)

driver.switch_to.window(driver.window_handles[1])
driver.get("https://facebook.com")
time.sleep(5)

driver.close()
time.sleep(5)

driver.switch_to.window(driver.window_handles[0])
driver.get("https://www.yahoo.com")
time.sleep(5)

#driver.close()