Get text from a label using Selenium (Python) - python

I'm trying to read the text from a label that changes according to certain conditions (eg. if you enter a Username already in use, the label will display "Username already in use").
I've been trying to read in the text from the label that gets displayed, but nothing I've tried has worked so far.
The HTML looks like this:
<div class="margin-top-10">
<span ng-show="sentValidation">
<span id="test1" ng-show="userNameAvailable" class="txt-color-green">
<i class="fa fa-check fa-lg"></i>Username available
</span>
<span id="test2" ng-show="!userNameAvailable && userNameAvailable != null" class="txt-color-red">
<i class="fa fa-exclamation-circle"></i>Username unavailable
</span>
</span>
<div class="txt-color-red" ng-show="form.cUsername.$dirty && form.cUsername.$invalid">
<p id="test3" ng-show="form.cUsername.$error.required">
<i class="fa fa-exclamation-circle"></i>Username is required
</p>
<p id="test4" class="txt-color-red" ng-show="form.cUsername.$error.maxlength">
<i class="fa fa-exclamation-circle"></i>Maxmium length is 50 characters
</p>
<p id="test5" class="txt-color-red" ng-show="form.cUsername.$error.minlength">
<i class="fa fa-exclamation-circle"></i>Minimum length is 4 characters
</p>
</div>
</div>
Does anyone know how I can read what gets displayed on the screen?

content = driver.find_element_by_class_name('fa-exclamation-circle')
print (content.text)

I didn't manage to find a way to read the text, but I found another solution. Instead of checking what text is displayed on the screen, I check to see which of the labels is being displayed (I'm able to do this because each of the labels is given a unique ID.
So the code will look something like:
Name=driver.find_element_by_id('test2')
if Name.is_displayed():
print ("Element found")
else:
print ("Element not found")

content = driver.find_element_by_class_name('fa-exclamation-circle')
content.is_displayed()
You can use the find_element_by_class_name built in method.
You need to pass the class name as a parameter.

Related

Select dropdown in Selenium Python

I can't select values in a list. I tried using find_element_by_class_name() to open the menu but when I need to select a <li> returns that element doesn't have a function click().
Here the code:
click_menu = driver.find_element_by_class_name("periodSelector")
click_menu[1].click()
Here is the HTML that I am trying to parse:
<div data-period-selector="" data-period="periodFilter">
<div class="periodSelectorContainer">
<div class="btn-group periodSelector">
<button class="flat-btn dropdown-toggle periodToggle ng-binding" data-toggle="dropdown"> 20/02/2021 - 22/03/2021 <span class="dropdown-arrow"></span> </button>
<ul class="dropdown-menu">
<li>
<a href="javascript:void(0);" class="new-financ" ng-click="selectToday()"><i></i>
<span class="pull-left">Hoje</span>
<span class="pull-right"></span>
</a>
</li>
<li>
<a href="javascript:void(0);" class="new-financ" ng-click="selectThisWeek()"><i>
</li>
There are multiple class names you have to use a css selector.
click_menu = driver.find_element_by_css_selector("button.flat-btn.dropdown-toggle.periodToggle.ng-binding")
click_menu.click()
Clicks 1st li tag.
driver.find_element_by_xpath("ul[#class='dropdown-menu']/li[1]").click()
periodSelector is a class on a DIV
<div class="btn-group periodSelector">
I'm assuming that you need to click on the BUTTON
<button class="flat-btn dropdown-toggle periodToggle ng-binding" data-toggle="dropdown">
Most of those classes seem generic (probably not unique) but I'm guessing that periodToggle might be unique given the date range. Try
driver.find_element_by_css_selector("button.periodToggle").click()
NOTE:
You have an error in your code. You are using .find_element_by_class_name() (singular) but have array notation on the next line, click_menu[1]. In this case, you can just use click_menu.click(). You'd only need the array notation if you were using .find_elements_by_*() (note the plural, elements).

XPATH help - finding text, then the following button a few divs later

XPATH newbie... I am trying to find text, then find the following button in a code block like below.
The ember numbers change so can't use those. Need to find text within a span, then the next (following) button after that text is found. Then click on that button. In this case it's a contact button.
I've tried:
//*[text()[contains(.,'Jason')]]/div/div/button
Also tried:
//*[text()[contains(.,'Jason')]]/following-sibling::button
A code block example I am trying to search.
<div data-test="e-list-item" data-e-id="Fdh348uF" class="material-list-tile e-list-item">
<div class="e-name">
<a href="/embed/Gdfsdjfhd25d88/gallery/Fdh348uF" id="ember2539" class="ember-view"> <span data-test="e-name">Jason Alamoa</span>
</a><!----> </div>
<!----> <div id="ember2539" class="c-info ember-view"> <div class="c-icons">
<!---->
<!---->
<!---->
<!---->
</div>
</div>
<div class="e-actions">
<div class="e-action-buttons">
<!----> <div class="e-action">
<button class="ssButton ssButtonPrimary v-button v " type="button" data-ember-action="" data-ember-action-2540="2540">
<i class="ssIcon-ok-sign ssIcon-large"></i>
Contact
</button>
<!---->
</div>
</div>
</div>
</div>
Based on HTML snippet provided following XPath could be used:
//div[./a/span[contains(.,'Jason')]]/following::div[#class="e-actions"]//button
Explanation:
//div[./a/span[contains(.,'Jason')]] => selects "div" with child "a" containing child "span" containing text "Jason"
/following::div[#class="e-actions"] => selects following "div" after the first one having attribute "class" with value "e-actions"
//button => selects "button" inside of the previous "div"
If you want to find span with specific text and following button, the easiest way
//span[contains(text(), 'Jason')]/following::button

How can i get text from class using selenium

<div class="class-one">
<div class="class-two">
sample text
<div class="class-three">
<i class="fal fa-fw fa-file-word"></i><span class="button__title">search</span>
</div>
</div>
</div>
When i do driver.find_elements_by_css_selector('div.class-two') it prints sample text and search too, how can i get only sample text using selenium in python?
You need only write "text" in end.
driver.find_element_by_css_selector('div.class-two').text

How to click the 2nd text box with smae class name in selenium using python

I have recently started using selenium with python and stuck with the below problem. It may be simple but I have tried a lot while searching through different answers but could not solve it.
I want to click the 2nd text box with class name 'param-text-input text-input numeric-value'
<div class="bet-widget-main-row-right">
<div class="bet-widget-main-content">
<div class="bet-params">
<div class="param-wrapper">
<span class="param-label">Label1</span>
<div class="param-input -desktop">
<div class="param with-error">
<span class="param-input-wrapper">
<span class="param-currency numeric-value">£</span>
<input type="text" class="param-text-input text-input numeric-value" value=".04" tabindex="0" size="3" maxlength="11">
</span>
</div>
<div class="param-input_ticks"></div>
</div>
</div>
<div class="param-wrapper">
<span class="param-label">Label2</span>
<div class="param-input -desktop">
<div class="param">
<span class="param-input-wrapper">
<input type="text" class="param-text-input text-input numeric-value" value="2.18" tabindex="0" size="4" maxlength="8">
</span>
</div>
<div class="param-input_ticks"></div>
</div>
</div>
</div>
</div>
<div class="bet-submit"><button class="confirm-bet-button -accented micro-button" type="submit" disabled="" tabindex="0"><span>Button1</span></button></div></div>
I have tried multiple solutions but none work:
self.driver.find_element_by_xpath("//[#class='param-text-inp‌​ut.text-input.numeri‌​c-value'][2]").clear‌​()
self.driver.find_element_by_css_selector("[input.param-text-‌​input.text-input.num‌​eric-value][2]").cle‌​ar()
self.driver.find_element_by_xpath("//input[#class='param-tex‌​t-input'][2]").clear‌​()
Any pointers/help is appreciated.
In the case that you would prefer to use a CSS selector, the following will choose that second input:
div.param-wrapper:nth-of-type(2) input.param-text-input.text-input.numeric-value
we're looking for the second "param-wrapper" because that is the thing which will correctly count the parameters.
It's pretty easy:
self.driver.find_elements_by_xpath('//input[#Class="param-text-‌​input.text-input.num‌​eric-value"]')[1].clear()
or
from selenium.webdriver.common.keys import Keys
self.driver.find_elements_by_xpath('//input[#Class="param-text-‌​input.text-input.num‌​eric-value"]')[1].send_keys(Keys.BACKSPACE)
You need to make an object list in the first place. So you should find all the placeholders with the same name. Then get said item, which is the second element(list are zero based, so 1 is second)
Cheers
It is possible in XPath to select the n-th object that corresponds to your XPath expression.
To achieve this you use the [n] at the end of of your expression.
What you forgot is to put () around your expression before adding the [n].
So your XPath should be (//input[#class='param-tex‌​t-input'])[2].
To click the 2nd text box with class name 'param-text-input text-input numeric-value' you can use the following code block :
self.driver.find_element_by_xpath("//div[#class='bet-params']//following-sibling::input[2]").clear()

How to implement following-sibling axis of xpath alternative in Beautifulsoup Python

I'm trying to collect the text using Bs4, selenium and Python I want to get the text "Lisa Staprans" using:
name = str(profilePageSource.find(class_="hzi-font hzi-Man-Outline").div.get_text().encode("utf-8"))[2:-1]
Here is the code:
<div class="profile-about-right">
<div class="text-bold">
SF Peninsula Interior Design Firm
<br/>
Best of Houzz 2015
</div>
<br/>
<div class="page-tags" style="display:none">
page_type: pro_plus_profile
</div>
<div class="pro-info-horizontal-list text-m text-dt-s">
<div class="info-list-label">
<i class="hzi-font hzi-Ruler">
</i>
<div class="info-list-text">
<span class="hide" itemscope="" itemtype="http://data-vocabulary.org/Breadcr
umb">
<a href="http://www.houzz.com/professionals/c/Menlo-Park--CA" itemprop="url
">
<span itemprop="title">
Professionals
</span>
</a>
</span>
<span itemprop="child" itemscope="" itemtype="http://data-vocabulary.org/Bre
adcrumb">
<a href="http://www.houzz.com/professionals/interior-designer/c/Menlo-Park-
-CA" itemprop="url">
<span itemprop="title">
Interior Designers & Decorators
</span>
</a>
</span>
</div>
</div>
<div class="info-list-label">
<i class="hzi-font hzi-Man-Outline">
</i>
<div class="info-list-text">
<b>
Contact
</b>
: Lisa Staprans
</div>
</div>
</div>
</div>
Please let me know how it would be.
I assumed you are using Beautifulsoup since you are using class_ attribute dictionary-
If there is one div with class name hzi-font hzi-Man-Outline then try-
str(profilePageSource.find(class_="hzi-font hzi-Man-Outline").findNext('div').get_text().split(":")[-1]).strip()
Extracts 'Lisa Staprans'
Here findNext navigates to next div and extracts text.
I can't test it right now but I would do :
profilePageSource.find_element_by_class_name("info-list-text").get_attribute('innerHTML')
Then you will have to split the result considering the : (if it's always the case).
For more informations : https://selenium-python.readthedocs.org/en/latest/navigating.html
Maybe something is wrong with this part:
find(class_="hzi-font hzi-Man-Outline")
An easy way to get the right information can be: right click on the element you need in the page source by inspecting it with Google Chrome, copy the xpath of the element, and then use:
profilePageSource.find_element_by_xpath(<xpath copied from Chorme>).text
Hope it helps.

Categories