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?
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:
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.
You start Chrome, which connects to the new Xephyr instance. Yay!
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).
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")
Related
I am running Selenium (v3.141.0) on Python 3. I have a sequence of element clicks and element scrolls which work flawlessly when the browser (Chrome) window is in focus. These however stop working completely when the Chrome window is in the background.
I am hooking Selenium to a manually opened browser window, specifically open for debugging. I also tried passing the --headless parameter to the driver options, with no luck.
Is this an inherent limitation to Selenium, do I need to keep the window in focus while the program is running, or can this be achieved successfully while the window is in the background, and I am attending to other tasks?
Use this code to create your chrome driver.
This will run in headless mode without any interference.
Plus now you don't have to keep the window open when the script is running since this codebase will run in the background and you can do whatever you want on your screen.
import os
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
class ChromeDriver_Class(webdriver.Chrome):
def __init__(self, chrome_driver_path, teardown=False):
self.driver_path = chrome_driver_path
self.options = Options()
self.options.headless = True
self.driver = webdriver.Chrome(executable_path=self.driver_path,options=self.options)
self.options.add_argument('--ignore-certificate-errors')
self.options.add_argument('--ignore-ssl-errors')
self.teardown = teardown
os.environ['PATH'] += self.driver_path
self.driver.implicitly_wait(30)
self.driver.maximize_window()
I am using complex selenium tests and pyvirtualdisplay in order to take screenshots during the selenium testing. However, I am using the following code to create a Display:
self.display = Display(visible=0, size=(1366, 768))
self.display.start()
and something like this code
self.driver.save_screenshot(savename)
to create a screenshot (where self.driver is a selenium-webdriver). However, the screenshots I get are much smaller that defined, like 911x197 pixels. Do I have to make some special configurations to get a better screenshot? So far I only can see small parts of the headless browser I am using for testing...
Do you start your browser with "--start-maximized" option?
from pyvirtualdisplay import Display
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
def browser():
opts = Options()
opts.add_argument('--start-maximized')
d = Display(visible=0, size=(1920, 1024))
d.start()
b = webdriver.Chrome(chrome_options=opts)
I´m really new to programming with Python.
I want to write a code that opens a URL in different Breakpoints (1280px / 768px / 320px) and then take screenshots from the site.
So far this is my code:
from selenium import webdriver
from pyvirtualdisplay import Display
import time
# Set Breakpoint for different View
Breakpoints = [1280, 768, 320]
"""
Open invisible Website in Breakpoint 1280
"""
display = Display(visible=0, size=(1280, 800))
display.start()
"""
Open the Headless Chrome Webdriver
"""
driver = webdriver.Chrome('/usr/local/bin/chromedriver')
driver.set_page_load_timeout(10)
driver.get('https://example.com')
driver.maximize_window()
"""
Take Screenshots and Save as File
"""
driver.get_screenshot_as_file('Screenshot_BrPt_1280.png')
time.sleep(1o)
driver.get_screenshot_as_file('Screenshot_BrPt_768.png')
time.sleep(1o)
driver.get_screenshot_as_file('Screenshot_BrPt_320.png')
My question is now:
How can i rewrite this code that he loops through the different Breakpoints, open the site in the different Breakpoints an take a screenshot of every breakpoint?
The call to
driver.get()
never finishes. I've tried using both Chrome and PhantomJS, but this URL (and other similar ones) just won't load on either. URLs on other sites work fine. Cloud instance is running Ubuntu 16.04, and I've configured Webdriver properly.
This same code works fine on my own laptop.
from selenium import webdriver
from pyvirtualdisplay import Display
import time
display = Display(visible=0, size=(800, 600))
display.start()
driver = webdriver.PhantomJS()
driver.get('https://api.flightradar24.com/common/v1/flight/list.json?query=vt-iao&fetchBy=reg&page=1&limit=100&token=')
#driver.get('http://www.google.com')
# ^works
EDIT: I actually have some other Selenium code that is not able to finish loading a page that requests this particular URL. The above code is just to demonstrate the problem.
I am performing some file uploading tests. I found that my test code hangs at element.send_keys(file) if I am using PhantomJS, however the same code does not hang if I am using Firefox.
element = self.browser.find_element_by_xpath("//input[#type='file']")
element.send_keys(file)
Is there any workarounds to make PhantomJS upload files properly? Currently I am using Windows 7, Python 3.4.1, selenium 2.42.1, PhantomJS 1.9.7.
browser = webdriver.PhantomJS()
browser.set_window_size(1200,800)
Without setting the window size, the browser remains in mobile size causing errors. Try a implicit wait too.
Should use PhantomJS.uploadFile(). However, didn't find python selenium API.
var webPage = require('webpage');
var page = webPage.create();
page.uploadFile('input[name=image]', '/path/to/some/photo.jpg');
Oddly enough i couldn't get anything to run in my ubuntu shell but it would run via iPython from Jupyter notebook on the exact same server.
I had to add a virtual display into the code to make it run from the shell as a .py script...
if it helps anyone facing the similiar problem here is the lines of code i added to my script and the send keys start to work without an issue.
from pyvirtualdisplay import Display
# Set screen resolution to 1366 x 768 like most 15" laptops. This is needed
#to run in the shell. Seems fine in iPython
display = Display(visible=0, size=(1366, 768))
display.start()
I use this approach when I can not simply change the value of the file input tag.
We will run it console, so we should use PyVirtualDisplay with window manager (I am using dwm, you can try fluxbox it is easy to install but need more RAM then dwm) and Xephyr for debug.
To run window manager we will use EasyProcess
So we will call File Upload Dialog, by clicking on element or button, then we simulate send keys with pynput and all these running in our console.
import time
from easyprocess import EasyProcess
from pynput.keyboard import Key, Controller
from pyvirtualdisplay import Display
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
class ImageUploadAutomation:
chrome = 'path/to/chrome'
chrome_options = Options()
# chrome_options.add_argument('--headless')
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-notifications")
chrome_options.add_argument("--disable-dev-shm-usage")
chrome_options.add_argument("--window-size=1280,900")
chrome_options.add_argument("--start-maximized")
chrome_options.add_argument("user-data-dir=selenium")
chrome_options.add_experimental_option(
"excludeSwitches", ["disable-popup-blocking"]
)
chrome_options.add_argument(
"--disable-blink-features=AutomationControlled"
)
driver = None
def upload(self, photo):
# Change visible to 1 if you want to use Xephyr debug
with Display(visible=0, size=(1280, 900)) as display:
with EasyProcess(["dwm"]) as process:
keyboard = Controller()
url = "https://www.exmaple.com"
self.driver = webdriver.Chrome(
executable_path=self.chrome,
chrome_options=self.chrome_options
)
self.driver.get(url)
test = self.driver.find_element_by_xpath(
"//div[#aria-label='Add Photos']"
)
time.sleep(1)
test.click()
time.sleep(1)
for key in photo.path:
keyboard.press(key)
keyboard.release(key)
# keyboard.press(Key.enter)
with keyboard.pressed(Key.enter):
pass