Python: Open several Websites with webdriver in different Breakpoints - python

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?

Related

How do I save a whatsapp web session in selenium?

I am trying to acces whatsapp web with python without having to scan the QR code everytime I restart the program (because in my normal browser I also dont have to do that). But how can I do that? Where is the data stored that tells whatsapp web to connect to my phone? And how do I save this data and send it to the browser when I rerun the code?
I already tried this because someone told me I should save the cookies:
from selenium import webdriver
import time
browser = None
cookies = None
def init():
browser = webdriver.Firefox(executable_path=r"C:/Users/Pascal/Desktop/geckodriver.exe")
browser.get("https://web.whatsapp.com/")
time.sleep(5) # in this time I scanned the QR to see if there are cookies
cookies = browser.get_cookies()
print(len(cookies))
print(cookies)
init()
Unfortunately there were no cookies..
The output was 0 and [].
How do I fix this probblem?
As mentioned in the answer to this question, pass your Chrome profile to the Chromedriver in order to avoid this problem. You can do it like this:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = webdriver.ChromeOptions()
options.add_argument("user-data-dir=C:\\Path") #Path to your chrome profile
driver = webdriver.Chrome(executable_path="C:\\Users\\chromedriver.exe", options=options)
This one works for me, I just created a folder, on the home directory of the script and a little modifications and it works perfectly.
###########
E_PROFILE_PATH = "user-data-dir=C:\Users\Denoh\Documents\Project\WhatBOts\SessionSaver"
##################
This is the Config File that I will import later
##################
The main script starts here
##################
from selenium import webdriver
from config import E_PROFILE_PATH
options = webdriver.ChromeOptions()
options.add_argument(E_PROFILE_PATH)
driver = webdriver.Chrome(executable_path='chromedriver_win32_86.0.4240.22\chromedriver.exe', options=options)
driver.get('https://web.whatsapp.com/')

Why do I get small screenshots with pyvirtualdisplay in selenium tests?

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)

Selenium Webdriver on Google Cloud instance won't load a certain URL I need

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.

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?
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")

Selenium Webdriver - PhantomJS hangs upon send_keys() to file input element

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

Categories

Resources