How to click on an li Element in Python - python-3.x

I was trying to automate a task in Python 3 using Selenium, where I need to click on a dropdown option. I was able to get the web element, but the click() function is not working on it.
driver.find_element_by_xpath("//li[#id='btnRemoveWorkflow']").click() throws an error
"selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable"
<ul class="dropdown-menu">
<li id="btnFillFromSignTemplate">...</li>
<li id="btnSaveAsSignTemplate">...</li>
<li id="btnManageSignTemplate">...</li>
<li class="divider"></li>...</li>
<li id="btnCancelWorkflow" class=" disabled " data-original-title="" title="">
<li class="divider"></li>
<li id="btnRemoveWorkflow" class="" data-original-title="" title="">...</li>
</ul>

Click the dropdown and wait for the element to be clickable

Try this:
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
ele = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, element)))
ele.click()
I think your element is hidden or overlayed.

Related

ElementNotInteractableException: Message: element not interactable: [object HTMLDivElement] has no size and location error using Selenium and Python

I am trying to click show results button after selecting filter on linkedin. I have correctly found the button element but it is giving me this error:
selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable: [object HTMLDivElement] has no size and location
Here is my piece of code that I have tried:
element = WebDriverWait(self, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR, 'div[class="artdeco-hoverable-content__shell"]')))
box = self.find_element_by_css_selector('div[class="artdeco-hoverable-content__shell"]')
ele = box.find_element_by_css_selector('button[data-control-name="filter_show_results"]')
ActionChains(self).move_to_element(ele).click(ele).perform()
I have also tried:
self.execute_script("arguments[0].click();", ele)
What's the reason behind this?
HTML of the results button:
<div class="reusable-search-filters-buttons display-flex justify-flex-end mt3 ph2">
<button data-test-reusables-filter-cancel-button="true" data-control-name="filter_pill_cancel" aria-label="Cancel Locations filter" id="ember429" class="artdeco-button artdeco-button--muted artdeco-button--2 artdeco-button--tertiary ember-view" type="button"><!---->
<span class="artdeco-button__text">
Cancel
</span></button>
<button data-test-reusables-filter-apply-button="true" data-control-name="filter_show_results" aria-label="Apply current filter to show results" id="ember430" class="artdeco-button artdeco-button--2 artdeco-button--primary ember-view ml2" type="button"><!---->
<span class="artdeco-button__text">
Show results
</span></button>
</div>
Edit 2: Here is the image of the button , I am trying to click.
https://ibb.co/4Y7VN0j
Edit 3: Image with dev tools open : https://ibb.co/CJdtNM1
The desired element is a Ember.js enabled element, so to click on the Show results button instead of presence_of_element_located() you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following locator strategies:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[data-control-name='filter_show_results'][aria-label='Apply current filter to show results'] span.artdeco-button__text"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[#data-control-name='filter_show_results' and #aria-label='Apply current filter to show results']//span[contains(., 'Show results')]"))).click()
Note: You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

python selenium selection option from dropdown

I need help to select the option "Last 7 days" from the following dropdown using python and selenium:
here is the html for part of the dropdown:
<div class="date-range" id="yui_3_18_1_1_1614002255126_175" style="margin-right: 25px;">
<div class="option-select global default" id="yui_3_18_1_1_1614002255126_174">
<div class="select-open" id="yui_3_18_1_1_1614002255126_173">
<div class="select-title" id="yui_3_18_1_1_1614002255126_172">
<span class="option-title">DATE RANGE:</span>
<span class="option-selection" id="yui_3_18_1_1_1614002255126_170">Last 30 days</span>
</div>
<div class="dropdown-arrow"></div>
</div>
<div class="select-body" id="yui_3_18_1_1_1614002255126_190">
<div class="option">
Today
<span class="extra-info-wrapper">
<span> (</span>
<span class="extra-info">22 Feb</span>
<span>)</span>
</span></div>
<div class="option">
Yesterday
<span class="extra-info-wrapper">
<span> (</span>
<span class="extra-info">21 Feb</span>
<span>)</span>
</span></div>
<div class="option">
This week
<span class="extra-info-wrapper">
<span> (</span>
<span class="extra-info">Monday - Today</span>
<span>)</span>
</span></div>
<div class="option" id="yui_3_18_1_1_1614002255126_189">
Last 7 days
<span class="extra-info-wrapper">
<span> (</span>
<span class="extra-info">16 Feb - Today</span>
<span>)</span>
</span></div>
<div class="option">
This month
<span class="extra-info-wrapper">
<span> (</span>
<span class="extra-info">1 Feb - Today</span>
<span>)</span>
</span></div>
My code so far is:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
PATH = "C:\Program Files (x86)\chromedriver.exe"
driver = webdriver.Chrome(PATH)
myUsername="Xxx”
myPassword="Xxx”
driver.get("https://uk.ixl.com/signin/sop")
driver.find_element_by_xpath('//*[#id="siusername"]').send_keys(myUsername)
driver.find_element_by_xpath('//*[#id="sipassword"]').send_keys(myPassword)
driver.find_element_by_xpath('//*[#id="custom-signin-button"]').click()
time.sleep(1)
#select report
driver.get("https://uk.ixl.com/analytics/students-quickview?teacherId=125756982")
time.sleep(5)
wait = WebDriverWait(driver, 10)
wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'date-range'))).click()
driver.find_element_by_id('yui_3_18_1_1_1614002255126_189').click()
I am getting the error:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate
element: {"method":"css selector","selector":"[id="yui_3_18_1_1_1614002255126_189"]"}
This is only my second python project so forgive any lack of understanding, this is just a hobby, but I've been stuck for 2 days trying all sorts but nothing works, any help would be appreciated (even links to videos that would help solve this so I can learn), thanks
You can hard code text in xpath like this:
wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'date-range'))).click()
wait.until(EC.element_to_be_clickable((By.XPATH, '//div[text()="Last 7 days"]'))).click()
Please change the text if you want other options.
What I usually do is:
driver.find_element_by_xpath(f'//select[#name="nameOfYourButton"]/option[text()=""TextToBeSelected"]').click()
Where nameOfYourButton and TextToBeSelected must be replaced with your specific variable
In particular, I can see that TextToBeSelected should be Last 7 days while from the HTML snippet that you are showing I can't see the name of the button.
Use WebDriverWait() and following xpath to click on Last 7 days.
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//div[#class='select-body']//div[#class='option' and contains(.,'Last 7 days')]"))).click()

How to extract the text content from multiple span elements using Selenium and Python

How to select text content from multiple DIV elements using selenium?
On the website I intend to collect information it contains div and span with the same class.
How can I collect this information separately?
I need the contents inside the panel-body div > span of each block
driver.find_element_by_xpath(".//div[#class='panel-body'][1]/span[1]").text
driver.find_element_by_xpath(".//div[#class='panel-body'][1]/span[2]").text
driver.find_element_by_xpath(".//div[#class='panel-body'][1]/span[3]").text
driver.find_element_by_xpath(".//div[#class='panel-body'][2]/span[1]").text
driver.find_element_by_xpath(".//div[#class='panel-body'][2]/span[2]").text
html
<div class="panel-heading">
<h3 class="panel-title">Identificação</h3>
</div>
<div class="panel-body">
<span class="spanValorVerde">TEXT</span><br>
<span style="font-size:small;color:gray">TEXT</span><br>
<br>
<span class="spanValorVerde">TEXT</span>
</div>
</div>
<div class="panel panel-success">
<div class="panel-heading">
<h3 class="panel-title">Situação Atual</h3>
</div>
<div class="panel-body">
<span class="spanValorVerde">TEXT</span> <br>
<span class="spanValorVerde">TEXT</span>
</div>
</div>
I am expecting that "select text" meant "get text".
first for loop:
count = driver.find_elements_by_xpath(".//div[#class='panel-body'][i]")
second for loop with count iteration:
driver.find_element_by_xpath(".//div[#class='panel-body'][i]/span[j]").text
If you search with findElements with ".//div[#class='panel-body'][i]" will give you the total element present, then add another loop for .//div[#class='panel-body'][i]/span[j] and then get text. Hope it helps!
To extract the texts e.g. TEXT, from each <span> using Selenium and python you have to induce WebDriverWait for visibility_of_all_elements_located() and you can use either of the following Locator Strategies:
Using CSS_SELECTOR and get_attribute("innerHTML"):
print([my_elem.get_attribute("innerHTML") for my_elem in WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, "div.panel.panel-success div.panel-body span.spanValorVerde")))])
Using XPATH and text attribute:
print([my_elem.text for my_elem in WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.XPATH, "//div[#class='panel panel-success']//div[#class='panel-body']//span[#class='spanValorVerde']")))])
Note : You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
Outro
Link to useful documentation:
get_attribute() method Gets the given attribute or property of the element.
text attribute returns The text of the element.
Difference between text and innerHTML using Selenium

Selenium selecting link within table - with all the same name

Cant click on the link due to the fact, all of the value I keep trying to select has the same name as well within the tables.
Tried xpath,by link, by text, by css none of it works. My current code:
driver.find_element_by_xpath('//[#id="homeapp"]/div/div/div[3]/div[1]/table/tbody/tr[3]/td[2]/div[1]/div[2]/span[1]/a').click()
Here is the relevant html code:
<tr class="bui-table__row"><td class="peg-table__cell--no-label bui-table__cell" data-heading="ID" scope="row"><a href="../../extranet_ng/manage/index.html?ses=8594ddf0718dec240a0c9e7991e108a8&name_id=11111" class="bui-link bui-link--secondary" target="_blank" data-track-ga="Groups: Home,Active Properties,Property ID">
1111(number i can click aswell)
</a></td> <td class="peg-table__cell--no-label bui-table__cell" data-heading="Name" scope="row"><div class="bui-avatar-block"><div class="peg-_-avatar-shrink bui-avatar"><img src="https://q-xx.bstatic.com/xdata/images/extra/square60/189090859.jpg?k=cc455d4d570f0e0c86a1b8329b16d53fdba96d78677cc87151d6181e45d38ec5&o=" alt="text i want to click" class="bui-avatar__image"></div> <div class="bui-avatar-block__text"><span class="bui-avatar-block__title"><a href="../../extranet_ng/manage/index.html?ses=8594ddf0718dec240a0c9e7991e108a8&name_id=11111" class="peg-property-link bui-link bui-link--secondary" target="_blank" data-track-ga="Groups: Home,Active Properties,Property Name">
Text i want to click
<!----> <!----></a></span> <span class="bui-avatar-block__subtitle"><!----> </span></div></div> <div class="bui-spacer--smaller"></div> <div class="peg-score-bar__inline bui-score-bar"><div class="bui-score-bar__item"><div class="bui-score-bar__header"><h2 class="bui-score-bar__title"></h2> <span class="bui-score-bar__score">93%</span></div> <div class="bui-score-bar__bar"><span data-value="9.3" class="bui-score-bar__value" style="width: 93%;"></span></div></div></div></td> <td class="peg-table__cell--no-label bui-table__cell" data-heading="Location"><div class="peg-address-wrapper"><span class="peg-flag-wrapper"><div class="peg-flag bui-flag"><img src="https://q.bstatic.com/backend_static/common/flags/16/nl/314ce6500532e846e25d6e3a7c824ef17c968446.png" class="bui-flag__flag" style="height: auto;"> <!----></div></span>
TEXT2
</div></td> <td class="peg-table__cell--no-label bui-table__cell" data-heading="Status"><span>Open/Bookable</span></td> <td class="bui-table__cell bui-table__cell--center" data-heading="Arrivals/departures & tomorrow"><span class="peg-counter--arrivals"><a href="../../extranet_ng/manage/search_reservations.html?ses=8594ddf0718dec240a0c9e7991e108a8&name_id=11111" data-track-ga="Groups: Home,Active Properties,Arrivals" target="_blank" class="peg-counter peg-counter--has"><span aria-label="80 unread" class="bui-bubble">
VALUE1
</span></a></span> <span class="peg-counter--departures"><a href="../../extranet_ng/manage/search_reservations.html?ses=8594ddf0718dec240a0c9e7991e108a8&name_id=11111&type=departure" data-track-ga="Groups: Home,Active Properties,Departures" target="_blank" class="peg-counter peg-counter--has"><span aria-label="80 unread" class="bui-bubble">
VALUE2
</span></a></span></td> <td class="bui-table__cell bui-table__cell--center" data-heading="Guest Messages"><a href="../../extranet_ng/manage/messaging_inbox.html?ses=8594ddf0718dec240a0c9e7991e108a8&name_id=11111" data-track-ga="Groups: Home,Active Properties,Guest Messages" target="_blank" class="peg-counter peg-counter--has"><span aria-label="102 unread" class="bui-bubble">
VALUE3
</span></a></td> <td class="bui-table__cell bui-table__cell--center" data-heading="extranet.com Messages"><a href="../../extranet_ng/manage/inbox.html?ses=8594ddf0718dec240a0c9e7991e108a8&name_id=11111" data-track-ga="Groups: Home,Active Properties,extrabnet.com Messages" target="_blank" class="peg-counter"><span aria-label="0 unread" class="bui-bubble">
0
</span></a></td></tr>
If you want to click the link which contains avatar in its class attribute use the following XPath expression:
//div[contains(#class,'avatar')]/descendant::a[contains(text(), 'text i want to click')]
where:
contains() is XPath Function allowing partial match on the attributes values and/or text
descendant - XPath Axis which matches children of the current node and their respective children
last part limits the search to hyperlinks which contain text you're looking for
The desired element is a ReactJS enabled element, so you have to induce WebDriverWait for the element to be clickable() and you can use either of the following solutions:
Using PARTIAL_LINK_TEXT:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.PARTIAL_LINK_TEXT, "text i want to click"))).click()
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a.peg-property-link.bui-link.bui-link--secondary[href*='/extranet_ng/manage/index'][data-track-ga*='Active Properties']"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[#class='peg-property-link bui-link bui-link--secondary' and contains(#href, '/extranet_ng/manage/index')][starts-with(#data-track-ga, 'Groups')]"))).click()
Note : You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

How to Click Link Being Covered by Another Element? Python 3.6 and Selenium

Having trouble figuring out how to click the Next button at the bottom of the table on this page:
https://www.zacks.com/stocks/industry-rank/reit-and-equity-trust-other-266/stocks-in-industry
This is what I've tried:
from bs4 import BeautifulSoup
import requests
import csv, random, time
from pandas.io.html import read_html
from selenium import webdriver
from selenium.webdriver.support.ui import Select
url = 'https://www.zacks.com/stocks/industry-rank/reit-and-equity-trust-other-266/stocks-in-industry'
# Open Chrome
driver = webdriver.Chrome()
# Send Chrome to the URL
page = driver.get(url)
# Wait for page to load a few seconds
timeDelay = random.randrange(4, 8)
time.sleep(timeDelay)
# Try to click the darn button
element = driver.find_element_by_xpath('//*[#id="industry_rank_table_next"]')
driver.execute_script("arguments[0].click();", element)
...and
element = driver.find_element_by_xpath('//*[#id="industry_rank_table_next"]')
element.send_keys("\n")
...found from other answers but not working for me. Simply using .click() does not work. I've also tried selecting the button using css_selector, partial_link_text, and class_name but still no success. I've ran into this on a few sites. Any ideas?
To click() on the element with text as Next you have to induce WebDriverWait for the element to be clickable and you can use either of the following solutions:
Using LINK_TEXT:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.LINK_TEXT, "Next"))).click()
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a.paginate_button next#industry_rank_table_next"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[#class='paginate_button next' and #id='industry_rank_table_next']"))).click()
Note : You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
if the element which you have to click have parent element then you can find parent by findElements method and after than you just need to pass the index of the element like 0 or 1 or so on.. and then you can perform click action on that
Want to click on third li from second ul:
<ul id="select-123" style="width: 1180px; display: none;">
<li class="" style="display:none;">
<li class="">
<li class="">
<li class="">
</ul>
<ul id="select-123" style="width: 1180px; display: none;">
<li class="" style="display:none;">
<li class="">
<li class="">
<li class="">
</ul>
Code I am trying is to select third li from second ul which does not work:
driver.findElements(By.css(ul[id*='select-123'])).then(function(elems) {
elems[2].then(function(lis) {
driver.findElement(By.css("ul[id*='select-123'] li:nth-child(3)")).click();
});
});
Another way if you don't wish to add additional wait(s) to your code and just click the button:
using javascript click:
element = driver.find_element_by_xpath("//a[#class='paginate_button next' and #id='industry_rank_table_next']")
driver.execute_script("arguments[0].click();", element)
UPDATE:
I didn't notice this earlier, but
element = driver.find_element_by_xpath('//*[#id="industry_rank_table_next"]')
driver.execute_script("arguments[0].click();", element)
...works as it clicks the link successfully, but gives me a
selenium.common.exceptions.WebDriverException: Message: unknown error: call function result missing 'value'
...error after it clicks the link. So to get around this, I've just added a try/except to handle the error. ie:
try:
element = driver.find_element_by_xpath('//*[#id="industry_rank_table_next"]')
driver.execute_script("arguments[0].click();", element)
except:
pass
...which seems to work. Seems like such a stupid observation on my part, but thank you to everyone for your help. Hopefully something in here will help someone else in the future.

Resources