Iterating in dropdown-menu - python

i'm having some troubles with trying to get a list in python..
I'm using Selenium Web Driver, Chrome specifically, and i have the next "button" :
<button id="btn" class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown" aria-expanded="false">Nope</button>
<ul id="ulDropdownNivel2" class="dropdown-menu">
<li>
text1
</li>
<li>
text2
</li>
<li>
text3
</li>
</ul>
So.. i have tried to use Select.class of Selenium Wd but, it's a button, and the class can't be used there... tried using it on the <ul> but it can't use Select neither...
Can't use smh like:
dropdoun = Select(driver.find_element_by_id('ID'))
for elm in dropdoun{ print(elm.text())}
Tried to figure a way to iterate through items... but i didn't get anything
i figured a way to click by xPath but, it doesn't work to me, cause text1, text2, text3 and so changes the order everytime you open the web
Any idea?
EDIT:
What i need here, is to iterate trough each item, and select the one that match with "text1", "text2" or "text3...

I think you should click button for dropdown will be opened:
opendropdownButton = driver.find_element_by_id("btn").click()
//here should be wait if now works
dropdownElements = driver.find_elements_by_xpath("//ul [#id="ulDropdownNivel2"]//a")
for elm in dropdownElements{ print(elm.text())}

Related

Selenium [python] not clicking an <li> button

So I have been trying to use selenium to click an <li> button on an HTML which is in a <ul> tag and looks something like this:
...
<ul id="ulVisualization">
<li class="active" id="liMap">Map</li>
<li id="liBar" class="">Bar</li>
<li id="liLine">Line</li>
</ul>
...
I have been using the following command to get to the element using XPATH:
WebDriverWait(driver, 50).until(EC.presence_of_element_located((By.XPATH,"//li[#id='liBar']"))).click()
Yet for some reason that I have not been able to identify, this command is not able to find/click that button and the command hits its time-out.
I have even tried:
driver.find_element_by_xpath('//li[#id="liBar"]').click()
But that too was of no avail, throwing an error message saying NoSuchElementException: Message:
I would appreciate any and all help and thank you very much in advance.
EDIT:
Additionally, I have noticed that when I click on the button manually the HTML modifies to:
...
<ul id="ulVisualization">
<li class="" id="liMap">Map</li>
<li id="liBar" class="Active">Bar</li>
<li id="liLine">Line</li>
</ul>
...
Revealing the data I am trying to acquire later in the HTML code, which was not available before I clicked the button manually.
Since you want to click on the Element, try element_to_be_clickable, instead of presence_of_element_located
WebDriverWait(driver,30).until(EC.element_to_be_clickable((By.XPATH,"//li[#id='liBar']"))).click()
Make sure the locator you are using is Unique, that is 1/1. Link to Refer
And also check if the Elements are in an iframe or in an shadow-root or Trying to find Element in a newly opened browser tab.
If none of them work, apply some time.sleep() and check if it works.

get updated list elements after each click with selenium/python

Im trying to click on list elements in an unordered list.
It works fine for the first element, but once the loops goes into the second round I get this error message:
selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
this is my loop:
catlist=["Buy & Sell", "Books", "Textbooks"]
for r in range(0,len(catlist)):
categoryList = browser.find_element_by_xpath("//*[starts-with(#class, 'categoryList-')]")
avilableButtons=categoryList.find_elements_by_tag_name("li")
for text in avilableButtons:
if text.text == catlist[r] :
text.click()
print (r)
the category list is being replaced/updated(not sure what the correct phrase is here) with each selection (click) that has been made. so after each click I only find one unordered list named "categoryList-".
I tried using browser.implicitly_wait(10) to give it time but the issue remains the same.
Html relevant code:
this is the code before clicking the Buy&sell button.
<ul class="categoryList-3073244717">
<li class="categoryListItem-3726364752">
<button class="categoryButton-3830788057 button-1997310527 button__medium-1066667140">
<h5 class="categoryName-958974558 level1Category-2680817441">Buy & Sell</h5>
</button>
</li>
<li class="categoryListItem-3726364752">
<button class="categoryButton-3830788057 button-1997310527 button__medium-1066667140">
<h5 class="categoryName-958974558 level1Category-2680817441">Cars & Vehicles</h5>
</button>
</li>
after .click() the list from above is invisible/gone and I get the subcategory list.
<ul class="categoryList-3073244717">
<li class="categoryListItem-3726364752">
<button class="categoryButton-3830788057 button-1997310527 button__medium-1066667140">
<h5 class="categoryName-958974558 level2Category-867177555">Arts & Collectibles</h5>
<svg class="icon-459822882 actionIcon-2308908423" focusable="false" height="100%" role="img" width="100%">
<use xlink:href="#icon-arrow-right"></use>
</svg>
</button>
</li>
<li class="categoryListItem-3726364752">
<button class="categoryButton-3830788057 button-1997310527 button__medium-1066667140">
<h5 class="categoryName-958974558 level2Category-867177555">Books</h5>
</button>
</li>
the website Kijiji.ca which is basically like craiglist.
I came across this blog post after some more searching and asking google the right questions. http://darrellgrainger.blogspot.com/2012/06/staleelementexception.html
This describes the same issue, now with the added loop and try/except statement it works!
categoryToPost=["Buy & Sell", "Books", "Textbooks"]
attempts=0
for r in range(0,len(categoryToPost)):
while attempts <2:
categoryList = browser.find_element_by_xpath("//*[starts-with(#class, 'categoryList-')]")
availableButtons = categoryList.find_elements_by_tag_name("li")
try:
for text in availableButtons:
if text.text==categoryToPost[r]:
print (text.text)
text.click()
attempts=0
except EC.StaleElementReferenceException:
attempts+=1
break

How I use python selenium for click Navigation Bar With Dropdown

I want to click on "Page 1" for show list of sub menu
python code I used
driver.find_element_by_xpath("nav/div/ul/li[2]/a").click()
website code:
<ul class="nav navbar-nav">
<li class="active">Home</li>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">Page 1
<span class="caret"></span></a>
<ul class="dropdown-menu">
<li>Page 1-1</li>
<li>Page 1-2</li>
<li>Page 1-3</li>
</ul>
</li>
<li>Page 2</li>
<li>Page 3</li>
</ul>
Image of nav
As your requirement is "I want to click on "Page 1" for show list of sub menu".
Instead of using absolute xpath , you can use linkText.
parent_page1 = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.LINK_TEXT, "Page 1")))
parent_page1.click()
if this linkText does not work out for you, you can use a relative xpath :
parent_page1 = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//a[#class='dropdown-toggle' and contains(text(),'Page 1')]")))
parent_page1.click()
Note that this code will click on Page 1 , if and only if it is clickable.
If it is a hover action then you can go ahead with action chain.
Note : This is for parent Page1 . Not for child. and based on the xpath you have tried nav/div/ul/li[2]/a
Your x-path is not correct. any x-path starts with / or //. This may be the issue.
try with the x-path //nav/div/ul/li[2]/a
in code,
driver.find_element_by_xpath("//nav/div/ul/li[2]/a").click()
I guess, you are using w3school bootstrap navigation bar. If yes, the page is inside frame, so first you need to switch to the frame as given below.
driver.switch_to_frame("iframeResult")
driver.find_element_by_xpath("//nav/div/ul/li[2]/a").click()

I want to click on the <li> item in the left navigation of a webpage, using Python and Selenium webdriver to locate it

I want to click on MAKE UP in the
left navigation, Please find attached image and link for the webpage
Image for the Webpage
Link for the Webpage
I am currently using the below code to click on the item but not
getting any result.I am able to acces the elements by class
name('has-sub').I can even print them but cant click them
obc = driver.find_elements_by_class_name('has-sub')
for ea in obc:
if ea.text == "Makeup":
ea.click()
Just for the more info below is the html code for the webpage
<li class="has-sub" style="height: 38px;">
Makeup
<ul class="submenu" style="top: 0px;">
<li>
<a id="SBN_facet_Face" href="http://shop.davidjones.com.au/djs/en/davidjones/beauty/face" escapexml="false">Face </a>
</li>
<li>
<a id="SBN_facet_Lips" href="http://shop.davidjones.com.au/djs/en/davidjones/beauty/lips" escapexml="false">Lips </a>
</li>
<li>
<a id="SBN_facet_Eyes" href="http://shop.davidjones.com.au/djs/en/davidjones/beauty/eyes" escapexml="false">Eyes </a>
</li>
<li>
<a id="SBN_facet_Nails" href="http://shop.davidjones.com.au/djs/en/davidjones/beauty/nails" escapexml="false">Nails </a>
</li>
<li>
<a id="SBN_facet_Brushes & Tools" href="http://shop.davidjones.com.au/djs/en/davidjones/beauty/beauty-brushes-accessories" escapexml="false">Brushes & Tools </a>
</li>
<li>
<a id="SBN_facet_Makeup" href="http://shop.davidjones.com.au/djs/en/davidjones/beauty/beauty-makeup" escapexml="false">All Makeup </a>
</li>
</ul>
</li>`enter code here`
Any help will be appreciated .
I am able to click using below code.
wait = WebDriverWait(driver, 10)
elements = wait.until(EC.presence_of_all_elements_located((By.XPATH, "//li[#class='has-sub']")))
for element in elements:
if element.find_elements_by_link_text("Makeup"):
element.click()
break
innerElements = wait.until(EC.presence_of_all_elements_located((By.XPATH, "//li[#class='has-sub open']/ul/li")))
for innerElement in innerElements:
if innerElement.text == "Face":
innerElement.click()
break
Hope this will help you.
Problem here is, you are trying to click on the element while the text is under the element. So what you are going to need to do is:
obc = driver.find_elements_by_xpath('//li[#class='has-sub']/a[contains(text(), 'Makeup')]')
I tested the xpath on your webpage and it worked.
As per the HTML you have provided, to click on MAKE UP in the left navigation pane, you can use the following code block :
obc = WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.XPATH, "//div[#class='aside all-open']/ul//li[#class='has-sub']/a")))
for ea in obc:
if 'Makeup' in ea.get_attribute("innerHTML"):
ea.click()
break

python, locating and clicking a specific button with selenium

Using python and selenium I need to locate and click a specific button on a webpage. While under normal circumstances this can be done with the commands
next = driver.find_element_by_css_selector(".next")
next.click()
that won't work in this case due to the webpages coding. Where both the button leading to the previous page and the one leading to the next share the same class name. Thus this code will only go back and forth between the first and second page
As far as I can tell the only way to tell the two buttons apart, is that the button leading to the previous page lies within
<li class="previous">
#button
</li>
and the one that leads to the next page lies within
<li class="next">
#button
</li>
Is there some way of having selenium only select and click the button that lies in the "next" li class?
The complete button code:
the previous button:
<li class="previous">
<a class="next" rel="nofollow" onclick="qc.pA('nrForm', 'f76', 'QClickEvent', '1', 'f28'); return false;" href="">
Previous
</a>
</li>
the next button:
<li class="next">
<a class="next" rel="nofollow" onclick="qc.pA('nrForm', 'f76', 'QClickEvent', '3', 'f28'); return false;" href="">
Next
</a>
</li>
I think you should use .find_element_by_xpath().
For example:
next = driver.find_element_by_xpath("//li[#class='next']/a")
prev = driver.find_element_by_xpath("//li[#class='previous']/a")
or:
next = driver.find_element_by_xpath("//a[text()='Next']")
prev = driver.find_element_by_xpath("//a[text()='Previous']")
With CSS selectors:
next = driver.find_element_by_css_selector('li.next>a')
CSS Selectors are cool and useful: http://www.w3schools.com/cssref/css_selectors.asp
XPATH, not so much - it should be used only as a last resort.

Categories

Resources