79

So I am trying to open websites on new tabs inside my WebDriver. I want to do this, because opening a new WebDriver for each website takes about 3.5secs using PhantomJS, I want more speed...

I'm using a multiprocess python script, and I want to get some elements from each page, so the workflow is like this:

Open Browser

Loop throught my array
For element in array -> Open website in new tab -> do my business -> close it

But I can't find any way to achieve this.

Here's the code I'm using. It takes forever between websites, I need it to be fast... Other tools are allowed, but I don't know too many tools for scrapping website content that loads with JavaScript (divs created when some event is triggered on load etc) That's why I need Selenium... BeautifulSoup can't be used for some of my pages.

#!/usr/bin/env python
import multiprocessing, time, pika, json, traceback, logging, sys, os, itertools, urllib, urllib2, cStringIO, mysql.connector, shutil, hashlib, socket, urllib2, re
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from PIL import Image
from os import listdir
from os.path import isfile, join
from bs4 import BeautifulSoup
from pprint import pprint

def getPhantomData(parameters):
    try:
        # We create WebDriver
        browser = webdriver.Firefox()
        # Navigate to URL
        browser.get(parameters['target_url'])
        # Find all links by Selector
        links = browser.find_elements_by_css_selector(parameters['selector'])

        result = []
        for link in links:
            # Extract link attribute and append to our list
            result.append(link.get_attribute(parameters['attribute']))
        browser.close()
        browser.quit()
        return json.dumps({'data': result})
    except Exception, err:
        browser.close()
        browser.quit()
        print err

def callback(ch, method, properties, body):
    parameters = json.loads(body)
    message = getPhantomData(parameters)

    if message['data']:
        ch.basic_ack(delivery_tag=method.delivery_tag)
    else:
        ch.basic_reject(delivery_tag=method.delivery_tag, requeue=True)

def consume():
    credentials = pika.PlainCredentials('invitado', 'invitado')
    rabbit = pika.ConnectionParameters('localhost',5672,'/',credentials)
    connection = pika.BlockingConnection(rabbit)
    channel = connection.channel()

    # Conectamos al canal
    channel.queue_declare(queue='com.stuff.images', durable=True)
    channel.basic_consume(callback,queue='com.stuff.images')

    print ' [*] Waiting for messages. To exit press CTRL^C'
    try:
        channel.start_consuming()
    except KeyboardInterrupt:
        pass

workers = 5
pool = multiprocessing.Pool(processes=workers)
for i in xrange(0, workers):
    pool.apply_async(consume)

try:
    while True:
        continue
except KeyboardInterrupt:
    print ' [*] Exiting...'
    pool.terminate()
    pool.join()
Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
Robert W. Hunter
  • 2,895
  • 7
  • 35
  • 73

22 Answers22

75

Editor's note: This answer no longer works for new Selenium versions. Refer to this comment.


You can achieve the opening/closing of a tab by the combination of keys COMMAND + T or COMMAND + W (OSX). On other OSs you can use CONTROL + T / CONTROL + W.

In selenium you can emulate such behavior. You will need to create one webdriver and as many tabs as the tests you need.

Here it is the code.

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

driver = webdriver.Firefox()
driver.get("http://www.google.com/")

#open tab
driver.find_element_by_tag_name('body').send_keys(Keys.COMMAND + 't') 
# You can use (Keys.CONTROL + 't') on other OSs

# Load a page 
driver.get('http://stackoverflow.com/')
# Make the tests...

# close the tab
# (Keys.CONTROL + 'w') on other OSs.
driver.find_element_by_tag_name('body').send_keys(Keys.COMMAND + 'w') 


driver.close()
user202729
  • 3,358
  • 3
  • 25
  • 36
aberna
  • 5,594
  • 2
  • 28
  • 33
  • But I have multiprocess, so, I have 10 simultaneous jobs, that wants to access data in each page, doing that (I've tried to) ends with tons of tabs opened but only one finding elements and doing business – Robert W. Hunter Feb 10 '15 at 14:44
  • Sorry I do not get your statement. You question was "For element in array -> Open website in new tab -> do my business -> close it". So the proposed solution tried to answer to it. Can you clarify exactly what you are looking for ? Are you sure webdriver is the right tool for you ? What about scrapy ? – aberna Feb 10 '15 at 14:50
  • What I'm doing is creating n workers (10 in this case), each of this workers needs to open an URL then scrap some stuff on that URL, main problem is that it is extremly slow because it needs to open a new webdriver on each iteration, this needs around 4 seconds for each. I think this is the right tool for me because there are some images loaded on the website that only loads when JavScript is loaded, otherwise the elements wont be created, and of course can't be scrapped – Robert W. Hunter Feb 10 '15 at 14:58
  • @RobertW.Hunter I am not famiIiar with multiprocess testing but I do not understand why you need to open a new webdriver for each interation. As another comment stated you can open one webdriver for each worker at the start and using the tab combination for accessing the urls – aberna Feb 10 '15 at 15:02
  • I've updated my question with a piece of code I'm using, it is fully working but I omitted some irrelevant parts. – Robert W. Hunter Feb 10 '15 at 15:21
  • @RobertW.Hunter Ok. That's a completely different question. First check this http://stackoverflow.com/questions/28067675/webpage-test-with-python-selenium-really-slow-execution/ – aberna Feb 10 '15 at 15:35
  • I have thoose versions already, Selenium 2.44 and latest PhantomJS version (I am using PhantomJS in order to have a headless browser) but I've tried with latest firefox too, same situation. Slow stuff, very very slow stuff... – Robert W. Hunter Feb 10 '15 at 15:45
  • 7
    I wasn't quite getting the expected behavior from `driver.find_element_by_tag_name('body').send_keys(Keys.COMMAND + 't') `. This gave me the expected behavior as documented here: [http://selenium-python.readthedocs.org/en/latest/api.html#module-selenium.webdriver.common.action_chains](http://selenium-python.readthedocs.org/en/latest/api.html#module-selenium.webdriver.common.action_chains): `ActionChains(driver).key_down(Keys.COMMAND).send_keys("t").key_up(Keys.COMMAND).perform()` – dmmfll Jul 27 '15 at 11:17
  • 11
    it's not working in my recent test (OSX 10.10.5, selenium 2.47.1 python, Ghrome driver 2.25), got the working way in this [post](http://stackoverflow.com/questions/14682350/how-to-open-a-new-window-or-tab-in-webdriver-python), code : `driver.execute_script("window.open('');")` – Jerry Zhang Nov 11 '16 at 02:34
  • If you are wondering why @DMfll's answer doesn't work when you copy+pasted it, it is because there is a zero-width whitespace between the `k` and `e` in `key_up` (and another between the `.` and `p` in `COMMAND).perform` – David Murdoch Dec 29 '17 at 17:18
  • Same for me as @JerryZhang commented. In my case I use `driver.execute_script("window.open('url');")` to open a specific `url` in a new tab. This trick is useful for my case where the target web site is state-full (session-bound variables) and disables right-clicks, but I don't want to keep going back and forth between pages. By using tabs I can easily keep all desired pages in the browser without wasting time clicking and navigating along the site's map. – tngn May 10 '18 at 03:44
  • 13
    Bad news: It looks like Control-t no longer works ... cf. `driver.find_element_by_tag_name('body').send_keys(Keys.COMMAND + 't') ` ...^T has been disabled as "out-of-spec" cf. https://github.com/mozilla/geckodriver/issues/786 also https://python-forum.io/Thread-Need-Help-Opening-A-New-Tab-in-Selenium – NevilleDNZ Aug 29 '18 at 14:38
68
browser.execute_script('''window.open("http://bings.com","_blank");''')

Where browser is the webDriver

Supratik Majumdar
  • 2,365
  • 1
  • 23
  • 31
  • can it be used with local html files? – abhi1610 May 25 '18 at 06:44
  • 1
    @abhi1610 yes that does not matter. The browser is instructed to open a new tab here – Supratik Majumdar Sep 20 '18 at 09:04
  • 3
    Don't forget about swith between tabs. For example `self.selenium.switch_to.window(window_name=window_name)` – Александр Nov 19 '19 at 21:39
  • 2
    @Александр How would you find the window name? I have the issue where the driver controls the first tab even though the browser is focused on the second tab. – F.M Aug 12 '20 at 17:18
  • 3
    @F.M just use `window_name = self.selenium.window_handles[-1]` for get name of last tab name or other available index. – Александр Aug 13 '20 at 07:59
  • @Александр Thanks! – F.M Aug 13 '20 at 16:57
  • This opens a new window, not a tab. Is there a version for opening a tab (the posted question)? – Ezekiel Kruglick Oct 15 '20 at 21:45
  • @EzekielKruglick This answer might open in a new window or a new tab, depends on Firefox settings. Refer to [my answer on another question](https://stackoverflow.com/a/68826888/5267751) (post-note 2) for more detailed explanation. – user202729 Aug 18 '21 at 05:16
  • For some reason, this method sometimes opened a new tab but also sometimes opened a new window. It was so weird. But Vahidin Bajrić's answer worked perfectly and seems much more robust. – John Hon Apr 08 '23 at 14:50
37

This is a common code adapted from another examples:

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

driver = webdriver.Firefox()
driver.get("http://www.google.com/")

#open tab
# ... take the code from the options below

# Load a page 
driver.get('http://bings.com')
# Make the tests...

# close the tab
driver.quit()

the possible ways were:

  1. Sending <CTRL> + <T> to one element

    #open tab
    driver.find_element_by_tag_name('body').send_keys(Keys.CONTROL + 't')
    
  2. Sending <CTRL> + <T> via Action chains

    ActionChains(driver).key_down(Keys.CONTROL).send_keys('t').key_up(Keys.CONTROL).perform()
    
  3. Execute a javascript snippet

    driver.execute_script('''window.open("http://bings.com","_blank");''')
    

    In order to achieve this you need to ensure that the preferences browser.link.open_newwindow and browser.link.open_newwindow.restriction are properly set. The default values in the last versions are ok, otherwise you supposedly need:

    fp = webdriver.FirefoxProfile()
    fp.set_preference("browser.link.open_newwindow", 3)
    fp.set_preference("browser.link.open_newwindow.restriction", 2)
    
    driver = webdriver.Firefox(browser_profile=fp)
    

    the problem is that those preferences preset to other values and are frozen at least selenium 3.4.0. When you use the profile to set them with the java binding there comes an exception and with the python binding the new values are ignored.

    In Java there is a way to set those preferences without specifying a profile object when talking to geckodriver, but it seem to be not implemented yet in the python binding:

    FirefoxOptions options = new FirefoxOptions().setProfile(fp);
    options.addPreference("browser.link.open_newwindow", 3);
    options.addPreference("browser.link.open_newwindow.restriction", 2);
    FirefoxDriver driver = new FirefoxDriver(options);
    

The third option did stop working for python in selenium 3.4.0.

The first two options also did seem to stop working in selenium 3.4.0. They do depend on sending CTRL key event to an element. At first glance it seem that is a problem of the CTRL key, but it is failing because of the new multiprocess feature of Firefox. It might be that this new architecture impose new ways of doing that, or maybe is a temporary implementation problem. Anyway we can disable it via:

fp = webdriver.FirefoxProfile()
fp.set_preference("browser.tabs.remote.autostart", False)
fp.set_preference("browser.tabs.remote.autostart.1", False)
fp.set_preference("browser.tabs.remote.autostart.2", False)

driver = webdriver.Firefox(browser_profile=fp)

... and then you can use successfully the first way.

yucer
  • 4,431
  • 3
  • 34
  • 42
26
  • OS: Win 10,
  • Python 3.8.1
    • selenium==3.141.0
from selenium import webdriver
import time

driver = webdriver.Firefox(executable_path=r'TO\Your\Path\geckodriver.exe')
driver.get('https://www.google.com/')

# Open a new window
driver.execute_script("window.open('');")
# Switch to the new window
driver.switch_to.window(driver.window_handles[1])
driver.get("http://stackoverflow.com")
time.sleep(3)

# Open a new window
driver.execute_script("window.open('');")
# Switch to the new window
driver.switch_to.window(driver.window_handles[2])
driver.get("https://www.reddit.com/")
time.sleep(3)
# close the active tab
driver.close()
time.sleep(3)

# Switch back to the first tab
driver.switch_to.window(driver.window_handles[0])
driver.get("https://bing.com")
time.sleep(3)

# Close the only tab, will also close the browser.
driver.close()

Reference: Need Help Opening A New Tab in Selenium

Jeremy Anifacc
  • 1,003
  • 10
  • 7
13

The other solutions do not work for chrome driver v83.

First you should get the index of the last newly created tab and switch to it before calling the url (credit to tylerl):

driver.execute_script("window.open('');")
driver.switch_to.window(driver.window_handles[-1])
driver.get("https://www.example.com")

Alternatively, you can use driver.switch_to.new_window()

driver.switch_to.new_window()
driver.get("driver.switch_to.new_window()")
Jurakin
  • 832
  • 1
  • 5
  • 19
Capitaine
  • 1,923
  • 6
  • 27
  • 46
  • 1
    `window_handles` is just a list, so your code working only for 2 tabs. Additionally you may not to know how many tabs you are have, cuz even -1 index will not help you – salius Jul 29 '20 at 13:06
  • my code is just an example to show how to switch tabs. Once you understand the logic of it, you will be able to switch multiple tabs. Not sure what you mean by -1 index. – Capitaine Jul 31 '20 at 13:39
  • Good work bro, this code works perfectly for chrome webdriver 85 and selenium. Keep it up – Soham Patel Sep 16 '20 at 20:37
  • 2
    Use `driver.switch_to.window(driver.window_handles[len(driver.window_handles)-1])` instead of `driver.switch_to.window(driver.window_handles[1])` if you want to always grab the latest tab. – tylerl Sep 19 '20 at 22:35
  • AttributeError: 'SwitchTo' object has no attribute 'new_window' -> `driver.switch_to.new_window()` does not worked for me – lam vu Nguyen Mar 14 '23 at 23:45
11

In a discussion, Simon clearly mentioned that:

While the datatype used for storing the list of handles may be ordered by insertion, the order in which the WebDriver implementation iterates over the window handles to insert them has no requirement to be stable. The ordering is arbitrary.


Using Selenium v3.x opening a website in a New Tab through Python is much easier now. We have to induce an WebDriverWait for number_of_windows_to_be(2) and then collect the window handles every time we open a new tab/window and finally iterate through the window handles and switchTo().window(newly_opened) as required. Here is a solution where you can open http://www.google.co.in in the initial TAB and https://www.yahoo.com in the adjacent TAB:

  • Code Block:

      from selenium import webdriver
      from selenium.webdriver.support.ui import WebDriverWait
      from selenium.webdriver.support import expected_conditions as EC
    
      options = webdriver.ChromeOptions() 
      options.add_argument("start-maximized")
      options.add_argument('disable-infobars')
      driver = webdriver.Chrome(chrome_options=options, executable_path=r'C:\Utility\BrowserDrivers\chromedriver.exe')
      driver.get("http://www.google.co.in")
      print("Initial Page Title is : %s" %driver.title)
      windows_before  = driver.current_window_handle
      print("First Window Handle is : %s" %windows_before)
      driver.execute_script("window.open('https://www.yahoo.com')")
      WebDriverWait(driver, 10).until(EC.number_of_windows_to_be(2))
      windows_after = driver.window_handles
      new_window = [x for x in windows_after if x != windows_before][0]
      driver.switch_to.window(new_window)
      print("Page Title after Tab Switching is : %s" %driver.title)
      print("Second Window Handle is : %s" %new_window)
    
  • Console Output:

      Initial Page Title is : Google
      First Window Handle is : CDwindow-B2B3DE3A222B3DA5237840FA574AF780
      Page Title after Tab Switching is : Yahoo
      Second Window Handle is : CDwindow-D7DA7666A0008ED91991C623105A2EC4
    
  • Browser Snapshot:

multiple__tabs


Outro

You can find the based discussion in Best way to keep track and iterate through tabs and windows using WindowHandles using Selenium

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
8

After struggling for so long the below method worked for me:

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

windows = driver.window_handles

time.sleep(3)
driver.switch_to.window(windows[1])
Keiwan
  • 8,031
  • 5
  • 36
  • 49
Ziad abbas
  • 81
  • 1
  • 2
  • Have you tested this with recent versions ? it doesn't work for me. I think that in your case you lost the focus for some reason. – yucer Aug 04 '17 at 08:56
8

Try this it will work:

# Open a new Tab
driver.execute_script("window.open('');")

# Switch to the new window and open URL B
driver.switch_to.window(driver.window_handles[1])
driver.get(tab_url)
Atul Gupta
  • 81
  • 1
  • 3
5
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()

https://www.edureka.co/community/52772/close-active-current-without-closing-browser-selenium-python

Efrat Levitan
  • 5,181
  • 2
  • 19
  • 40
4

The 4.0.0 version of Selenium supports the following operations:

  • to open a new tab try:

    driver.switch_to.new_window()

  • to switch to a specific tab (note that the tabID starts from 0):

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

Bertold Kolics
  • 892
  • 6
  • 11
  • 1
    This is a much better answer - if not the best answer here - but it's a shame that it doesn't have more upvotes because it's new. – John Hon Apr 08 '23 at 14:38
3

just for future reference, the simple way could be done as this:

driver.switch_to.new_window()
t=driver.window_handles[-1]# Get the handle of new tab
driver.switch_to.window(t)
driver.get(target_url) # Now the target url is opened in new tab
1

Strangely, so many answers, and all of them are using surrogates like JS and keyboard shortcuts instead of just using a selenium feature:

def newTab(driver, url="about:blank"):
    wnd = driver.execute(selenium.webdriver.common.action_chains.Command.NEW_WINDOW)
    handle = wnd["value"]["handle"]
    driver.switch_to.window(handle)
    driver.get(url) # changes the handle
    return driver.current_window_handle
KOLANICH
  • 2,904
  • 2
  • 20
  • 20
  • 1
    `AttributeError: type object 'Command' has no attribute 'NEW_WINDOW'` – Chickenmarkus Mar 05 '21 at 09:02
  • 1
    Looks like this is only available in selenium pre-release version 4.0.0. In version selenium==4.0.0b2.post1, `driver.execute(selenium.webdriver.remote.command.Command.NEW_WINDOW, {"type": "tab"})` works. – user202729 Aug 18 '21 at 06:54
1

I'd stick to ActionChains for this.

Here's a function which opens a new tab and switches to that tab:

import time
from selenium.webdriver.common.action_chains import ActionChains

def open_in_new_tab(driver, element, switch_to_new_tab=True):
    base_handle = driver.current_window_handle
    # Do some actions
    ActionChains(driver) \
        .move_to_element(element) \
        .key_down(Keys.COMMAND) \
        .click() \
        .key_up(Keys.COMMAND) \
        .perform()
    
    # Should you switch to the new tab?
    if switch_to_new_tab:
        new_handle = [x for x in driver.window_handles if x!=base_handle]
        assert len new_handle == 1 # assume you are only opening one tab at a time
        
        # Switch to the new window
        driver.switch_to.window(new_handle[0])

        # I like to wait after switching to a new tab for the content to load
        # Do that either with time.sleep() or with WebDriverWait until a basic
        # element of the page appears (such as "body") -- reference for this is 
        # provided below
        time.sleep(0.5)        

        # NOTE: if you choose to switch to the window/tab, be sure to close
        # the newly opened window/tab after using it and that you switch back
        # to the original "base_handle" --> otherwise, you'll experience many
        # errors and a painful debugging experience...

Here's how you would apply that function:

# Remember your starting handle
base_handle = driver.current_window_handle

# Say we have a list of elements and each is a link:
links = driver.find_elements_by_css_selector('a[href]')

# Loop through the links and open each one in a new tab
for link in links:
    open_in_new_tab(driver, link, True)
    
    # Do something on this new page
    print(driver.current_url)
    
    # Once you're finished, close this tab and switch back to the original one
    driver.close()
    driver.switch_to.window(base_handle)
    
    # You're ready to continue to the next item in your loop

Here's how you could wait until the page is loaded.

Yaakov Bressler
  • 9,056
  • 2
  • 45
  • 69
  • 1
    Surprisingly no one gives this answer an upvote. As sometimes ```^+T``` or ```^+ENTER/RETURN``` not work, ```click``` is a considerable choice. – Xixiaxixi Jul 09 '22 at 15:01
1

you can use this to open a new tab

driver.execute_script("window.open('http://google.com', 'new_window')")
jack chyna
  • 83
  • 4
1

This worked for me:-

link = "https://www.google.com/"
driver.execute_script('''window.open("about:blank");''')  # Opening a blank new tab
driver.switch_to.window(driver.window_handles[1])  # Switching to newly opend tab
driver.get(link)
Amar Kumar
  • 2,392
  • 2
  • 25
  • 33
1

just enough use this to open new window(for example):

driver.find_element_by_link_text("Images").send_keys(Keys.CONTROL + Keys.RETURN)
0

I tried for a very long time to duplicate tabs in Chrome running using action_keys and send_keys on body. The only thing that worked for me was an answer here. This is what my duplicate tabs def ended up looking like, probably not the best but it works fine for me.

def duplicate_tabs(number, chromewebdriver):
#Once on the page we want to open a bunch of tabs
url = chromewebdriver.current_url
for i in range(number):
    print('opened tab: '+str(i))
    chromewebdriver.execute_script("window.open('"+url+"', 'new_window"+str(i)+"')")

It basically runs some java from inside of python, it's incredibly useful. Hope this helps somebody.

Note: I am using Ubuntu, it shouldn't make a difference but if it doesn't work for you this could be the reason.

astroben
  • 1
  • 3
0

Opening the new empty tab within same window in chrome browser is not possible up to my knowledge but you can open the new tab with web-link.

So far I surfed net and I got good working content on this question. Please try to follow the steps without missing.

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

driver = webdriver.Chrome()
driver.get('https://www.google.com?q=python#q=python')
first_link = driver.find_element_by_class_name('l')

# Use: Keys.CONTROL + Keys.SHIFT + Keys.RETURN to open tab on top of the stack 
first_link.send_keys(Keys.CONTROL + Keys.RETURN)

# Switch tab to the new tab, which we will assume is the next one on the right
driver.find_element_by_tag_name('body').send_keys(Keys.CONTROL + Keys.TAB)

driver.quit()

I think this is better solution so far.

Credits: https://gist.github.com/lrhache/7686903

Abdulvakaf K
  • 606
  • 1
  • 7
  • 16
0
tabs = {}

def new_tab():
    global browser
    hpos = browser.window_handles.index(browser.current_window_handle)
    browser.execute_script("window.open('');")
    browser.switch_to.window(browser.window_handles[hpos + 1])
    return(browser.current_window_handle)
    
def switch_tab(name):
    global tabs
    global browser
    if not name in tabs.keys():
        tabs[name] = {'window_handle': new_tab(), 'url': url+name}
        browser.get(tabs[name]['url'])
    else:
        browser.switch_to.window(tabs[name]['window_handle'])
ronybc
  • 15
  • 6
0

As already mentioned several times, the following approaches are NOT working anymore:

driver.find_element_by_tag_name('body').send_keys(Keys.CONTROL + 't')
ActionChains(driver).key_down(Keys.CONTROL).send_keys('t').key_up(Keys.CONTROL).perform()

Moreover, driver.execute_script("window.open('');") is working but is limited by the popup blocker. I process hundreds of tabs in parallel (web scraping using scrapy). However, the popup blocker became active after opening 20 new tabs using JavaScript's window.open('') and, thus, has broke my crawler.

As work around I declared a tab as "master" which has opended the following helper.html:

<!DOCTYPE html>
<html><body>
<a id="open_new_window" href="about:blank" target="_blank">open a new window</a>
</body></html>

Now, my (simplified) crawler can open as many tabs as necessary by purposely clicking the link which is not considered by the popup blogger at all:

# master
master_handle = driver.current_window_handle
helper = os.path.join(os.path.dirname(os.path.abspath(__file__)), "helper.html")
driver.get(helper)

# open new tabs
for _ in range(100):
    window_handle = driver.window_handles          # current state
    driver.switch_to_window(master_handle)
    driver.find_element_by_id("open_new_window").click()
    window_handle = set(driver.window_handles).difference(window_handle).pop()
    print("new window handle:", window_handle)

Closing these windows via JavaScript's window.close() is no problem.

Chickenmarkus
  • 1,131
  • 11
  • 25
0
#Change the method of finding the element if needed
self.find_element_by_xpath(element).send_keys(Keys.CONTROL + Keys.ENTER)

This will find the element and open it in a new tab. self is just the name used for the webdriver object.

john heroi
  • 47
  • 2
  • 12
  • Hello... Inspect // Watch ... Your answer is poorly elaborated. It is useful to insert an effective response, with codes and references. Concluding a practical and efficient solution. This platform is not just any forum. We are the largest help and support center for other programmers and developers in the world. Review the terms of the community and learn how to post; – Paulo Boaventura Mar 24 '21 at 19:38
0

Now natively supported by selenium

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# Store the ID of the original window
original_window = driver.current_window_handle    

# Opens a new window and switches to new window
driver.switch_to.new_window('window')

# Check we don't have other windows open already
assert len(driver.window_handles) == 1

# Click the link which opens in a new window
driver.find_element(By.LINK_TEXT, "new window").click()

# Wait for the new window or tab
wait.until(EC.number_of_windows_to_be(2))

#Close the tab or window
driver.close()
#Switch back to the old tab or window
driver.switch_to.window(original_window)

Reference: https://www.selenium.dev/documentation/webdriver/interactions/windows/

gaut
  • 5,771
  • 1
  • 14
  • 45