Python Splinter clicking button CSS - python

I'm having trouble selecting a button in my Splinter script using the find_by_css method. The documentation is sparse at best, and I haven't found a lot of good articles out there with examples.
br.find_by_css('div#edit-field-download-files-und-0 a.button.launcher').first.click()
...where br is my browser instance.
I've tried a few different ways of writing it. I'm really not sure how I'm supposed to do it because the documentation doesn't give any hard examples of the syntax.
Here's a screenshot of the element.
Sorry the screenshot kind of sucks.
Does anyone have any experience with this?

The css selector looks alright, just that i am not sure from where have you got find_by_css as a method?
How about this :-
br.find_element_by_css_selector("div#edit-field-download-files-und-0 a.button.launcher").click()
Selenium provides the following methods to locate elements in a page:
find_element_by_id
find_element_by_name
find_element_by_xpath
find_element_by_link_text
find_element_by_partial_link_text
find_element_by_tag_name
find_element_by_class_name
find_element_by_css_selector
To find multiple elements (these methods will return a list):
find_elements_by_name
find_elements_by_xpath
find_elements_by_link_text
find_elements_by_partial_link_text
find_elements_by_tag_name
find_elements_by_class_name
find_elements_by_css_selector

I'm working on something similar where I'm trying to click stuff on a webpage. The documentation for find_by_css() is very poor and you need to type the css path to the element you want to click.
Say we want to go to the about tab on python.org
from splinter import Browser
from time import sleep
with Browser() as browser: #<--Create browser instance (firefox default driver)
browser.visit('http://www.python.org') #<--Visits url string
browser.find_by_css('#about > a').click()
# ^--Put css path here in quotes
sleep(5)
If your connection is good you might not get the chance to see the about tab getting clicked but you should end up on the about page.
The hard part is figuring out the css path to an element. However once you have it, the find_by_css() method looks pretty easy

I like the W3Schools reference for CSS selection parameters: http://www.w3schools.com/cssref/css_selectors.asp
As for your code... I recommend breaking this down into a few steps, at least during debug. The call to br.find_by_css('css_string') returns a list of elements. So you can grab that list and check the count.
elems = br.find_by_css('div#edit-field-download-files-und-0 a.button.launcher')
if len(elems) == 1:
elems.first.click()
If you don't check the length of the returned list and call '.first' on an empty list, you'll get an exception. If len > 1, you're probably getting things you don't expect.
Each id on a page is unique, and you can daisy-chain searches, so you can use a few different statements to make this happen:
id_elems = br.find_by_id('edit-field-download-files-und-0')
if id_elems:
id_elem = id_elems.first
a_elems = id_elem.find_by_tag("a")
for e in a_elems:
if e.has_class("button launcher"):
print('Found it!')
e.click()
This is, of course, just one of many ways to do this.
Lastly, Splinter is a wrapper around Selenium and other webdrivers. It's possible that, even after you find the element to click, the actual click won't do anything. If this happens, you can also try clicking on the wrapped Selenium object, available as e._element. So you could try e._element.click() if necessary.

Related

I found a span on a website that is not visible and I can't scrape it! Why?

Currently I'm trying to scrape data from a website. Therefore I'm using Selenium.
Everything is working as it should. Until I realised I have to scrape a tooltiptext.
I found already different threads on stackoverflow that are providing an answer. Anyway I did not manage to solve this issue so far.
After a few hours of frustration I realised the following:
This span has nothing to do with the tooltip I guess. Because the tooltip looks like this:
There is actually a span that I can't read. I try to read it like this:
bewertung = driver.find_elements_by_xpath('//span[#class="a-icon-alt"]')
for item in bewertung:
print(item.text)
So Selenium finds this element. But unfortunatly '.text' returns nothing. Why is it always empty ?
And what for is the span from the first screenshot ? Btw. it is not displayed at the Website as well.
Since you've mentioned Selenium finds this element, I would assume you must have print the len of bewertung list
something like
print(len(bewertung))
if this list has some element in it, you could probably use innerText
bewertung = driver.find_elements_by_xpath('//span[#class="a-icon-alt"]')
for item in bewertung:
print(item.get_attribute("innerText"))
Note that, you are using find_elements which won't throw any error instead if it does not find the element it will return an empty list.
so if you use find_element instead, it would throw the exact error.
Also, I think you've xpath for the span (Which does not appear in UI, sometime they don't appear until some actions are triggered.)
You can try to use this xpath instead:
//i[#data-hook='average-stars-rating-anywhere']//span[#data-hook='acr-average-stars-rating-text']
Something like this in code:
bewertung = driver.find_elements_by_xpath("//i[#data-hook='average-stars-rating-anywhere']//span[#data-hook='acr-average-stars-rating-text']")
for item in bewertung:
print(item.text)

Looping through webelements with selenium Python

I am currently trying to automate a process using Selenium with python, but I have hit a roadblock with it. The list is part of a list which is under a tree. I have identified the base of the tree with the following xpath
item = driver.find_element_by_xpath("//*[#id='filter']/ul/li[1]//ul//li")
items = item.find_elements_by_tag_name("li")
I am trying to Loop through the "items" section but need and click on anything with an "input" tag
for k in items:
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((k.find_element(By.TAG_NAME, "input")))).click()
When execute the above I get the following error:
"TypeError: find_element() argument after * must be an iterable, not WebElement"
For some reason .click() will not work if I use something like the below.
k.find_element_by_tag_name("input").click()
it only works if i use the webdriverwait. I have had to use the web driver wait method anytime i needed to click something on the page.
My question is:
What is the syntax to replicate items = item.find_elements_by_tag_name("li")
for WebDriverWait(driver, 10).until(EC.element_to_be_clickable((k.find_element(By.TAG_NAME, "input")))).click()
i.e how do I use a base path and append to the using the private methods find_elements(By.TAG_NAME)
Thanks in advance
I have managed to find a work around and get Selenium to do what i need.
I had to call the javascript execution, so instead of trying to get
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((k.find_element(By.TAG_NAME, "input")))).click() to work, i just used
driver.execute_script("arguments[0].click();", k.find_element_by_tag_name("input"))
Its doing exactly what I needed it to do.

Python - Salesforce: How to find an object with no definitive class name and verify the text?

So, currently I'm using Python 3 and the selenium webdriver with Salesforce to automate admin verifications.
I've been pretty successful (even though I'm not that proficient with programming). However, I've run into an issue... I can't seem to figure out how to find an element on the page so that I can verify the text contained within is accurately being displayed.
This is what it looks like on the user's end:
The highlighted element displays as this
But whenever I search for "GlobalHeaderCommunitySwitcher", it spits back an error that it can't find it.
So I try searching for the other elements in the block of code:
<b class="zen-selectArrow"></b>PVT GBI Internal
<b class="zen-selectArrow"></b>
"PVT GBI Internal"
I've come up empty each time by searching by:
browser.find_element_by_id("globalHeaderCommunitySwitcher")
browser.find_element_by_class_name & used "zen-trigger" and "zen-selectArrow"
browser.find_element_by_xpath("//div[#class='zen-trigger'and text()='PVT GBI Internal']")
This also results in nothing being returned..
Essentially, how do I locate the element in the screenshot via the above code and then have the script verify that the text within that element ("PVT GBI INTERNAL") is present and correct?
you can use //tag[text()="value"] or //tag[contains(attribute,‘value’)]
example : browser.find_element_by_xpath("//a[#class='zen-trigger']//*[‌​text()='PVT GBI Internal']")
//a[#class='zen-trigger']//*[contains(text(),'PVT GBI Internal')]
//a[#class='zen-trigger']//*[contains(#class="zen-selectArrow")and
contains(text(),'PVT GBI Internal')]
Open the page using the google chrome browser
Move the mouse over the element that you want to find and right-click it
Left click Inspect (at the bottom of the selection list)
Your element will be hi-lighted in the Developers tools
Right click the hi-lighted element and select Copy
Click either copy Selector or XPath depending on your preference
Paste that into your selenium find_element_by_xpath() or find_element_by_css_selector() statement as appropriate.
Say xpath
element = browser.find_element_by_xpath("your pasted xpath")
assert element.text == 'Your expected text'

Selenium CSS_Selector looking for an element with specific text is turning out a 'NoSuchElementException'

I'm having an issue with looking for an element with a particular text attribute utilizing CSS_Selectors in Selenium. Here is the current line of code I have:
element = driver.find_element(By.CSS_SELECTOR, "li.adTypeItem[text='CLASS']")
I've had trouble using the attribute selector brackets in CSS_Selectors in the past, and clearing this up would really go a long way to better understanding how to use CSS_Selectors in the future.
Please note - i'm not looking for a element with a class, but rather the actual text that is displayed with that element.
Is this the only place on the page with the text "class" displayed? If so you can try:
driver.find_element(By.LINK_TEXT('CLASS'));
driver.find_element(By.PARTIAL_LINK_TEXT('CLASS'));

how to use Selenium to click something

I have two simple questions relevant to Selenium. Actually I am new to this framework.
The questions are raised for:
HERE ARE CHINESE CHARACTERS
and
HERE ARE ANOTHER CHINESE CHARACTERS
How can I use selenium to click each anchor?
Please note that the first has the keyword "title", I know I may use it for match, but no idea how to realize it. I don't plan to use the CHARACTERS presented there, because it varies depending on different projects.
And the second, in this case, the CHINESE CHARACTERS are fixed. Due to there is no other clue, I think I will have to only use it for detection and issue a click event by Selenium.
Please advise, thanks.
You have multiple ways to find both links. Which option to choose depends on the locations of the links on the page, uniqueness of element attributes, text etc.
That said, there are two relevant methods that should be tried first:
find_element_by_link_text()
find_element_by_partial_link_text()
Here is how you should use them:
first_link = driver.find_element_by_link_text(u'HERE ARE CHINESE CHARACTERS')
first_link.click()
second_link = driver.find_element_by_link_text(u'HERE ARE ANOTHER CHINESE CHARACTERS')
second_link.click()
where driver is a Webdriver instance, e.g.:
from selenium import webdriver
driver = webdriver.Firefox()
If you cannot rely on the link texts, then check title and onclick attributes and use one of the following methods:
find_element_by_xpath()
find_element_by_css_selector()
Example (using the first method of two):
first_link = driver.find_element_by_xpath('//a[#title="title_text"]')
first_link.click()
second_link = driver.find_element_by_xpath('//a[#onclick="anotherjsfunc();"]')
second_link.click()
You can use cssSelector in both cases.
css for first a tag should look like
[title='title_text']
and 2nd a tag
[onclick='anotherjsfunc();']

Categories

Resources