I have a submenu item that I used to be able to access via selenium web navigation. Now I keep getting the following error: "You may only interact with visible elements". I have tried a number of recommendations (waits, implicit/explicit, maximizing windows, using the ActionChain object) without success. Can anyone spot why this element would remain invisible by looking at the following HTML and code?:
<ul class="nav" >
<li>
EDC
</li>
</ul>
<ul class="nav" >
<li>
Queries
</li>
</ul>
<ul class="nav" >
<li>
Docs
</li>
</ul>
<ul class="nav" >
<li>
Data
</li>
</ul>
<ul class="nav" >
<li>
Audit Log
</li>
</ul>
<ul class="nav" >
<li>
Reports
</li>
</ul>
<ul class="nav" >
<li class="dropdown ">
Tools <b class="caret"></b>
<ul class="dropdown-menu">
<li>
SQL Worksheet
</li>
<li>
Meddra
</li>
<li>
SAE
</li>
<li>
Worksheets
</li>
<li>
Pipelines
</li>
<li>
Sync
</li>
<li>
Project Management
</li>
<li>
RSS
</li>
<li>
IPT
</li>
<li>
Images
</li>
</ul>
</li>
</ul>
And here is the python code snippet that is not working:
try:
menu_item = driver.find_element(By.LINK_TEXT, 'Tools')
actions = ActionChains(driver)
actions.click(menu_item).perform()
except Exception as error:
print ("Tools menu not found: " + str(error))
try:
wait = WebDriverWait(driver, 10) wait.until(EC.presence_of_element_located(By.XPATH("/html/body/header/div/div/div/div/ul[7]/li/ul/li[9]/a")));
ipt_menu_item = driver.find_element(By.XPATH, "/html/body/header/div/div/div/div/ul[7]/li/ul/li[9]/a")
actions.click(ipt_menu_item).perform()
except Exception as error:
print ("Tools | IPT link not found: " + str(error))
I have dealt with this same issue a few times, I have found that most the time you can move to the element first and then issue the .click() command:
Element = driver.find_element_by_link_text('link')
actions = ActionChains(driver)
# try this
actions.move_to_element(Element)
# or this
driver.execute_script("return arguments[0].scrollIntoView();", Element)
Element.click()
EDIT:
Or, a third option for click in case the top two do not work, if you can get the element with selenium and the element is in view, but just can't interact with it, then it's probably behind a <div that is not visible. Try this click instead of your normal .click():
driver.execute_script("arguments[0].click()", Element)
If that does not work, you may need to try interacting with the attributes to get the element in a state of visibility for selenium before you make the click, such as:
driver.execute_script("arguments[0].style.display = 'block'", Element)
Related
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()
I am attempting to toggle a button on an existing html file that is online. I change some of the names of the files to not give away the website I am working on. I know there is a way to do this if the dropdown-toggle has a title or id. However, for this html file there are only classes. Is there a way to click on the toggle button with an html file with this structure?
<li class="dropdown">
<b>Name</b><strong class="caret"></strong>
<ul class="dropdown-menu">
<li>
File1
</li>
<li>
File2s
</li>
<li>
File3
</li>
<li role="presentation" class="divider"></li>
<li>
Add
</li>
<li>
search
</li>
</ul>
</li>
Try this:
button = driver.findElement(By.cssSelector("a[class='dropdown-toggle']"))
# Or if it is not working.
button = driver.findElement(By.cssSelector("a[data-toggle='dropdown']"))
I think you are trying to select <a> with class name dropdown-toggle.
I'm trying to select the li element "US" in this dropdown list of the following website: https://proxyscrape.com/free-proxy-list
Here is the python code I have but does not work:
driver.find_element_by_xpath('/html/body/main/div/div[1]/div[3]/div/div[1]/div[2]').click()
time.sleep(4)
driver.find_element_by_css_selector("#list httpcountry countryselect [value='US']")
And here is the HTML I'm working with:
<div class="nice-select selectortypes open" tabindex="0">
<span>
Country: <span class="current">all</span>
</span>
<ul class="list httpcountry countryselect">
<li data-value="all" class="option">all</li>
<li data-value="US" class="option">US</li>
<li data-value="ES" class="option">ES</li>
<li data-value="RU" class="option">RU</li>
<li data-value="PL" class="option">PL</li>
<li data-value="BD" class="option">BD</li>
<li data-value="IR" class="option">IR</li>
<li data-value="FR" class="option">FR</li>
<li data-value="CN" class="option">CN</li>
<li data-value="CA" class="option">CA</li>
<li data-value="PK" class="option">PK</li>
<li data-value="IN" class="option">IN</li>
<li data-value="ID" class="option">ID</li>
<li data-value="BR" class="option">BR</li>
<li data-value="DE" class="option">DE</li>
<li data-value="GB" class="option">GB</li>
<li data-value="TH" class="option">TH</li>
<li data-value="SG" class="option">SG</li>
<li data-value="EG" class="option">EG</li>
<li data-value="UA" class="option">UA</li>
</ul>
</div>
Any clue on how to select this element?
Solution:
You need to wait before clicking on country dropdown list, because of top-banner appears and webdriver losts the focus, dropdown closes.
Here is the code which i wrote and script has passed after adding two sleeps in these two places:
driver.get('https://proxyscrape.com/free-proxy-list')
country_list = driver.find_element_by_css_selector('.list.socks4country.countryselect').find_element_by_xpath('./..')
sleep(2)
country_list.click()
sleep(1)
country_list.find_element_by_css_selector('[data-value="US"]').click()
us = driver.find_element_by_css_selector('[class="list socks4country countryselect"] [data-value="US"]')
assert us.get_attribute('class') == 'option selected'
If you look what happens when you select US option, then you can see, that it will change parameters in request here:
From:
Download
To:
Download
So, you actually don't want to click US option, but probably send request with appropriate parameters
I'm using selenium for automation and i want to click in each one of the <ul>elements then wait before clicking again in the element. This is my code but it doesn't seem to be the solution :
def navBar():
driver=setup()
navBar_List = driver.find_element_by_class_name("nav")
listItem = navBar_List.find_elements_by_tag_name("li")
for item in listItem :
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.TAG_NAME,"li")))
item.click()
Here the HTLM code :
<ul class="nav navbar-nav">
<li tabindex="0">
<a class="h">
<div class="icon-left-navbar">
...
</div>
</a>
</li>
<li tabindex="0">
<a class="h">
<div class="icon-left-navbar">
...
</div>
</a>
</li>
<li tabindex="0">
<a class="h">
<div class="icon-left-navbar">
...
</div>
</a>
</li>
</ul>
Is Thread.sleep(100) an option?
Define your li with .find_elements.
Use xpath for recognize them : //ul[#class='nav navbar-nav']//li.
With loop you can utilize increment to wait each li. I'm imagine it will produce like below:
(xpath)[1]
(xpath)[2]
etc...
And try the following code:
listItem = WebDriverWait(driver, 30).until(EC.visibility_of_all_elements_located((By.XPATH,"//ul[#class='nav navbar-nav']//li")))
for x in range(1, len(listItem)+1):
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"(//ul[#class='nav navbar-nav']//li)[" +str(x) +"]"))).click()
I'm trying to click on the button "Advanced Search" but everything I've tried - referencing by class / xpath etc results in "Element not visible"
Special Situations Research
</li>
<li id="tGX" style="z-index:997">Governance Exchange</li>
<li id="tVM" style="z-index:996">Voting Data
<ul>
<li> Companies</li>
<li> Proposals</li>
<li> Institutions</li>
<li> Search</li>
<li> Shareholder Resolution Filings</li>
</ul></li>
<li id="tSCAS" style="z-index:995">RecoverMax<!-- Commented Recovermax menus in Link 1.40 Release to include RecoerMax Dashboard changes
<ul>
<li>Dashboard</li>
<li>New Cases</li>
<li>Tentative Settlements</li>
<li>Pending Settlements</li>
<li>International Litigations</li>
<li>Not Yet Disbursed</li>
<li>Disbursements</li>
<li>Claim Tracking</li>
<li>Quick Search</li>
<li>Advanced Search</li>
<li>Watchlists</li>
<li>Alerts</li>
<li>Preferences</li>
<li>% Decline Claim Identification</li>
<li>Eligibility Search</li>
<li>HelpDesk</li></ul>--></li>
<li id="tECA" style="z-index:994"><a class="navLink unentitled" title="ExecComp Analytics" onclick="updateBreadCrumbNew('tECA','/cda/index.php')">ExecComp Analytics</a>
<ul>
<li>Executive Pay Benchmarking</li>
<li>Equity Plan Benchmarking</li>
<li>Pay for Performance</li>
Would be grateful for help!