How to find element by xpath in Selenium Python? - python

I am trying to use Selenium in Python to click on a link to a report on a web page. I have it working up to the point where it opens the page that the report is on, but I am having trouble actually clicking that specific report.
The page has a list of reports all with the same class. This is what I get when I inspect that specific report for example:
<a class="rpt" href="reportConfigRedirect.asp?action=filter&rc_id=181786&letter=">Run with new filters</a>
I have tried:
driver.find_element_by_xpath("xpath")
and this doesn't seem to work, it doesn't do anything once it gets to that page with the report.

Induce WebdriverWait and element_to_be_clickable.Use the following Xpath.
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
element=WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.XPATH,"//a[#class='rpt'][contains(.,'Run with new filters')]")))
element.click()
If unable to click using Webdriver try use javascript executor.
element=WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.XPATH,"//a[#class='rpt'][contains(.,'Run with new filters')]")))
driver.execute_script("arguments[0].click();",element)
EDITED
element=WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.XPATH,"//a[contains(.,'Run with new filters')]")))
driver.execute_script("arguments[0].click();",element)
OR
element=WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.XPATH,"//a[contains(#hef,'reportConfigRedirect.asp?action=filter')][contains(.,'Run with new filters')]")))
driver.execute_script("arguments[0].click();",element)

Related

Getting data after page update using Selenium

I am wondering if anyone knows a way to get page data after it updates content from a post request via Selenium. I understand that the way Selenium works is by when you get() a website it parses the content at its current state and then that is what you have have to work with but I am wondering if anyone knows how to get this updated conent without "getting" the page again?
You need to wait for the visibility of some static element after the page is completely updated, before you attempt to get the data inducing WebDriverWait for the visibility_of_element_located() as follows:
WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//xpath_of_static_element")))
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

Python Selenium ID Tags change each time i refresh the page

I am currently trying to automate a data entry process. Every time I refresh the page the ID tags change and make it impossible. I read that I can use CSS selectors or a possible xpath using tags that don't change. It seems that only the ID tags are the problem.
Below is the HTML code for the button. Every time i try and use the CSS selector i got a no such element exception. I think I am doing it wrong. Please help.
<button type="button" class="dark button secondary" data-automation-id=
"btn-footer-save" data-dojo-attach-event="onclick:saveAndStayPressed"
data-qbo-bind="visible:shouldShowSaveAndStayButton" style>Save</button>
Try this:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
wait = new WebDriverWait(driver, 20)
wait.until(EC.element_to_be_clickable((By.XPATH, "//button[contains(text(),'Save')]"))).click()
The element gets wrapped in a WebDriverWait until it is interactable, in this case clickable

Python + Selenium -- Unable to locate image element (Can't click image)

I'm trying to create a macro that opens up all my online classes on Chrome (cause logging in is annoying, especially if you have to do it 8 times every morning).
BTW, I use Python 3.8, Chrome 81.0.4044.122, and the latest version of Selenium.
Until now, I clicked button using:
driver = webdriver.Chrome()
driver.find_element_by_xpath("PATH_OF_ELEMENT").click()
And then I find a login button that has a image instead of text.
I tried XPath, CSS Selector, id, name, the link of text, ActionChains (move_to) nothing works.
Here's the HTML:
here click me please.
The button I'm trying to press is the one with the tag a.
I spent 30 minutes googling about this and all I found was Stack Overflow questions from 6 years ago. They suggested I use WebDriverWait or change the frame. None of them worked (I might have made a mistake). I'm new to Selenium so please be kind and explain hard stuff.
How can I find the correct XPath of an image button and click it?
driver.find_element_by_css_selector('.nice-select').click()
driver.find_element_by_xpath("/html/body/div1/div[3]/div/div/div/div/div/div2/div1/div/ul/li2").click()
driver.find_element_by_xpath('/html/body/div1/div[3]/div/div/div/div/div/div2/div2/div/span').click()
driver.find_element_by_xpath('/html/body/div1/div[3]/div/div/div/div/div/div2/div2/div/ul/li[19]').click()
driver.find_element_by_xpath('/html/body/div1/div[3]/div/div/div/div/div/div2/div[3]/div/span').click()
driver.find_element_by_xpath('/html/body/div1/div[3]/div/div/div/div/div/div2/div[3]/div/ul/li[3]').click()
driver.find_element_by_xpath('/html/body/div1/div[3]/div/div/div/div/div/div2/div[4]/div/span').click()
driver.find_element_by_xpath('/html/body/div1/div[3]/div/div/div/div/div/div2/div[4]/div/ul/li[3]').click()
driver.find_element_by_xpath('/html/body/div1/div[3]/div/div/div/div/div/div2/div[5]/a').click()
Try the following CSS Selector:
.my_menu>a
Code should look like:
driver.find_element_by_css_selector(".my_menu>a").click()
Also, try to locate the element with explicit wait:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".my_menu>a"))).click()
I have tested with the following code block (as result will be displayed popup with 2 options):
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
import time
driver = webdriver.Chrome()
driver.get("https://oc31.ebssw.kr/onlineClass/search/onlineClassSearchView.do?schulCcode=00898&schCssTyp=online_mid")
WebDriverWait(driver, 20).until(EC.element_to_be_clickable(
(By.CSS_SELECTOR, ".my_menu>a"))).click()
time.sleep(5)
I hope it helps you!

xpath for first post on instagram profile not working (python, selenium, chromedriver)

I am trying to click on the first post after navigating to any Instagram profile. I looked at the xpath of the first post of multiple Instagram user's profiles and they all seem to be the same. Here is an example of messi's profile.
Here is my attempt with using chromedriver with python to click on Messi's first post. I have already navigated to https://www.instagram.com/leomessi/, which is Messi's profile.
first_post_elem_click = driver.find_element_by_path('//*[#id="react-root"]/section/main/div/div[4]/article/div[1]/div/div[1]/div[1]/a/div').click()
However, the first post is not being clicked on. Would greatly appreciate any help.
Please check below solution,
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
Browser = webdriver.Chrome(executable_path=r"chromedriver.exe")
Browser.get("https://www.instagram.com/leomessi/")
WebDriverWait(Browser, 20).until(EC.element_to_be_clickable((By.XPATH, "//body//div[contains(#class,'_2z6nI')]//div//div//div[1]//div[1]//a[1]//div[1]//div[2]"))).click()
Instead of using the absolute xpath, you should be using relative xpath.
You can click on the first post using the below command(Have applied Explicit wait as well):
WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, "(//div[#class='Nnq7C weEfm']//img)[1]"))).click()
You need 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
I have just checked this in Firefox: $x('//*[#id="react-root"]/section/main/div/descendant::article/descendant::a[1]'). That should give you what you want, I think.

How to click a button on a website by finding its id

When I run the code, the website loads up fine but then it won't click on the button- an error appears saying the element is not interacterble. What do I need to do to click the button? I am relatively new to this and would be grateful for any help.
I have already tried finding it by id and tag.
page = driver.get("https://kenpreston.co.uk/author/")
element = driver.find_element_by_id('mk-button-31')
element.click()
SOLVED:
I used driver.find_element_by_link_text and this worked fine.
I have checked the website and noticed that mk-button-31 is an id for a div tag and inside it there is an a tag. Try getting the url from the a tag and do another driver.get instead of clicking on it.
Also the whole div tag is not clickable so that is why you are getting this error.
Use sleep from time library to be sure page fully loaded
from time import sleep
page = driver.get("https://kenpreston.co.uk/author/")
sleep(2)
element = driver.find_element_by_id('mk-button-31')
element.click()
Looks like your element is not clickable you need to replace this id selector with the css and need to wait for the element before click on it.
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
page = driver.get("https://kenpreston.co.uk/author/")
element = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "#mk-button-31 span"))
element.click();
Consider adding Explicit Wait to your script as it might be the case the DOM had finished loading and the button you're looking for is still not there.
The classes you're looking for are:
WebDriverWait
expected_conditions
Suggested code change:
#your other imports here
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions
#your other code here
page = driver.get("https://kenpreston.co.uk/author/")
element = WebDriverWait(driver, 10).until(expected_conditions.element_to_be_clickable((By.ID, "mk-button-31")))
element.click()
More information: How to use Selenium to test web applications using AJAX technology

Categories