Reputation: 411
I am trying to click on text links and that does not work:
from selenium import webdriver
driver = webdriver.Firefox()
driver.get("https://my.gumtree.com/login")
driver.find_element_by_name("username").send_keys(email)
driver.find_element_by_id("existingUser").click()
driver.find_element_by_id("fld-password").send_keys(password)
driver.find_element_by_xpath("//*[contains(text(), 'Continue')]").click() # works
driver.get("https://my.gumtree.com/postad")
driver.find_elements_by_xpath("//*[text()='For Sale']")[-1].click() # this now works, thanks
# driver.find_element_by_xpath("//*[contains(@span,'Appliances']").click() # this worked but I need the next line instead
driver.find_element_by_xpath("//span[text()[normalize-space()='Phones, Mobile Phones & Telecoms']]").click() # this does not work
driver.find_element_by_xpath("//span[text()[normalize-space()='Phones, Mobile Phones & Telecoms']]").click() # this does not work either
driver.find_element_by_xpath("//span[text()[normalize-space()='Mobile Phones']]").click()
driver.find_element_by_xpath("//span[text()[normalize-space()='Other']]").click()
HTML:
<li class="border-b is-parent" data-category-name="Appliances" data-category-url="kitchen-appliances" data-category-id="2485" data-category-children="true">
<span class="category-name">
<span class="category-list-control is-parent">
</span>
Appliances
</span>
</li>
What do I do wrong?
Upvotes: 1
Views: 12468
Reputation: 3927
As per provided HTML code I hope it will work:
//span[contains(text(),'For Sale')]
Upvotes: 2
Reputation: 1329
Your provided HTML does not show that the Appliances span contains a lot of whitespace which is likely the reason you are not finding this element. Try the following Xpath to find the Appliances span,
//span[text()[normalize-space()='Appliances']]
Below is the script I used,
from selenium import webdriver
email, password = 'your-own-email', 'your-own-password'
driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.get("https://my.gumtree.com/login")
driver.find_element_by_name("username").send_keys(email)
driver.find_element_by_id("existingUser").click()
driver.find_element_by_id("fld-password").send_keys(password)
driver.find_element_by_xpath("//*[contains(text(), 'Continue')]").click()
driver.get("https://my.gumtree.com/postad")
driver.find_elements_by_xpath("//*[text()='For Sale']")[-1].click()
driver.find_element_by_xpath("//span[text()[normalize-space()='Appliances']]").click()
driver.find_element_by_xpath("//span[text()[normalize-space()='Home Appliances']]").click()
driver.find_element_by_xpath("//span[text()[normalize-space()='Other Home Appliances']]").click()
For those elements that are not in view use the approach below,
element = driver.find_element_by_xpath("//span[text()[normalize-space()='Phones, Mobile Phones & Telecoms']]")
driver.execute_script("return arguments[0].scrollIntoView();", element)
element.click()
Upvotes: 0
Reputation: 1577
This kind of contains in XPath can be used in advanced scenarios, like your:
//span[text()[contains(.,'Appliances')]]
@Edit:
You can test all the XPath responses in this topic in Google Chrome using $x("selector")
. Maybe the problem is in your selenium version.
I really don't know the python syntax (I used to create tests in C#), but you can do a ugly code that will work. Try to change the code to python, I think there are some errors:
elements = driver.find_elements_by_cssselector("span.category-name")
for element in elements:
if (element.text == "Appliances" || element.text == "Home Appliances" || element.text == "Other Home Appliances")
element.click()
Upvotes: 0
Reputation: 761
If you have fixed strings in your HTML code, there is no need to use contains()
method in xpath. Please use text()
method of xpath:
driver.findElement(By.xpath(.//*[text()='Appliances'])).click();
The reason to use this is, if your HTML code contains two or more elements with the word "Applicances", it would not select any element. So, in order to avoid that ambiguity we can use text()=
directly.
Hope this helps.
Upvotes: 0
Reputation: 1057
Try the below one. Hope it helps.
driver.find_element_by_xpath("//*[text()='For Sale']")
Upvotes: 4
Reputation: 1845
In Selenium the XPath finding it's a bit broken for recursive searches of elements that don't specify the tag name. So don't use: //*[]
.
Furthermore the XPath is a bit broken. In your examples you are searching for an element that has an attribute named "span
" that contains the whatever string.
It should look like this:
driver.find_element_by_xpath("//a[contains(string(.),'For Sale']").click()
If you want, you can try germanium, a free test framework that I wrote, that deals with this kind of inconsistencies and more. In germanium the same code looks like:
click(Text("Other Home Appliances"))
Upvotes: 1