Return UID attribute value using Selenium Python - python

I have a site that looks like this and I want to extract the contents of the uid field using firefox + selenium + python. There is only 1 UID per page.
<div class= "parent" >
<div class="module profile" dcp="1" uid="90">
...
...
</div>
</div>
To make it concrete see the following:
<div class= "parent" >
<div class="module profile" dcp="1" uid="[RETURN THIS]">
...
...
</div>
</div>
I've tried several techniques in selenium including using
browser.find_elements_by_name
browser.find_elements_by_xpath
browser.find_elements_by_class_name
browser.find_elements_by_css_selector
But none of them are able to return the UID. I either get an empty set or I only get the class (i.e. the entire module class rather than the attributes inside the DIV).
I saw some folks recommend the get_attribute selector but I was unsuccessful in applying it to this use case.
Any guidance would be appreciated, thanks.

To extract the value of the attribute uid i.e. the text 90 you can use either of the Locator Strategies:
css_selector:
myText = browser.find_element_by_css_selector("div.parent>div.module.profile").get_attribute("uid")
xpath:
myText = browser.find_element_by_xpath("//div[#class='parent']/div[#class='module profile']").get_attribute("uid")
However it seems the attribute uid i.e. the text 90 is a dynamic element so you have to induce WebDriverWait for the element to be visible and you can use either of the following solutions:
css_selector:
myText = WebDriverWait(browser, 20).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div.parent>div.module.profile"))).get_attribute("uid")
xpath:
myText = WebDriverWait(browser, 20).until(EC.visibility_of_element_located((By.XPATH, "//div[#class='parent']/div[#class='module profile']"))).get_attribute("uid")
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

Related

Selenium XPATH looking for a keyword inside of a Href that is inside of a class

I am struggling to click the first href that matches a keyword. There is at least 2 hrefs that match a keyword im using so selenium fails at clicking the element. I have tried to nominate the class and look inside that class for the Href but the syntax is incorrect. I currently have this code in a try block as it refreshes if the href is not found and tries again.
see below:
<div class="productitem--info">
<span class="productitem--vendor">
GlenWyvis</span>
<h2 class="productitem--title">
<a href="/collections/new-whisky-arrivals/products/glenwyvis-batch-20-18-2018-vintage-2nd-release" data-product-page-link="">
GlenWyvis Batch 02/18 | 2nd Release
</a>
</h2>
The Python try block I have is below:
while True:
try:
element = driver.find_element(By.XPATH, "//*[#class='productitem--title'] and contains(.#href, 'glenwyvis')]")
element.click()
break
except NoSuchElementException:
driver.refresh()
time.sleep(3)
Any help is greatly appreciated.
Many thanks.
With minimal modifications, you could use
element = driver.find_element(By.XPATH, "//*[#class='productitem--title' and contains(a/#href, 'glenwyvis')]")
This returns the <h2> element with the desired properties.
As per the HTML:
<h2 class="productitem--title">
<a href="/collections/new-whisky-arrivals/products/glenwyvis-batch-20-18-2018-vintage-2nd-release" data-product-page-link="">
GlenWyvis Batch 02/18 | 2nd Release
</a>
</h2>
To click on the element with href starting with /collections/new-whisky-arrivals/products/glenwyvis-batch 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, "h2.productitem--title > a[href^='/collections/new-whisky-arrivals/products/glenwyvis-batch']"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//h2[#class='productitem--title']/a[starts-with(#href, '/collections/new-whisky-arrivals/products/glenwyvis-batch')]"))).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

Selenium Click button whitout id

i have to click the input type="button" element of the first li, but i can not refer to the id of the li, since it changes every time i i open the website, this is what i tried
driver.find_elements_by_xpath('//input[data-componentname="gender"]').get(0).click()
and it gives me this error:
AttributeError: 'list' object has no attribute 'get'
if i remove the get part, this is the error:
AttributeError: 'list' object has no attribute 'click'
This is the code, like i said, i have to click the first input without referring to the id
<ul data-componentname="gender">
<li id="78ece221-1b64-4124-8483-80168f21805f" class="">
<input type="button">
<span>Uomo</span>
</li>
<li id="2678a655-b610-41e0-8e7f-bad58fbcb1b3" class="">
<input type="button">
<span>Donna</span>
</li>
</ul>
To click on the element Uomo 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, "ul[data-componentname='gender'] li:nth-of-type(1) span"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//ul[#data-componentname='gender']//span[text()='Uomo']"))).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
Browser Snapshot:
find_elements method return a list of web elements.
The first member of the list can be received by simple indexation i.e. list_object[0]
Also, since you want to get the first element matching the //input[data-componentname="gender"] locator you can simply use find_element method.
So, instead of
driver.find_elements_by_xpath('//input[data-componentname="gender"]').get(0).click()
You can use
driver.find_element_by_xpath('//input[data-componentname="gender"]').click()
Or
driver.find_elements_by_xpath('//input[data-componentname="gender"]')[0].click()
UPD
well, you tried to use a wrong locator.
This should work:
driver.find_element_by_xpath("//ul[#data-componentname='gender' ]//span[text()='Uomo']/../input").click()
You can also click the element containing the "Uomo" text itself as well
driver.find_element_by_xpath("//ul[#data-componentname='gender' ]//span[text()='Uomo']").click()
You can include the first li if you only want that. For example:
driver.find_element_by_xpath('//input[data-componentname="gender"]/li[1]')
otherwise if you want the list then you can do
driver.find_elements_by_css_selector('input[data-componentname="gender"] > li')
and do the .get() according to which button you want to click

AttributeError: 'list' object has no attribute 'click' error clicking on an element using Selenium and Python

I need help this is my script:
# Imports
from selenium import webdriver
url = "https://sjc.cloudsigma.com/ui/4.0/login"
d = webdriver.Chrome()
d.get(url)
escolhe = d.find_elements_by_xpath('//*[#id="trynow"]')
escolhe.click()
and this is what the html looks like:
<button id="trynow" class="btn g-recaptcha block full-width m-b dwse btn-warning" ng-class="{'btn-danger': instantAccess=='Error', 'btn-success': instantAccess=='Success', 'btn-warning': instantAccess=='Working', 'btn-warning': (instantAccess!='Working' && instantAccess!='Success' && instantAccess!='Error')}" data-ng-disabled="instantAccess=='Working' || instantAccess=='Success' || instantAccess=='Error'" analytics-on="click" analytics-event="Guest logged in" analytics-category="Guest logged in" analytics-label="Guest logged in" data-sitekey="6Lcf-2MUAAAAAKG8gJ-MTkwwwVw1XGshqh8mRq25" data-callback="onTryNow" data-size="invisible">
<span name="btn-warning" class="default " style="font-size: 20px;">
<i class="fa fa-thumbs-up"></i> Instant access
<p style="font-size: 9px;font-style: italic;margin: 2px 0px;" class="ng-binding">No credit card is required</p>
</span>
<span name="btn-warning" class="working hide" disabled=""><i class="fa fa-spinner fa-spin"></i> Instant access...</span> <span name="btn-success" class="success hide" disabled=""><i class="fa fa-spinner fa-spin"></i> Entrar na sessão</span> <span name="btn-danger" class="error hide" disabled=""><i class="fa fa-exclamation-circle"></i> Erro</span>
</button>
I need help because whenever I put xpath this error:
AttributeError: 'list' object has no attribute 'click'
Find element not elements.
from selenium import webdriver
import time
url = "https://sjc.cloudsigma.com/ui/4.0/login"
d = webdriver.Chrome(executable_path='C:/bin/chromedriver.exe')
d.get(url)
time.sleep(5) #Wait a little for page to load.
escolhe = d.find_element_by_xpath('//*[#id="trynow"]/span[1]')
escolhe.click()
You have to write element not elements --> Even if there is only one item it will treat it as a list. You have to modify like this:
from selenium import webdriver
url = "https://sjc.cloudsigma.com/ui/4.0/login"
d = webdriver.Chrome()
d.get(url)
escolhe = d.find_element_by_xpath('//*[#id="trynow"]')
escolhe.click()
This error message...
AttributeError: 'list' object has no attribute 'click'
...implies that you have tried to invoke click() method on a list element where as click() is invoked on a WebElement.
Solution
To click on the desired element you can use either of the following Locator Strategies:
Using css_selector:
driver.find_element_by_css_selector("button#trynow").click()
Using xpath:
driver.find_element_by_xpath("//button[#id='trynow']").click()
Ideally, to click on the element you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:
Using CSS_SELECTOR:
driver.get('https://sjc.cloudsigma.com/ui/4.0/login')
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button#trynow"))).click()
Using XPATH:
driver.get('https://sjc.cloudsigma.com/ui/4.0/login')
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[#id='trynow']"))).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
Your code returns a list of webelements. Webelements can be clicked on. You either need to select one webelement of the list by index, such as:
escolhe = d.find_elements_by_xpath('//*[#id="trynow"]')
escolhe[0].click() #first element
or use find_element_by_xpath to return the first element that matches your xpath locator:
escolhe = d.find_element_by_xpath('//*[#id="trynow"]')
escolhe.click()
I'd also suggest using find_element_by_id if you're using an id locator strategy:
escolhe = d.find_element_by_id('trynow')
escolhe.click()

How to get text outside the div?

<div class="amlocator-store-information" style="" xpath="1">
<div class="amlocator-title" style="">The Better Health Store</div>
2420 E-Stadium Ann Arbor MI 48104
<br><br>
(613) 975-6613
<div style="" class="amasty_distance" id="amasty_distance_1">Distance:
<span class="amasty_distance_number"></span>
</div>
</div>
I am using selenium with python and trying to get the address from the DOM but I can't,
I have used
store_block_list = '//div[#class="amlocator-store-information"]'
store_block_list = '//div[#class="amlocator-title"]'
to capture the elements but cant get the address out as you can see the address is outside the //div element
Please note it is a list of elements and I then use for loop to loop around the element list
To extract the address i.e. 2420 E-Stadium Ann Arbor MI 48104 as it is a Text Node you need to induce WebDriverWait for the visibility_of_element_located() using execute_script() method and you can use either of the following Locator Strategies:
Using CSS_SELECTOR:
print(driver.execute_script('return arguments[0].childNodes[2].textContent;', WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div.amlocator-store-information")))).strip())
Using XPATH:
print(driver.execute_script('return arguments[0].childNodes[2].textContent;', WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//div[#class='amlocator-store-information']")))).strip())
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 locate the element and extract the innerText using Selenium and Python

<span class="chr-UserDropdownItem-imageAndText">
<img class="chr-UserDropdownItem-image" src="/slm/profile/image/264023573852/24.sp?version=1" alt="User Profile Avatar">
<span class="smb-DropdownItem-text">
<span> test user </span>
</span>
</span>
By taking look on above screenshot please help me extract the innerText test user uniquely from span tag.
To extract the text test user you have to induce WebDriverWait for the visibility_of_element_located() and you can use either of the following Locator Strategies:
Using CSS_SELECTOR and get_attribute():
print(WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "span.smb-DropdownItem-text>span"))).get_attribute("innerHTML"))
Using XPATH and text attribute:
print(WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "span[#class='smb-DropdownItem-text']>span"))).text)
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
You can find the element using the xpath:
driver.find_element_by_xpath("//span[#class='smb-DropdownItem-text']//span[contains(text(),'test user')]");
You can give it try with below xpath.
//img[contains(#src, '/profile/image/')]]/following-sibling::span
You can use XPath like this for remove white-space:
driver.find_element_by_xpath('//span/text()[normalize-space()="test user"]')
If you don't have white-space in the span tag, use XPath this way:
driver.find_element_by_xpath('//span[contains(text(), "test user")]')
For Dynamically:
driver.find_element_by_xpath('//span[contains(text(), "' . $HereIsSetYourDynamicallyVaribleName . '")]')

Categories