partial text in xpath - python

<a class="ui-autocomplete-row ui-corner-all"
aria-label="(1100)Texas (PL1200/PC1030)- (200167)-Supplies: Other Supplies (620038): 1100-1200-200167-620038"
id="ui-id-7" tabindex="-1">
(1100)- (PL1200/PC1030)-(200167)-Supplies:
Other Supplies (620038):
<u><b>1100-1200-200167-620038</b></u>
</a>
In Xpath, I want to check if aria-label contains the value "1100-1200-200167-620038". It looks like there is a syntax error in the below statement:
element = wait.until(EC.visibility_of_element_located((By.XPATH,'//*[#aria-label="1100-1200-200164-620038"]')))

You can use two option like this:
CSS Selector
element = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, 'a[aria-label*="1100-1200-200167-620038"]')))
Xpath:
element = wait.until(EC.visibility_of_element_located((By.XPATH, '//a[contains(#aria-label, "1100-1200-200167-620038")]')))

Xpath can be a hassle sometimes, I recommend using the CSS selector method to accomplish this:
element = driver.find_elements_by_css_selector("[aria-label='1100-1200-200167-620038']")
You could them use the element in your visibility_of_element_located method.

Related

How to find element with "== $0" after end tag in html using Xpath, css or any other locators in Selenium Python?

the html tag
<div class=""><div>Bengaluru, Karnataka</div></div>
Consider the above example for reference.
I tried the following code but it doesn't work!!!
driver.find_element(By.XPATH,'//div[#class=""]').text.strip()
You can not filter by that "==$0"
But you can use this xpath, which will return to you the element with following requirements:
It is a "div"
That "div" contains an attribute "class"
That "class" attribute has a length of 0 chars
This is the xpath:
//div[#class[string-length()=0]]
You can use this:
driver.find_element(By.XPATH, ".//div[#class='']/div").text
Output:
Bengaluru, Karnataka

Selenium: Unable to locate element by class and id

Trying to scrape a website, I created a loop and was able to locate all the elements. My problem is, that the next button id changes on every page. So I can not use the id as a locator.
This is the next button on page 1:
<a rel="nofollow" id="f_c7" href="#" class="nextLink jasty-link"></a>
And this is the next button on page 2:
<a rel="nofollow" id="f_c9" href="#" class="nextLink jasty-link"></a>
Idea:
next_button = browser.find_elements_by_class_name("nextLink jasty-link")
next_button.click
I get this error message:
Message: no such element: Unable to locate element
The problem here might be that there are two next buttons on the page.
So I tried to create a list but the list is empty.
next_buttons = browser.find_elements_by_class_name("nextLink jasty-link")
print(next_buttons)
Any idea on how to solve my problem? Would really appreciate it.
This is the website:
https://fazarchiv.faz.net/faz-portal/faz-archiv?q=Kryptow%C3%A4hrungen&source=&max=10&sort=&offset=0&_ts=1657629187558#hitlist
There are two issues in my opinion:
Depending from where you try to access the site there is a cookie banner that will get the click, so you may have to accept it first:
browser.find_element_by_class_name('cb-enable').click()
To locate a single element, one of the both next buttons, it doeas not matter, use browser.find_element() instead of browser.find_elements().
Selecting your element by multiple class names use xpath:
next_button = browser.find_element(By.XPATH, '//a[contains(#class, "nextLink jasty-link")]')
or css selectors:
next_button = browser.find_element(By.CSS_SELECTOR, '.nextLink.jasty-link')
Note: To avoid DeprecationWarning: find_element_by_* commands are deprecated. Please use find_element() import in addition from selenium.webdriver.common.by import By
You can't get elements by multiple class names. So, you can use find_elements_by_css_selector instead.
next_buttons = browser.find_elements_by_css_selector(".nextLink.jasty-link")
print(next_buttons)
You can then loop through the list and click the buttons:
next_buttons = browser.find_elements_by_css_selector(".nextLink.jasty-link")
for button in next_buttons:
button.click()
Try below xPath
//a[contains(#class, 'step jasty-link')]/following-sibling::a

How to find an element with respect to its parent element with Selenium and Python

I am trying to scrape a website, but I need to search for an element whose parent is like this:
//div[#title="parent"]
People are talking about getting an element from its child. Is there a way to reverse it and find the child from its parent?
I want the /span with #title = "child" whose parent is //div[#title = "Search results."]
You can try to use
//div[parent::div[#title="parent"]]
or simply
//div[#title="parent"]/div
In Python code you can also use
parent = driver.find_element(By.XPATH, '//div[#title="parent"]')
child = parent.find_element(By.XPATH, './div')
To locate the child element:
<span title="child"...>
within it's parent:
<div title="Search results."...>
you can use either of the following Locator Strategies:
Using css_selector:
element = driver.find_element(By.CSS_SELECTOR, "div[title='Search results.'] span[title='child']")
Using xpath:
element = driver.find_element(By.XPATH, "//div[#title='Search results.']//span[#title='child']")

Alternatives to using selenium XPATH to find an element?

On this website, I'm trying to find an element based on its XPATH, but the XPATH keeps changing. What's the next best alternative?
Snippet from website
<button class="KnkXXg vHcWfw T1alpA kiPMng AvEAGQ vM2UTA DM1_6g _-kwXsw Mqe1NA SDIrVw edrpZg" type="button" aria-expanded="true"><span class="nW7nAQ"><div class="VpIG5Q"></div></span></button>
XPATH:
//*[#id="__id15"]/div/div/div[1]/div[2]/div
#Sometimes id is a number between 15-18
//*[#id="__id23"]/div/div/div[1]/div[2]/div
#Sometimes id is a number between 13-23
Here's how I use the code:
element = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, """//*[#id="__id3"]/div/div/div[1]/div[2]/div/div/div/button"""))).click()
I've tried clicking the element by finding the button class, but for whatever reason it won't do anything.
element = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, "KnkXXg vHcWfw T1alpA kiPMng AvEAGQ vM2UTA DM1_6g _-kwXsw Mqe1NA SDIrVw edrpZg"))).click()
If Part of the text is keep changing you can use contains in the xpath.
//*[contains(#id,"__id"]/div/div/div[1]/div[2]/div

find_element_by_class_name class spaces does not work

I'm trying to use find_element_by_class_name where the class has spaces and it does not work:
Here is the code:
<a class="yt-simple-endpoint style-scope yt-formatted-string" href="/user/santanderbrasil">Santander Brasil</a>
I want the get the content "Santander Brasil"
I tried the following:
driver.find_element_by_class_name("yt-simple-endpoint.style-scope.yt-formatted-string")
driver.find_element_by_class_name("a.yt-simple-endpoint.style-scope.yt-formatted-string")
and
driver.find_element_by_class_name("a.yt-simple-endpoint.")
none of the worked...
Any help?
Use the css selector function instead.
driver.find_element_by_css_selector("a.yt-simple-endpoint.style-scope.yt-formatted-string")
Those are three separated classes, find_element_by_class_name() receives only one class as parameter. For example
driver.find_element_by_class_name('yt-simple-endpoint')
The . you added between the classes represent class in css_selector. You can use it to locate the element by all three classes use css_selector
driver.find_element_by_css_selector('.yt-simple-endpoint.style-scope.yt-formatted-string')
Or by xpath
driver.find_element_by_xpath('//a[#class="yt-simple-endpoint style-scope yt-formatted-string"]')
Try this
driver.find_element_by_xpath("//div[contains(#class, 'yt-simple-endpoint') and contains(#class, 'style-scope') and contains(#class, 'yt-formatted-string')]"")
Not sure about the find_element_by_xpath method because i don't use selenium in python, but whatever that function is, selector should do the trick.
Hope this helps.
All of these work for me (Firefox driver):
yt-simple-endpoint
style-scope
yt-formatted-string
yt-simple-endpoint.style-scope.yt-formatted-string
Note that the last class name is actually the same as the first one in your question. It works because Selenium internally converts the class name into a CSS selector and then uses it for the search. If you want to nail things down for specific tags, e.g. only match <a> tags with those classes then you will need to look at CSS selectors and other options such as XPath.
from selenium import webdriver
driver = webdriver.Firefox()
driver.get("file:///tmp/test.html")
for class_name in 'yt-simple-endpoint', 'yt-formatted-string', 'style-scope', 'yt-simple-endpoint.style-scope.yt-formatted-string':
e = driver.find_element_by_class_name(class_name)
print(e.text)
driver.close()
Output
Santander Brasil
Santander Brasil
Santander Brasil
Santander Brasil
The test.html file contains:
<html>
<head><title>Test</title></head>
<body>
<a class="yt-simple-endpoint style-scope yt-formatted-string" href="/user/santanderbrasil">Santander Brasil</a>
</body>
</html>

Categories