Search code examples
pythonseleniumselenium-webdriverpyvirtualdisplay

Python open multiple display windows from a loop


I'm getting some great help from the community today and hoping someone can put me in the right direction on this little one.

I have a loop going where I am trying to load up a number of different web pages but at the moment the same web page is opening in a different window.

How can I open them in separate displays? And is there a way to label the display?

for d in data["screen"]:
   screen_list["code"]))
    display = Display(visible=1, size=(800, 600))
    display.start()
    driver = webdriver.Chrome()
    driver.get("https://" + d["server"] + "/test/")

Edited

Trying to improve the answer, I've written a quick script to try to load up two different displays showing to different web pages but it loads up both webpages in the same window

import sys
import os
from selenium import webdriver
from pyvirtualdisplay import Display
from selenium.webdriver.common.keys import Keys



display = Display(visible=1, size=(800, 600))
display.start()
driver = webdriver.Chrome()
driver.get("https://news.bbc.co.uk")

display2 = Display(visible=1, size=(800, 600))
display2.start()
driver2 = webdriver.Chrome()
driver2.get("https://www.google.com")

Edited

I think the issue is that the script opens up one xephyr session on a port then the chrome driver will only talk to that session, so can you open multiple xephyr sessions for each driver.get("") request?


Solution

  • Ok, I reproduced the problem here. When I found the issue, I almost slapped myself since it is so obvious once all the pieces are together. The problem is that displays that you start after the first one are not connecting to your "real" X server. They are connecting to one another. Here's what happens:

    1. You create a display and call the start() method on it. This start method launches a new Xephyr instance and helpfully changes the DISPLAY environment so that subsequent processes that connect to X connect to the new Xephyr instance.

    2. You start Chrome, which connects to the new Xephyr instance. Yay!

    3. You create a new display, which obligingly connects to the first Xephyr instance rather than your "real" X server. Since it has the same dimensions as the first Xephyr, it takes the entire space of the first display and completely obstructs the view of the Chrome browser which was created earlier. It looks like you have only one Xephyr running but there are two of them running (which can be determined by using ps, for instance).

    4. The new Chrome instance appears in the embedded display. You have two instances of Chrome running but the earlier one cannot be seen.

    What you have to do is before you create a new Display, reset DISPLAY to what it was before you started creating displays. Here's code that works:

    import sys
    import os
    from selenium import webdriver
    from pyvirtualdisplay import Display
    from selenium.webdriver.common.keys import Keys
    
    orig = os.environ["DISPLAY"]
    
    display = Display(visible=1, size=(800, 600))
    display.start()
    driver = webdriver.Chrome()
    driver.get("https://news.bbc.co.uk")
    
    # You have to do this between each new Display.
    os.environ["DISPLAY"] = orig
    
    display2 = Display(visible=1, size=(800, 600))
    display2.start()
    driver2 = webdriver.Chrome()
    driver2.get("https://www.google.com")