How I use python selenium for click Navigation Bar With Dropdown - python

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()

Related

Web scraping ignore "Next" or ">" when hidden (Selenium, Python)

I am using Selenium for Python to scrape a site with multiple pages. To get to the next page, I use driver.find_element(By.XPATH, xpath). However, The xpath text changes. So, instead, I want to use other attributes.
I tried to find by class, using "page-link": driver.find_element(By.CLASS_NAME, "page-link". However, the "page-link" class is also present in the disabled list item. As a result, the Selenium driver won't stop after the last page, in this case page 2.
I want to stop the driver clicking the disabled item on the page, i.e. I want it to ignore the last item in the list, the one with "page-item disabled", aria-disabled="true" and aria-hidden="true". The idea is that if the script can't find that item, it will end a while loop that relies on the ">" button to be enabled.
See the source code below.
Please advise.
<nav>
<ul class="pagination">
<li class="page-item">
<a class="page-link" href="https://www.blucap.net/app/FlightsReport?fromdate=2023-02-01&todate=2023-02-28&filterByMemberId=&view=View%20Report&page=1" rel="prev" aria-label="« Previous">‹</a>
</li>
<li class="page-item">
<a class="page-link" href="https://www.blucap.net/app/FlightsReport?fromdate=2023-02-01&todate=2023-02-28&filterByMemberId=&view=View%20Report&page=1">1</a>
</li>
<li class="page-item active" aria-current="page">
<span class="page-link">2</span>
</li>
<li class="page-item disabled" aria-disabled="true" aria-label="Next »">
<span class="page-link" aria-hidden="true">›</span>
</li>
</ul>
</nav>
To go to the Next Page there can be a couple of approaches:
You can opt to find_element() and click it's descendant <span> of the <li> with aria-label="Next »" but doesn't contains aria-disabled="true" as follows:
driver.find_element(By.XPATH, "//li[starts-with(#aria-label, 'Next') and not(#aria-disabled='true')]/span").click()

Iterating in dropdown-menu

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())}

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

Why did changing my xpath make my selenium click work consistently?

I am running a series of selenium tests with python. I have a navigation on the page I'm testing that has this structure:
<ul>
<li class="has-sub">
<a href="#">
<span> First nav </span>
</a>
<ul style="display:block">
<li>
<a href="#">
<span> First subnav </span>
</a>
</li>
<li>...</li>
<li>...</li>
<li>...</li>
</ul>
</li>
<li>...</li>
</ul>
Now I am clicking on the first subnav, that is the first span, but clicking on First nav to open up that list then first subnav. I implement a webdriverwait, to wait for the element to be visible and click on it via it's xpath,
//span[1]
I often got timeout exceptions waiting for the subnav span to be visible after clicking on the nav, which made me think something was wrong with clicking on the first nav to open up the list. So I changed the xpath of the first nav (//span[1]) to
//li[#class='has-sub']/descendant::span[text()='First subnav']
and I never get timeout exceptions when waiting for subnav span to be visible now. So seems like it's always clicking on the nav span every time to open it up and give me no timeout when trying to get to the subnav. Anyone have any idea why that is?
Here is my python code as well:
inside LoadCommPage class:
def click_element(self, by, locator):
try:
WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located((by, locator)))
print "pressing element " + str(locator)
self.driver.find_element(by, locator).click()
except TimeoutException:
print "no clickable element in 10 sec"
print self.traceback.format_exc()
self.driver.close()
inside main test (load_comm_page is an instance of LoadCommPage, where click_clement is defined):
load_comm_page.click_element(*LoadCommPageLocators.sys_ops_tab)
And another class for the locators:
class LoadCommPageLocators(object):
firstnav_tab = (By.XPATH, "//li[#class='has-sub']/descendant::span[text()='First nav']")
Xpath indexes begin at one, not 0 so the Xpath
//span[1]
is looking for the first span element in the html. Whereas
//span[2]
will look for the second span.

Selecting an option from drop down that opens up on hover

Need help in selecting an option from a drop that opens up on hover, here is the html i'm currently looking at or you can just look into the attached image -
<ul id="yui_3_7_0_4_1390312781452_393" class="dropdown-menu">
<li id="yui_3_7_0_4_1390312781452_392" class="action" value="4001">
Promising
</li>
<li class="action" value="4003">
In Discussion
</li>
<li class="action" value="4004">
Phone screen
</li>
<li class="action" value="4005">
Interview
</li>
<li class="action" value="4006">
Offered
</li>
<li class="action" value="4007">
Hired
</li>
And here is the code i'm trying -
strings = driver.find_elements_by_class_name("action").text
for text in strings:
if text=='Offered':
text.click()
Using a CSS Selector, you could click it by doing:
driver.find_element_by_css_selector("ul.dropdown-menu[id^='yui'] li[value='4006']").click()
In order to achieve drop down menu selection mentioned in the question, you'll first have to mouse hover to drop down menu then hover mouse over element to select and the click on the element. Following is Java code, but the logic will help you to implement it in Python:
WebElement dropDownMenu = driver.findElement(By.id("yui_3_7_0_4_1390312781452_393"));
WebElement elementToSelect = driver.findElement(By.xpath(".//li[contains(text(), 'Offered')"));
Actions action = new Actions(driver);
action.moveToElement(dropDownMenu).moveToElement(elementToSelect).click().build().perform();
try this (ref:http://allselenium.info/mouse-over-actions-using-python-selenium-webdriver/)
from selenium.webdriver.common.action_chains import ActionChains
action = ActionChains(driver)
firstLevelMenu = driver.find_element_by_id("yui_3_7_0_4_1390312781452_393") #id of menu, or xpath of menu, whatever
action.move_to_element(firstLevelMenu).perform()
secondLevelMenu = driver.find_element_by_xpath("XPATH_OF_OFFERED")
action.move_to_element(secondLevelMenu).perform()
secondLevelMenu.click()

Categories

Resources