How to click this button on this URL using selenium and Python? - python

from selenium import webdriver
from selenium.webdriver import ChromeOptions
from selenium.webdriver.common.keys import Keys
import configparser
from selenium.webdriver import ActionChains
import time
import os
class SeleniumConfig():
def __init__(self):
config = configparser.ConfigParser()
self.absolute = "C:\\Program Files (x86)\\chromedriver.exe"
options = webdriver.ChromeOptions()
options.add_argument("--start-maximized")
self.driver = webdriver.Chrome(self.absolute, options=options)
def jupiter_1(self):
self.driver.get('http://jupiter.cloud.planittesting.com')
self.driver.find_element_by_id("nav-contact").click()
time.sleep(5)
form = self.driver.find_element_by_class_name(
"btn-contact btn btn-primary") # my issue seems to start at the submit button
time.sleep(5)
self.driver.quit()
I'm not sure why i'm not able to use the class name, as the inspection says it is
My error:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":".btn-contact btn btn-primary"}
(Session info: chrome=87.0.4280.141)

self.driver.find_element_by_css_selector(".btn-contact.btn.btn-primary")
Spaces in class names need to be replaced with . in order for proper xpathing.
Also try not to use time.sleep() and use the following to allow the page to load and for elements to be clickable.
wait = WebDriverWait(self.driver,10)
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,".btn-contact.btn.btn-primary"))).click()
Import
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

In my experience with selenium, the find_element_by_ can be a bit wonky and you sometimes have to try several reference techniques before one finally works. I'd recommend using the full Xpath as that seems to reliably work (it's drawback is that it is not as obvious to read in the code itself). You can get the xpath by inspecting the element in the html dev tool and just right click to copy it. An option for "copy full xpath" should show up somewhere.
With that in mind, you can try your code line to the following and see if it helps:
form = driver.find_element_by_xpath("/html/body/div[2]/div/form/div/a")
Hopefully that can at least point you in the right direction!

Nevermind i found the answer or a workaround =>
form = self.driver.find_element_by_link_text(
"Submit")
I use find_element_by_link_text to submit and it works.

Please use following relative xpath to click submit buttton
//a[#class='btn-contact btn btn-primary']

Related

Why am I getting the message that the search-bar is not intractable?

The code is supposed to type "fish" into the YouTube search bar using Selenium and a Chrome Browser.
I have tried the xpaths of mulitple divs that hold the tag and they didn't work either.(not sure if the error was the same though) The xpath in the code is for the <input> tag so it should be fine.
I also watched a tutorial and the xpath was exactly the same so that shouldn't be the problem since it worked for the YouTuber.
It also took me some time to figure out that the find_element_by_* are depreciated functions.
Could it be that the .send_keys has also been changed? I did try to find the selenium changes in 4.1.0 and it said nothing about it on a website that I found.
Should I maybe delete Selenium 4.1.0 and install an older version? For simplicity sake. Since there is probably a bigger number of tutorials for it.
from selenium import webdriver
from selenium.webdriver.common.by import By
setting = webdriver.ChromeOptions()
setting.add_argument("--incognito")
# I open the browser in incognito just so I don't clutter my search
# history with dumb stuff as I'm testing things out
# could it be a part of the problem?
driver = webdriver.Chrome(options = setting)
driver.get('http://youtube.com')
searchbox = driver.find_element(By.XPATH, '//*[#id="search"]')
searchbox.send_keys('fish')
Error Message:
selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable
wait=WebDriverWait(driver,60)
driver.get('http://youtube.com')
searchbox = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,"input#search")))
searchbox.send_keys('fish')
In order to send_keys to that element wait for it to interactable and then send keys.
Imports:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
Outputs:

Cannot use WebDriverWait library properly in Python Selenium

Hello everyone I'm learning selenium recently and as I bet is a classic newbie mistake I filled my code with time.sleep which made everything really slow. So I started to learn about webdriverWait. I took some sample code and I have tried multiple things but I still get the error of "what you clicked is blocked by this other thing" meaning that the library did not crash but it also did not do anything. Which must mean I am doing something wrong. This is an error I can avoid if use the time.sleep function.
I'm using expected conditions, BY and action chains alongside WebDriverWait, though in my last test I tried to not use Acton chains to lower the possibilities of why its failing.
I'm using a company site that is probably under NDA so I don't have a public example to show this on, I tried searching for "pages with cover openings" but I couldn't find any, so if you guys know of any that I can use to illustrate this I would also find that really helpful. What is happening is that the site loads with a "cover" animation and after a few seconds the animation goes away to reveal the Button I'm looking for.
Environment info:
Using Pycharm community latest version
Using Selenium 4.0.0b2.post1 (I also tried in 3.9 to no results)
Using ChromeDriver 89 as my google chrome version is 89 as well [Version 89.0.4389.114 for Chrome]
Here are my code snippets:
Attempt #1:
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
import selenium.webdriver.support.expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
import selenium.webdriver.support.ui as ui
def test(driver, actions, delay):
cart = "//header/div[1]/div[1]/a[2]/*[1]"
cartxp = WebDriverWait(driver, delay).until(EC.visibility_of_element_located((By.XPATH, cart)))
actions.move_to_element(cartxp).perform()
cartclk = driver.find_element_by_xpath(cart).click()
Attempt #2: Using UI library
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
import selenium.webdriver.support.expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
import selenium.webdriver.support.ui as ui
def test2(driver, delay, actions):
cart = "//header/div[1]/div[1]/a[2]/*[1]"
cartxp = ui.WebDriverWait(driver, delay).until(EC.visibility_of_element_located((By.XPATH, cart)))
actions.move_to_element(cartxp).perform()
cartclk = driver.find_element_by_xpath(cart).click()
Attempt #3: Not using Action chains
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
import selenium.webdriver.support.expected_conditions as EC
from selenium.webdriver.common.by import By
def test3(driver, delay):
wait = WebDriverWait(driver, delay)
cart = "//header/div[1]/div[1]/a[2]/*[1]"
button = wait.until(EC.element_to_be_clickable((By.XPATH, cart)))
cartclk = driver.find_element_by_xpath(cart).click()
All of these have a main method that just has:
driver = webdriver.Chrome()
test3(driver, 30)
driver.get('Site that I cant reveal cuz of NDA')
action = ActionChains(driver)
The error I get is:
Message: element click intercepted: Element ... is not clickable at point (1183, 27). Other element would receive the click
Thanks in advance for any help!
Edit: After some comments changed my xpath to //a[#class='header__cart'] both the previous and this one leads to a single result If I use it on chrome inspect to look for the button, additionally it works as intended if I use it to actually click the button after using time.sleep() to wait out the animation
Additionally just in case tried using the try catch as they did on the suggested question. It also failed
Attempt 4: surrounding in a try-catch
def test4(driver, delay):
cart = "//a[#class='header__cart']"
try:
my_elem = WebDriverWait(driver, delay).until(EC.visibility_of_element_located((By.XPATH, cart)))
print
"Page is ready!"
except TimeoutException:
print
"Loading took too much time!"
cart_btn = driver.find_element_by_xpath(cart)
cart_btn.click()
Error: selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element <a href="/cart" class="header__cart" data-items-in-cart="0" )="">... is not clickable at point (1200, 27). Other element would receive the click
To clarify what I meant earlier this works:
cart = "//a[#class='header__cart']"
time.sleep(20)
cartclk = driver.find_element_by_xpath(cart).click()

Confirm whether to write comments with xpath

Could you make an example with the site? I want to ignore the posts with comments and just click the ones without comments.
from selenium import webdriver
import time
path = "C:\chromed\chromedriver.exe"
driver = webdriver.Chrome(path) #path
'''
'''
driver.get("http://cineaste.co.kr/") #url
time.sleep(0.5)
postclick = driver.find_element_by_xpath("//h3[.='영화이야기']/following::div[#class='widget-small-box'][1]//li[#class='ellipsis'][not(contains(.,'+'))]") #로그인창 활성화
postclick.click()
driver.close()
I tried this, but there was an error.
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//h3[.='영화이야기']/following::div[#class='widget-small-box'][1]//li[#class='ellipsis'][not(contains(.,'+'))]"}
(Session info: chrome=81.0.4044.138)
I want to click on a post that doesn't have any comments yet. And I want to skip posts with comments.
I'm still a beginner. Help me.
The Element you are looking for is not available.
You need to recreate the Xpath. The Xpath you created is incorrect. See following image :-
You'll need these imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
Example with the first entry with no comments in the "movie-reviews" block :
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//h3[.='영화감상평']/following::div[#class='widget-small-box'][1]//li[#class='ellipsis'][not(contains(.,'+'))][1]"))).click()

selenium in python. trying to select element

UPDATE: I found out what caused the issue in my original post, but don't know how to solve. Here is some more of my code. I first did a search, after which my page in firefox jumped to www.flickr.com/searc/?text=volleybal.
but apparently my browser object still sits on www.flickr.com. How can I update it?
from selenium import webdriver
browser = webdriver.Firefox()
browser.get('https://www.flickr.com')
s = browser.find_element_by_id('search-field')
s.send_keys('volleyball')
s.submit()
s = browser.find_element_by_class_name("style-button")
#s = browser.find_element_by_xpath("//li[#data-style-value = 'minimalism']")
s.click()
original post:
I'm experimenting with selenium, and I want to select the following element:
<li class="style-button minimalist" data-style-value="minimalism" data-tooltip-title="Minimalist" tabindex="0" role="button" aria-label="Minimalist">
I have tried the following, but none of them work:
s = browser.find_element_by_class_name("style-button minimalist")
s = browser.find_element_by_class_name("style-button.minimalist")
s = browser.find_element_by_css_selector("li.style-button.minimalist")
s = browser.find_element_by_css_selector(".style-button.minimalist")
How can I select this element?
You could try an XPath here:
s = browser.find_element_by_xpath("//li[contains(#class, 'style-button')]")
Hope this helps a bit.
Solved. Added browser.refresh()after s.submit()
The best option is to use absolute xpath. It for that button will be:
/html[1]/body[1]/div[1]/div[1]/div[3]/div[1]/div[1]/div[1]/div[2]/ul[1]/li[3]
Moreover, I found that sometimes the page is not loaded and the selenium searches for the element, which results in error. You can wait for the element to appear. You can find more information here.
With the combination of these, your code will be:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
browser = webdriver.Firefox()
browser.get('https://www.flickr.com/')
s = browser.find_element_by_id('search-field')
s.send_keys('volleyball')
s.submit()
s = WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.XPATH, "/html[1]/body[1]/div[1]/div[1]/div[3]/div[1]/div[1]/div[1]/div[2]/ul[1]/li[3]")))
s.click()

Finding dynamically named elements on a page using Selenium

I'm trying to locate and click on a section of a web page using Selenium so I can add a comment. I'm having a bit of trouble figuring out how to do this, though.
It seems like the class of the element changes from page-to-page. It also doesn't help that there are multiple similar elements in the document. Here's what I've come up so far:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_argument("--user-data-dir=/Users/me/Library/Application/Support/Google/Chrome/Default")
chrome_options.add_argument('--profile-directory=Profile 1')
driver = webdriver.Chrome(chrome_options=chrome_options)
driver.get("https://link-i-want-to-visit")
comment_section = driver.find_elements_by_xpath(("//input"))
print comment_section
comment_section.click()
Here's some of the markup from the relevant page:
<input class="sc-iKpIOp igoGaM" placeholder="Add a comment…">
On each different URL on this site, the class name appears to change. How can I circumvent that limitation, click into the input field, and send my comment?
Any guidance would be much appreciated. If it helps, this input field appears to be the last on the page, but I don't know if that's relevant (semantically).
Can't you use absolute xpath not including class?
e.g. /html/body/div/div/div/div/div/div/div/div/div/p[1] is your "I'm trying to..." paragraph on this page.
Also, try //input[placeholder="Add a comment…"]
comment_section = driver.find_elements_by_xpath("//input")
This will return list.So you can't click on list. You should use driver.find_element_by_xpath("//input") to click on the element.
However for a best practice Use WebDriverWait and Wait for the element element_to_be_clickable
and then click.
comment_section=WebDriverWait(driver,30).until(EC.element_to_be_clickable((By.XPATH,"//input[#placeholder='Add a comment…']")))
comment_section.click()
OR
comment_section=WebDriverWait(driver,30).until(EC.element_to_be_clickable((By.XPATH,"//input[contains(#placeholder,'Add a comment')]")))
comment_section.click()
You need to use following imports to execute above code.
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

Categories