Selenium Python find_element Xpath cant find xpath - python

I want to access an website with selenium and than a addblock-window appears, in which i need to click a button for it to disappear.
Eventhough I can find my XPath(//button[#title='Einverstanden'], /html/body/div/div[2]/div[3]/div[1]/button[#title = 'Einverstanden'] or
//button[contains(text(),"Einverstanden")]') in the browser,
I can't find it with my Python script. And i can't seem to find the mistake.
Here is my code.
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
driver = webdriver.Firefox()
driver.implicitly_wait(30)
driver.get("``https://www.derstandard.at/story/2000134260361/endspiel-vor-gericht-prozess-gegen-boris-becker-startet-in-london``")
driver.maximize_window()
x = driver.find_element(By.XPATH, "//button[#title = 'Einverstanden']")
print(x)
This is the error I'm getting.

The button is enclosed in an iframe in which case, you first need to switch to the iframe and then access the element
This should work:
driver.get("https://www.derstandard.at/consent/tcf/")
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH, "//div[contains(#id, 'sp_message_container')]//iframe")))
WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "button[title='Einverstanden']"))).click()
Wait Imports:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
In case you want to switch to default frame again, you may use this when required:
driver.switch_to.default_content()

Related

Can't click on a grid with the absence of some hardcoded delay

I'm trying to click on Jetzt bewerben available in this webpage using selenium. The script that I've written so far can click on that grid If I stick with hardcoded delay. I would like to do the clicking without using any hardcoded delay.
I've tried with:
import time
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
url = "https://jobs.deloitte.de/job/D%C3%BCsseldorf-Werkstudent-%28mwd%29-Administration-Business-Process-Solutions/522320501/"
driver = webdriver.Chrome()
driver.get(url)
wait = WebDriverWait(driver,10)
time.sleep(5)
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR,"a#bewerben_top > h1"))).click()
How can I click on that grid shaking off hardcoded delay?
There is not a problem with a fact that button is not clickable or not visible.
The problem is that there is Javascript doing some "magic" to the button.
All you need to do is to wait until the document is complete.
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
url = "https://jobs.deloitte.de/job/D%C3%BCsseldorf-Werkstudent-%28mwd%29-Administration-Business-Process-Solutions/522320501/"
driver = webdriver.Chrome()
driver.get(url)
wait = WebDriverWait(driver,10)
wait.until(lambda d: d.execute_script("return document.readyState")=='complete')
driver.find_element_by_css_selector("a#bewerben_top > h1").click()
Your locator strategy was perfect. However, there are a couple of things:
It seems the Browsing Context of the website https://jobs.deloitte.de/job/D%C3%BCsseldorf-Werkstudent-%28mwd%29-Administration-Business-Process-Solutions/522320501/ returns back the control even before document.readyState turns complete.
Ideally, you should acknowledge the Acceptance of the website's cookie policy.
As per best practices, while invoking click() you need to induce WebDriverWait for the element_to_be_clickable().
You can use the following Locator Strategies:
driver.get("https://jobs.deloitte.de/job/D%C3%BCsseldorf-Werkstudent-%28mwd%29-Administration-Business-Process-Solutions/522320501/")
WebDriverWait(driver, 10).until(lambda driver: driver.execute_script('return document.readyState') == 'complete')
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button#cookie-acknowledge"))).click()
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a#bewerben_top > h1"))).click()
Note: You have to add the following imports:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
PS: In such one off scenarios you may require to wait for the jQuery to complete as follows:
WebDriverWait(driver, 20).until(lambda driver: driver.execute_script('return jQuery.active') == 0)

Nothing happend when clicking a button in selenium

from selenium import webdriver
import time
driver = webdriver.Chrome()
driver.get('https://www.worldometers.info/coronavirus/country/canada/')
time.sleep(1)
button = driver.execute_script("window.scrollTo(0, 5500)")
button1 = driver.find_element_by_xpath('/html/body/div[4]/div[2]/div[1]/div[8]/div/div[9]/a/button')
button1.click()
Trying to click this button using xpath but it just doesn't seem to click the button to extend the webpage. I first tried to copy by xpath which didn't work and then I copied the full xpath which also didn't work. After that, I tried to find by name and enter the text on the button and click the button. But none of these methods actually worked and clicked the button. So how can I click this button so that it extends the webpage allowing me to scrape more of the webpage?
The problem was that the button wasn't at "clickable state" despite was rendered in page at moment.
To obviate this, you have to add an explicit wait to tell the driver to wait until it's state change to clickable.
Try to use this code instead :
from selenium import webdriver
import time
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
driver.get('https://www.worldometers.info/coronavirus/country/canada/')
time.sleep(1)
button = driver.execute_script("window.scrollTo(0, 5500)")
button1 = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '/html/body/div[4]/div[2]/div[1]/div[8]/div/div[9]/a/button')))
button1.click()
To click on View more News Induce WebdriverWait and wait for presence_of_element_located() and following css selector.
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get('https://www.worldometers.info/coronavirus/country/canada/')
button=WebDriverWait(driver,20).until(EC.presence_of_element_located((By.CSS_SELECTOR,"a.load-more__btn>.btn")))
button.location_once_scrolled_into_view
button.click()
Or Use following xpath
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get('https://www.worldometers.info/coronavirus/country/canada/')
button=WebDriverWait(driver,20).until(EC.presence_of_element_located((By.XPATH,"//a[#class='load-more__btn']/button[#class='btn']")))
button.location_once_scrolled_into_view
button.click()

Login Button can not be found with selenium

https://www.sevenonemedia.de/tv/programm/programmwochen
Here I want to login:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import time
options = Options()
chrome_path = "T:/Markus/WebScrapingExample/Chromedriver/chromedriver.exe"
driver = webdriver.Chrome(executable_path=chrome_path,chrome_options=options)
driver.set_window_size(1280, 720)
time.sleep(5)
driver.get("https://www.sevenonemedia.de/tv/programm/programmwochen")
driver.find_element_by_id("_58_login").send_keys("name")
driver.find_element_by_id("_58_password").send_keys("pw")
driver.find_element_by_xpath('//*[#id="sign-in-button"]').click()
ElementNotInteractableException: element not interactable
(Session info: chrome=78.0.3904.97)
This is my error
Id is there. Why does this happen?
This page contains duplicate of element with ID sign-in-button. If your selector points to more than one element, driver always takes the first from the top of the DOM one which is not interactable in this case. You must refer to the second element with this id. Try this selector for "Sign in" button:
//*[#id="aheadcustom_p_p_id_58"]//button
hi first things you should not give your password to all of the stackoverflow community :)
you can't click on the button because there is a popup at the bottom of the page and you have to click on it first for selenium it's hidding your button
last is that the totality of your code ?
if yes you forgot
driver = webdriver.Firefox() #or any other webdriver
you have not create driver without this line
EDIT !!
it wasn't working with only the modification above but with this one its good
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import time
time.sleep(5)
driver = webdriver.Firefox()
driver.get("https://www.sevenonemedia.de/tv/programm/programmwochen")
driver.find_element_by_id("_58_login").send_keys("login")
driver.find_element_by_id("_58_password").send_keys("pssd")
driver.find_element_by_xpath("/html/body/div[1]/div/div/div[2]/a").click()
driver.find_element_by_css_selector("#_58_fm > fieldset:nth-child(1) > div:nth-child(6) > button:nth-child(1)").click()
this work :)
sometime css selector a safer and work better
To click on the Login button you have to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following solutions:
Using XPATH:
driver.get("https://www.sevenonemedia.de/tv/programm/programmwochen")
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[#title='Anmelden' and not(contains(#name,'INSTANCE'))]"))).send_keys("a.mai#mediaplus.com")
driver.find_element_by_xpath("//input[#title='Passwort' and not(contains(#name,'INSTANCE'))]").send_keys("Edidaten17")
driver.find_element_by_xpath("//input[#title='Passwort' and not(contains(#name,'INSTANCE'))]//following::button[1]").click()
Note : You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
Browser Snapshot:
The problem is that your button locator isn't unique on the page. It finds two buttons, the first of which is not visible which causes the ElementNotInteractableException.
The simple fix is to use the CSS selector below
#main-content #sign-in-button
That will find only the button you want. So your last few lines of code would be
driver.find_element_by_id("_58_login").send_keys("name")
driver.find_element_by_id("_58_password").send_keys("pw")
driver.find_element_by_css_selector('#main-content #sign-in-button').click()
sleep(1)
login_box = driver.find_element_by_name('login')
login_box.click()
this is for facebook login button, just inspect the website and see the id/name/type to make your code automate to work properly

Selenium Python Script throws no element error exception even though the x path is right?

from selenium import webdriver
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.common.keys import Keys
driver=webdriver.Chrome()
driver.get("https://paytm.com/")
driver.maximize_window()
driver.find_element_by_class_name("login").click()
driver.implicitly_wait(10)
driver.find_element_by_xpath("//md-input-container[#class='md-default-theme md-input-invalid']/input[#id='input_0']").send_keys("99991221212")
In the above code, I have verified the xpath using fire bug its highlighting the correct element. But when the script run its failing? Can you help me folks?
In selenium each frame is treated individually. Since the login is in a separate iframe element, you need to switch to it first using:
iframe = driver.find_elements_by_tag_name('iframe')[0]
driver.switch_to_frame(iframe)
Before trying to interact with it's elements.
Or in this case, you would wait for the frame to exist, and it would 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
driver = webdriver.Chrome()
driver.get("https://paytm.com/")
driver.maximize_window()
wait = WebDriverWait(driver, 10)
wait.until(EC.visibility_of_element_located((By.CLASS_NAME, "login"))).click()
wait.until(EC.frame_to_be_available_and_switch_to_it((By.TAG_NAME, "iframe")))
_input = wait.until(EC.visibility_of_element_located((By.ID,"input_0")))
_input.send_keys("99991221212")
You should try using WebDriverWait to wait until input element visible on the page as below :-
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
driver.get("https://paytm.com/")
driver.maximize_window()
wait = WebDriverWait(driver, 10)
wait.until(EC.visibility_of_element_located((By.CLASS_NAME, "login"))).click()
#now switch to iframe first
wait.until(EC.frame_to_be_available_and_switch_to_it((By.TAG_NAME, "iframe")))
input = wait.until(EC.visibility_of_element_located((By.ID, "input_0")))
input.send_keys("99991221212")
Hope it helps...:)

Can not find/click this button with Selenium/Firefox

I am trying to press this "New Search" button. It appears on the top of the screen after entering a search on http://www.lexisnexis.com/hottopics/lnacademic/
I have looked at the Xpath and Unique Selector.
What I have tried:
browser.find_element_by_css_selector('#restoreButtons > a:nth-child(3)').click()
browser.find_element_by_xpath(id('restoreButtons')/x:a[3])
browser.find_element_by_xpath(/x:a[3])
For all three I get an "unable to locate element error"
To build on alecxes answer,
once you're inside the iframe, you can find the clickable using it's xpath:
new_search_xpath = '/html/body/div[2]/table/tbody/tr[2]/td[2]/div[1]/table/tbody/tr/td/span/a[3]'
new_search = driver.find_element(By.XPATH, new_search_xpath)
new_search.click()
You should consider installing firebug firefox addon to grab Xpaths:
https://addons.mozilla.org/en-US/firefox/addon/firebug/
This is because the element is inside an iframe. You have to be in the context to search elements inside. Use .switch_to.frame():
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
wait = WebDriverWait(driver, 10)
frame = wait.until(EC.presence_of_element_located((By.ID, "mainFrame")))
driver.switch_to.frame(frame)
FYI, here is the complete working code:
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get('http://www.lexisnexis.com/hottopics/lnacademic/')
actions = ActionChains(driver)
wait = WebDriverWait(driver, 10)
frame = wait.until(EC.presence_of_element_located((By.ID, "mainFrame")))
driver.switch_to.frame(frame)
driver.find_element_by_id("terms").send_keys("Test")
driver.find_element_by_id("srchButt").click()

Categories

Resources