Selenium find element and click on it - python

I'm trying to get Selenium to click on View All Companies button, but i'm not sure what am I doing wrong. It returns no element found
html code
<div class="screener-toggles">
<div class="buttons">
<span class="button selected" data-name="advanced-screener">Search by Screener<span data-name="advanced-screener" class="arrow selected"></span></span>
<span class="button" data-name="alpha-factors">Search by Alpha Factors<span data-name="alpha-factors" class="arrow"></span></span>
<span class="button" data-name="all-companies">View All Companies<span data-name="all-companies" class="arrow"></span></span>
</div>
</div>
python code I wrote
element1 = driver.find_elements_by_class_name('View All Companies')
element1.click()
# I have tried all-companies instead of View All Companies as well. But still doesn't work
Should I not be using find_elements_by_class_name?
Any advice on what I am doing wrong is greatly appreciated!

try xpath: "//span[contains(text(),'View All Companies')]"

View All Companies is text, not the class. Try looking by text with css_selector or xpath
element1 = find_element_by_css_selector('span:contains("View All Companies")')
element1 = find_element_by_xpath('//span[contains(text(), "View All Companies")]')
Or by the data-name attribute which contains all-companies
element1 = find_element_by_css_selector('span[data-name*="all-companies"]')

Yes, you should not use the find_elements_by_class_name instead of use find_element_by_class_name.
find_elements_by_class_name is used when your expecting your locator to return more than 1 element. for a specific element use only find_element_by_class_name.
Another thing is I am not able to see any class name as View All Companies in your HTML code. Please look into your HTML and select classname or other locator carefully
Hope it will help you

Related

Selenium starts-with searchs entire page not in given Webelement

I want to search class name with starts-with in specific Webelement but it search in entire page. I do not know what is wrong.
This returns list
muidatagrid_rows = driver.find_elements(by=By.CLASS_NAME, value='MuiDataGrid-row')
one_row = muidatagrid_rows[0]
This HTML piece in WebElement (one_row)
<div class="market-watcher-title_os_button_container__4-yG+">
<div class="market-watcher-title_tags_container__F37og"></div>
<div>
<a href="#" target="blank" rel="noreferrer" data-testid="ios download button for 1628080370">
<img class="apple-badge-icon-image"></a>
</div>
<div></div>
</div>
If a search with full class name like this:
tags_and_marketplace_section = one_row.find_element(by=By.CLASS_NAME, value="market-watcher-title_os_button_container__4-yG+")
It gives error:
selenium.common.exceptions.InvalidSelectorException: Message: Given css selector expression ".market-watcher-title_os_button_container__4-yG+" is invalid: InvalidSelectorError: Element.querySelector: '.market-watcher-title_os_button_container__4-yG+' is not a valid selector: ".market-watcher-title_os_button_container__4-yG+"
So i want to search with starts-with method but i can not get what i want.
This should returns only two Webelements but it returns 20
tags_and_marketplace_section = one_row.find_element(by=By.XPATH, value='//div[starts-with(#class, "market-watcher-")]')
print(len(tags_and_marketplace_section))
>>> 20
Without seeing the codebase you are scraping from it's difficult to help fully, however what I've found is that "Chaining" values can help to narrow down the returned results. Also, using the "By.CSS_SELECTOR" method works best for me.
For example, if what you want is inside a div and p, then you would do something like this;
driver.find_elements(by=By.CSS_SELECTOR, value="div #MuiDataGrid-row p")
Then you can work with the elements that are returned as you described. You maybe able to use other methods/selectors but this is my favourite route so far.

Finding/locating a clickable text by xpath in div/span format

I used the following line to click the Availability Grid button, but it failed to locate the element.
Class Sarsa-button-content is used everywhere so, I added text together to make it unique. However, it couldn't find it. What am I missing?
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//a[#class='sarsa-button-content']/span[text()='Availability Grid']"))).click()
<div class="sticky-top-wrapper" style="top: 80px;">
<div class="site-filter-container" id="site-filter-container">
<a data-component="Button" class="sarsa-button view-by-availability-grid--button-tracker sarsa-button-primary sarsa-button-sm" href="/site/123456/availability">
<span class="sarsa-button-inner-wrapper">
<span class="sarsa-button-content">Availability Grid</span>
your xpath is wrong, try this:
//span[contains(#class, 'sarsa-button-content') and text() = 'Availability Grid']

How to identify an element using webdriver in python for http link

How to identify the link, I have inspected the elements which are as below :
<div class="vmKOT" role="navigation">
<a class="Ml68il" href="https://www.google.com" aria-label="Search" data-track-as="Welcome Header Search"></a>
<a class="WaidDw" href="https://mail.google.com" aria-label="Mail" data-track-as="Welcome Header Mail"></a>
<a class="a4KP9d" href="https://maps.google.com" aria-label="Maps" data-track-as="Welcome Header Maps"></a>
<a class="QJOPee" href="https://www.youtube.com" aria-label="YouTube" data-track-as="Welcome Header YouTube"></a>
</div>
I want to identify the class WaidDw or href and click it using python.
You can try
driver.find_element_by_class_name('WaidDw').click()
or
driver.find_element_by_xpath('//a[#href="https://mail.google.com" and #aria-label="Mail"]').click()
In your provided HTML all attribute's values are unique, you can locate easily that element by using their attribute value.
As your question points to locate this <a class="WaidDw" href="https://mail.google.com" aria-label="Mail" data-track-as="Welcome Header Mail"></a> element. I'm providing you multiple cssSelectors which can work easily to identify the same element as below :-
a.WaidDw
a.WaidDw[href='https://mail.google.com']
a.WaidDw[aria-label='Mail']
a.WaidDw[data-track-as='Welcome Header Mail']
a.WaidDw[href='https://mail.google.com'][aria-label='Mail']
a.WaidDw[href='https://mail.google.com'][aria-label='Mail'][data-track-as='Welcome Header Mail']
Note :- Keep in practice (priority) to use cssSelector instead xpath if possible, because cssSelectors perform far better than xpath
Locating Element by CSS Selectors using python :-
element = driver.find_element_by_css_selector('use any one of the given above css selector')
Clicks the element :-
element.click()
Reference link :-
https://www.w3schools.com/cssref/css_selectors.asp
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors

Python 3.5 + Selenium Scrape. Is there anyway to select <a><a/> tags?

So I'm very new to python and selenium. I'm writting an scraper to take some balances and download a txt file. So far I've managed to grab the account balances but downloading the txt files have proven to be a difficult task.
This is a sample of the html
<td>
<div id="expoDato_msdd" class="dd noImprimible" style="width: 135px">
<div id="expoDato_title123" class="ddTitle">
<span id="expoDato_arrow" class="arrow" style="background-position: 0pt 0pt"></span>
<span id="expoDato_titletext" class="textTitle">Exportar Datos</span>
</div>
<div id="expoDato_child" class="ddChild" style="width: 133px; z-index: 50">
<a class="enabled" href="/CCOLEmpresasCartolaHistoricaWEB/exportarDatos.do;jsessionid=9817239879882871987129837882222R?tipoExportacion=txt">txt</a>
<a class="enabled" href="/CCOLEmpresasCartolaHistoricaWEB/exportarDatos.do;jsessionid=9817239879882871987129837882222R?tipoExportacion=pdf">PDF</a>
<a class="enabled" href="/CCOLEmpresasCartolaHistoricaWEB/exportarDatos.do;jsessionid=9817239879882871987129837882222R?tipoExportacion=excel">Excel</a>
<a class="modal" href="#info_formatos">InformaciĆ³n Formatos</a>
</div>
</div>
I need to click on the fisrt "a" class=enabled. But i just can't manage to get there by xpath, class or whatever really. Here is the last thing i tried.
#Descarga de Archivos
ddmenu2 = driver.find_element_by_id("expoDato_child")
ddmenu2.find_element_by_css_selector("txt").click()
This is more of the stuff i've already tryed
#TXT = driver.select
#TXT.send_keys(Keys.RETURN)
#ddmenu2 = driver.find_element_by_xpath("/html/body/div[1]/div[1]/div/div/form/table/tbody/tr[2]/td/div[2]/table/tbody/tr/td[4]/div/div[2]")
#Descarga = ddmenu2.find_element_by_visible_text("txt")
#Descarga.send_keys(Keys.RETURN)
Please i would apreciate your help.
Ps:English is not my native language, so i'm sorry for any confusion.
EDIT:
This was the approach that worked, I'll try your other suggetions to make a more neat code. Also it will only work if the mouse pointer is over the browser windows, it doesn't matter where.
ddmenu2a = driver.find_element_by_xpath("/html/body/div[1]/div[1]/div/div/form/table/tbody/tr[2]/td/div[2]/table/tbody/tr/td[4]/div/div[1]").click()
ddmenu2b = driver.find_element_by_xpath("/html/body/div[1]/div[1]/div/div/form/table/tbody/tr[2]/td/div[2]/table/tbody/tr/td[4]/div/div[2]")
ddmenu2c = driver.find_element_by_xpath("/html/body/div[1]/div[1]/div/div/form/table/tbody/tr[2]/td/div[2]/table/tbody/tr/td[4]/div/div[2]/a[1]").click()
Pretty much brute force, but im getting to like python scripting.
Or simply use CSS to match on the href:
driver.find_element_by_css_selector("div#expoDato_child a.enabled[href*='txt']")
You can get all anchor elements like this:
a_list = driver.find_elements_by_tag_name('a')
this will return a list of elements. you can click on each element:
for a in a_list:
a.click()
driver.back()
or try xpath for each anchor element:
a1 = driver.find_element_by_xpath('//a[#class="enabled"][1]')
a2 = driver.find_element_by_xpath('//a[#class="enabled"][2]')
a3 = driver.find_element_by_xpath('//a[#class="enabled"][3]')
Please let me know if this was helpful
you can directly reach the elements by xpath via text:
driver.find_element_by_xpath("//*[#id='expoDato_child' and contains(., 'txt')]").click()
driver.find_element_by_xpath("//*[#id='expoDato_child' and contains(., 'PDF')]").click()
...
If there is a public link for the page in question that would be helpful.
However, generally, I can think of two methods for this:
If you can discover the direct link you can extract the link text and use pythons' urllib and download the file directly.
or
Use use Seleniums' click function and have it click on the link in the page.
A quick search resulted thusly:
downloading-file-using-selenium

Click the link, if we have only class name

How can I click the link:
<a class="single_like_button btn3-wrap" onclick="openFbLWin_189932();">
<span> </span><div class="btn3">Share</div>
</a>
This is my code in Python, but it doesn't work. I use Selenium
......
elem = self.driver.find_elements_by_class_name("single_like_button btn3-wrap")[0].click();
......
find_elements_by_class_name() is apparently limited to a single class name.
You can use find_element_by_css_selector() instead and write:
self.driver.find_element_by_css_selector(
".single_like_button.btn3-wrap").click();

Categories