load selenium chrome instance in a python widget - python

thereĀ“s any python component
to do someting like this(this is java)
https://jxbrowser.support.teamdev.com/support/solutions/articles/9000013135-jxbrowser-selenium
i use python tkinter to open chrome instances on a click button,
i'd like to run selenium chrome instance in a python widget on a click button,
at the top of python gui app a button and when you click on it open the selenium chrome instance in a tkinter frame
is it possible to do something like that with a python GUI
thanks a lot

Yes you can, I would try something like this:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import WebDriverException
#Your paths and driver might be different.
CHROME_PATH = 'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe'
CHROMEDRIVER_PATH = 'chromedriver.exe'
WINDOW_SIZE = "1920,1080"
chrome_options = Options()
chrome_options.add_argument("--log-level=3")
chrome_options.add_argument("--headless") # This is optional, but faster than gui
chrome_options.add_argument("--window-size=%s" % WINDOW_SIZE)
chrome_options.binary_location = CHROME_PATH
browser = webdriver.Chrome(executable_path=CHROMEDRIVER_PATH, chrome_options=chrome_options)
url = "https://www.example.com" # Your url goes here.
browser.get(url)
# - You'll need to copy the button's xpath and place it in here.
element = WebDriverWait(browser, 10).until(
EC.presence_of_element_located((By.XPATH, 'copy_xpath_into_here')))
# click on button - You'll need to copy the button's xpath and place it in here, too.
selectElem=browser.find_element_by_xpath('copy_xpath_into_here').click()

Related

Python Selenium can't click on button in a pop up

I am playing around with selenium on https://www.autozone.com/, trying to fill out the add vehicle form using selenium and python
first I click on the add vehicle button
URL = "https://www.autozone.com/"
ADD_VEHICLE_XPATH = "/html/body/div[1]/div/div[2]/div[2]/header/div[2]/div/div/div[2]/div/button"
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
driver.implicitly_wait(WAIT_TIME)
driver.get(URL)
add_vehicle_button = driver.find_element(By.XPATH, ADD_VEHICLE_XPATH)
add_vehicle_button.click()
Then a pop up window pops up, and I try to locate the button for the year dropdown
YEAR_BUTTON_XPATH = "/html/body/div[4]/div[3]/div/div[2]/div/div/div[1]/div/div[2]/div[1]/div/div/div[1]/div/button"
year_button = driver.find_element(By.XPATH, YEAR_BUTTON_XPATH)
This throws the NoSuchElementException
according to this script
def is_in_iframe():
driver.execute_script("""function iniFrame() {
if ( window.location !== window.parent.location )
{
// The page is in an iFrames
document.write("The page is in an iFrame");
}
else {
// The page is not in an iFrame
document.write("The page is not in an iFrame");
}
}
// Calling iniFrame function
iniFrame();""")
I am not in an iframe after clicking on add vehicle
I have also checked the names of all windows before and after clicking add vehicle, there is only ever 1 window and it is the same before and after clicking.
Some things to note:
I have tried adding both python sleep() and waiting in selenium
The div that contains the pop up and all buttons does not show up until I click add vehicle, and after that it shows up near the bottom
The xpath I'm using is unique to that button
What are some other ways I can try to locate the button? Please let me know if I need to add any more code or description.
You need to improve your locators.
Also you need to wait for elements to become clickable before clicking them.
The following code opens the "Add Vehicle" dialog and selects 2020 year.
from selenium import webdriver
from selenium.webdriver import DesiredCapabilities
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
options = Options()
options.add_argument("start-maximized")
caps = DesiredCapabilities().CHROME
caps["pageLoadStrategy"] = "eager"
webdriver_service = Service('C:\webdrivers\chromedriver.exe')
driver = webdriver.Chrome(options=options, desired_capabilities=caps, service=webdriver_service)
wait = WebDriverWait(driver, 10)
url = "https://www.autozone.com/"
driver.get(url)
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[data-testid='deskTopVehicle-menu-lg']"))).click()
wait.until(EC.element_to_be_clickable((By.ID, "yearheader"))).click()
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[data-testid='yearheader-dropdown-list-item-4']"))).click()
This is the screenshot of web page state after applying the code above:
That site containing several JavaScript scripts making the page loading time long, so I added a special settings to driver not to wait for it.
This is what
caps = DesiredCapabilities().CHROME
caps["pageLoadStrategy"] = "eager"
coming for

Press a button from popup window with selenium

import time
from selenium import webdriver
from selenium.webdriver.common.by import By
chrome_options = webdriver.ChromeOptions()
prefs = {"profile.default_content_setting_values.notifications": 2}
chrome_options.add_experimental_option("prefs", prefs)
# Add experimental options to remove "Google Chrome is controlled by automated software" notification
chrome_options.add_experimental_option("useAutomationExtension", False)
chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
driver = webdriver.Chrome(r'C:\Users\iwanh\Desktop\Drivers\chromedriver.exe', options=chrome_options)
driver.get("https://www.youtube.com/")
# We use driver.find_element with the help of the By import instead of find_element_by_name or id
accept_all = driver.find_element(By.ID, value="text")
time.sleep(7)
accept_all.submit()
So i have this code, and what i am trying to do is press the accept all button on the screenshot but I think the code doesnt recognize it with the id because it is some what of a popup window?
And here is the inspect element
Inspect Element
Screenshot
Right-click on the element and go to Copy > Copy (full) xpath.
Then use:
from selenium.webdriver.common.by import By
driver.find_elements(By.XPATH, 'xpath_value_here')
Edited to reflect the difference between 'copy xpath' and 'copy full xpath'; indeed, copy full xpath is the correct answer, as per the below comment.

Clicking Side Panel Elements in Selenium Without IFrames

I want to download U.S. Department of Housing and Urban Development data using Python's Selenium. Here's my code.
import os
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import Select
options = webdriver.ChromeOptions()
preferences= {"download.default_directory": os.getcwd(), "directory_upgrade": True}
options.add_experimental_option("prefs", preferences)
#options.headless = True
options.add_experimental_option('excludeSwitches', ['enable-logging'])
url = "https://hudgis-hud.opendata.arcgis.com/datasets/deteriorated-paint-index-by-county/explore"
# Path of my WebDriver
driver = webdriver.Chrome(ChromeDriverManager().install(), options=options)
wait = WebDriverWait(driver, 60)
# to maximize the browser window
driver.maximize_window()
#get method to launch the URL
driver.get(url)
paths = ["#ember97", "calcite-card > div > calcite-button"]
for x in paths:
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, x))).click()
I can click the button to expand the side panel, where the CSV file button is located, but I cannot click the CSV file itself to download it. My first thought was to check for if the side panel existed within an IFRAME, so I did
seq = driver.find_elements_by_tag_name('iframe')
seq
And it returned nothing. The content is nested in a class called side-panel-ref. Is there a way to switch to this somehow so I can click that content, when iframes aren't there? What might I be missing?
Your button is inside a shadowroot.
You see this when you inspect in devtools:
Quickest and easiest way to handle this is with some JS .This is your script slightly refactored + the JS call:
url = "https://hudgis-hud.opendata.arcgis.com/datasets/deteriorated-paint-index-by-county/explore"
wait = WebDriverWait(driver, 60)
driver.maximize_window()
driver.get(url)
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '#ember97'))).click()
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div.dataset-download-card > hub-download-card")))
driver.execute_script('document.querySelector("div.dataset-download-card > hub-download-card").shadowRoot.querySelector("calcite-card > div > calcite-button").click()')
It's a fairly lengthy JS call. It's reasonably self explanatory if you read it, there are 5 parts to it: document.querySelector(..).shadowRoot.querySelector(..).click() - but just ask if you need more support.
Please also be aware that selenium is bad at downloading files. There's no API that exposes the downloads progress. You'll need to ensure your browser remains open while you download the file.
It seems a pretty quick download so you might get away with a hard coded sleep.
Also worth a mention - If you're not a fan of the long JS, you can also break it down like so:
container = driver.find_element_by_css_selector("div.dataset-download-card > hub-download-card")
shadowRoot = driver.execute_script("return arguments[0].shadowRoot", container)
shadowRoot.find_element_by_css_selector("calcite-card > div > calcite-button").click()

How can I paste a string to textarea in browser with python?

I want to send a string to the web page whose text field name is "inputfield". Actually, I can send the word to the page, but when I run the program, a new "chrome" page opens, which is used for testing purposes. However, I want to send a string to the field on a chrome page that is already open.
Here my code:
from selenium import webdriver
import time
url = "https://10fastfingers.com/typing-test/turkish"
options = webdriver.ChromeOptions()
options.binary_location = r"C://Program Files//Google//Chrome//Application//chrome.exe"
chrome_driver_binary = 'chromedriver.exe'
options.add_argument('headless')
driver = webdriver.Chrome(chrome_driver_binary, options=options)
driver.get(url)
driver.implicitly_wait(10)
text_area = driver.find_element_by_id('inputfield')
text_area.send_keys("Hello")
Nothing happens when I run this code. Can you please help? Can you run it by putting a sample web page in the url part?
Thank you.
EDIT: It is working when I deleted options. But still opening a new page when I run it. Is there a way use a page which already open on background.
chrome_driver_binary = 'chromedriver.exe'
driver = webdriver.Chrome(chrome_driver_binary)
driver.get('https://10fastfingers.com/typing-test/turkish')
text_area = driver.find_element_by_id('inputfield')
text_area.send_keys("Hello")
Click the popup prior to sending keys.
driver.get('https://10fastfingers.com/typing-test/turkish')
wait=WebDriverWait(driver, 10)
wait.until(EC.element_to_be_clickable((By.ID, "CybotCookiebotDialogBodyLevelButtonLevelOptinAllowallSelectionWrapper"))).click()
text_area = wait.until(EC.element_to_be_clickable((By.ID, "inputfield")))
text_area.send_keys("Hello")
Imports
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
I am not sure what is your question but if the issue is multiple tabs or windows being opened then:
you can switch between the windows as:
// you can move to specific handle
chwd = driver.window_handles
print(chwd)
driver.switch_to.window(chwd[-1])
you should shoul switch to the correct window before you can interact with elements on that window
just switch to the window that was already opened bypassing the index
If the problem is that you want to interact with an already opened chrome then you should follow below steps:
Start chrome with debug port:
<path>\chrome.exe" --remote-debugging-port=1559
Python :
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:1559")
driver = webdriver.Chrome(options=chrome_options)

DeprecationWarning: use options instead of chrome_options error using ChromeDriver and Chrome through Selenium on Windows 10 system

Trying to run this code on my windows 10 machine https://github.com/KalleHallden/reddit_automations/blame/master/movie-tickets.py
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from decouple import config
import time
# the way to locate the button or thing you want on a website in chrome is
# by pressing cmd + shift + c and then you can use your mouse to find the
# info on the element that you want and you can copy the full xpath.
options = webdriver.ChromeOptions()
# options.add_argument('--ignore-certificate-errors')
# options.add_argument('--incognito')
# options.add_argument('--headless')
driver = webdriver.Chrome("/Users/kalle/Downloads/chromedriver83", chrome_options=options)
driver.get(config('THEATRE_SITE'))
# for some odd reason you need to reload the site for it to load.
# possibly a bug of the theatre site
driver.get(config('THEATRE_SITE'))
time.sleep(3)
# select city
button = driver.find_element_by_xpath('/html/body/div[1]/div[3]/div/div/div[1]/div/div[2]/ul/li[1]/label/input')
button.click()
# save city
button = driver.find_element_by_xpath('/html/body/div[1]/div[3]/div/div/div[2]/span/button')
button.click()
time.sleep(2)
# proceed to tickets tab
button = driver.find_element_by_xpath('/html/body/div[1]/nav/div[2]/div[2]/div[1]/ul[1]/li[1]/a')
button.click()
time.sleep(2)
# select the movie you want (should be more specific than just selecting the first one but whateva)
button = driver.find_element_by_xpath('/html/body/div[1]/main/div/div[2]/div/div/div/div[2]/div/div[2]/div[2]/div[2]/ul/li[1]/ul/li/div/div[1]/div/span[2]/a')
button.click()
time.sleep(1)
# select the time you want to go
button = driver.find_element_by_xpath('/html/body/div[1]/main/div/div[1]/div/div/div/div[4]/section/div/div[2]/div[2]/ul/li/ul/li[1]/div/span/span[3]/span[2]/span')
button.click()
time.sleep(1)
# choose amount of people
button = driver.find_element_by_xpath('/html/body/div[1]/main/div/div[2]/div/div/div/div/section/div/div[2]/div/button')
button.click()
time.sleep(2)
# choose seats
button = driver.find_element_by_xpath('/html/body/div[1]/main/div/div[1]/div/div/div/div[2]/section/div[3]/div[2]/button')
button.click()
time.sleep(2)
# pay
button = driver.find_element_by_xpath('/html/body/div[1]/main/div/div[1]/div/div/div/div[2]/section/div[4]/div/div[2]/button/span')
button.click()
I have all the correct programs installed:
running python 3.8
have chrome webdriver installed
running version 84 stable chrome web browser
When I run the program it opens chrome however I get a blank web page with nothing on there but some text which says "data:." that is all nothing else.
This is the error I get in VS code:
:\Users\user>python c:/chromedriver_win32/movie-tickets1.py
c:/chromedriver_win32/movie-tickets1.py:15: DeprecationWarning: use options instead of chrome_options
driver = webdriver.Chrome(executable_path=r'C:\chromedriver_win32\chromedriver.exe', chrome_options=options)
DevTools listening on ws://127.0.0.1:29442/devtools/browser/872d4312-b51d-4a38-bc1b-3b80495950
Traceback (most recent call last):
File "c:/chromedriver_win32/movie-tickets1.py", line 17, in <module>
driver.get(config("https://www.google.co.uk"))
File "C:\Users\user\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\decouple.py", line 199, in __call__
return self.config(*args, **kwargs)
File "C:\Users\user\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\decouple.py", line 83, in __call__
return self.get(*args, **kwargs)
File "C:\Users\user\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\decouple.py", line 68, in get
raise UndefinedValueError('{} not found. Declare it as envvar or define a default value.'.format(option))
decouple.UndefinedValueError: https://www.google.co.uk not found. Declare it as envvar or define a default value.
Any help would be much appreciated, I am unsure why decouple is not working.
This error message...
DeprecationWarning: use options instead of chrome_options
...implies that in your program you have used chrome_options to initiate a Selenium driven ChromeDriver initiated google-chrome Browsing Context.
chrome_options is deprecated now and you have to use options instead as well as pass the absolute path of the ChromeDriver along with the extension.
Solution
As you are triggering your tests on a windows-10 system, effectively you line of code will be:
options = webdriver.ChromeOptions()
options.add_argument('--headless')
driver = webdriver.Chrome(executable_path=r'C:\chromedriver_win32\chromedriver.exe', options=options)
It's ok!
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_argument('--headless')
browser = webdriver.Chrome(options=chrome_options)
no, the error will remain if you cover it like this
browser = webdriver.Chrome(options=chrome_options)
it will be right
browser = webdriver.Chrome(options=options)
***Below code sample is from 2022 and uses Web Driver Manager (https://pypi.org/project/webdriver-manager/)
#Imports for Web Driver, Service, Web Driver Manager
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
#options reference to Chrome Options
options = webdriver.ChromeOptions()
options.add_argument("--start-maximized")
#Pass options to the WebDriver with ChromeDriverManager
driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()), options=options)

Categories