I have an input tag html element that Selenium Python fails to identify (not because of the wait). So on a web page with a form (name is Form1), I want to extract the text in one of the fields. This is the html element here when I inspect the elements on chrome:
Input Element:
<input name="txtSerialNo" type="text" readonly="readonly" id="txtSerialNo" class="tbFormRO" style="width:160px;position:absolute;left:90px;top:7px;text-align:center;">
The full xpath is this when I right-click on the element to copy the xpath: /html/body/form/div[9]/input[1]
The HTML Element
There isn't any text on it, so I tried the below and all did not work. I also tried the implicit wait and WebDriverWait. They are irrelevant and did not work.
driver.maximize_window()
driver.find_element_by_xpath('/html/body/form/div[9]/input[1]')
driver.find_element_by_id('txtSerialNo')
driver.find_element_by_name("txtSerialNo")
driver.find_element_by_xpath("//input[#id='txtSerialNo']")
It all returns error:
NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"[id="txtSerialNo"]"}
(Session info: chrome=91.0.4472.114)
My question is: I can see that when I inspect the element, the text I want to retrieve is in the Property tab, under input#txtSerialNo.tbFormRO
Under Property
I am using a for loop to gather all input element, but I don't know how to extract that "value" property under the "category" of input#txtSerialNo.tbFormRO in the property tab when I inspect the element. Sorry I don't have a solid CSS/HTML knowledge.
The Text I Want to Extract
I tried the below without success:
for inp in driver.find_elements_by_xpath('//form[#name="Form1"]//input'):
for k in inp.get_property('attributes')[0].keys():
print(inp.get_attribute(k))
for inp in driver.find_elements_by_xpath('//form[#name="Form1"]//input'):
print(inp.value_of_css_property('value'))
# get_property(input#txtSerialNo.tbFormRO.text)
# .get_attribute('text')
# .get_attribute("innerHTML")
# .get_attribute('value')
# .get_property('input#txtSerialNo.tbFormRO.value')
I think you are looking for .get_attribute(). Based on the image lets adjust the xpath to '//input[#name="txtSerialNo"]'
for inp in driver.find_elements_by_xpath('//input[#name="txtSerialNo"]'):
print(inp.get_attribute('value'))
Related
Trying to scrape a website, I created a loop and was able to locate all the elements. My problem is, that the next button id changes on every page. So I can not use the id as a locator.
This is the next button on page 1:
<a rel="nofollow" id="f_c7" href="#" class="nextLink jasty-link"></a>
And this is the next button on page 2:
<a rel="nofollow" id="f_c9" href="#" class="nextLink jasty-link"></a>
Idea:
next_button = browser.find_elements_by_class_name("nextLink jasty-link")
next_button.click
I get this error message:
Message: no such element: Unable to locate element
The problem here might be that there are two next buttons on the page.
So I tried to create a list but the list is empty.
next_buttons = browser.find_elements_by_class_name("nextLink jasty-link")
print(next_buttons)
Any idea on how to solve my problem? Would really appreciate it.
This is the website:
https://fazarchiv.faz.net/faz-portal/faz-archiv?q=Kryptow%C3%A4hrungen&source=&max=10&sort=&offset=0&_ts=1657629187558#hitlist
There are two issues in my opinion:
Depending from where you try to access the site there is a cookie banner that will get the click, so you may have to accept it first:
browser.find_element_by_class_name('cb-enable').click()
To locate a single element, one of the both next buttons, it doeas not matter, use browser.find_element() instead of browser.find_elements().
Selecting your element by multiple class names use xpath:
next_button = browser.find_element(By.XPATH, '//a[contains(#class, "nextLink jasty-link")]')
or css selectors:
next_button = browser.find_element(By.CSS_SELECTOR, '.nextLink.jasty-link')
Note: To avoid DeprecationWarning: find_element_by_* commands are deprecated. Please use find_element() import in addition from selenium.webdriver.common.by import By
You can't get elements by multiple class names. So, you can use find_elements_by_css_selector instead.
next_buttons = browser.find_elements_by_css_selector(".nextLink.jasty-link")
print(next_buttons)
You can then loop through the list and click the buttons:
next_buttons = browser.find_elements_by_css_selector(".nextLink.jasty-link")
for button in next_buttons:
button.click()
Try below xPath
//a[contains(#class, 'step jasty-link')]/following-sibling::a
Situation
I'm using Selenium and Python to extract info from a page
Here is the div I want to extract from:
I want to extract the "Registre-se" and the "Login" text.
My code
from selenium import webdriver
url = 'https://www.bet365.com/#/AVR/B146/R^1'
driver = webdriver.Chrome()
driver.get(url.format(q=''))
elements = driver.find_elements_by_class_name('hm-MainHeaderRHSLoggedOutNarrow_Join ')
for e in elements:
print(e.text)
elements = driver.find_elements_by_class_name('hm-MainHeaderRHSLoggedOutNarrow_Login ')
for e in elements:
print(e.text)
Problem
My code don't send any output.
HTML
<div class="hm-MainHeaderRHSLoggedOutNarrow_Join ">Registre-se</div>
<div class="hm-MainHeaderRHSLoggedOutNarrow_Login " style="">Login</div>
By looking this HTML
<div class="hm-MainHeaderRHSLoggedOutNarrow_Join ">Registre-se</div>
<div class="hm-MainHeaderRHSLoggedOutNarrow_Login " style="">Login</div>
and your code, which looks okay to me, except that part you are using find_elements for a single web element.
and by reading this comment
The class name "hm-MainHeaderRHSLoggedOutMed_Login " only appear in
the inspect of the website, but not in the page source. What it's
supposed to do now?
It is clear that the element is in either iframe or shadow root.
Cause page_source does not look for iframe.
Please check if it is in iframe, then you'd have to switch to iframe first and then you can use the code that you have.
switch it like this :
driver.switch_to.frame(driver.find_element_by_xpath('xpath here'))
So I'm trying to find this <ul> tag I found using inspect element on chrome:
<ul class = "jobs-search-results__list artdeco-list" itemtype="http://schema.org/ItemList"></ul>
This is what I tried in Python:
ul = driver.find_element_by_class_name("jobs-search-results__list artdeco-list")
Which should return the <ul> tag.
Instead I get this error:
selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element:{"method":"class","selector":"jobs-search-results__list artdeco-list"}
I get the same error whether I use a tag/xpath/absolutepath selector.
Then I find out this element is not on the HTML page source, and so selenium can't find it.
HTML Source (pastebin)
How do I go about finding this element if its not on the page source?
The class of ul element that you are trying to get is changing while accessing site using Selenium. For this use the xpath as
//ul[contains(#class,'jobs-search__results')]
Now you can find ul element as
ul = driver.find_element_by_xpath("//ul[contains(#class,'jobs-search__results')]")
I am trying to access the text of multiple tags using selenium in python.
The tags do not have attribute like id or class; they have an attribute named itemprop.
For instance there are multiple tags of such type:
<p itemprop="articleBody">
London's Gatwick Airport ........</p>
I can't use "select element by tag name" because there are tag "p" with different attributes which I don't want to include.
I am using the below code to select these elements:
elements = driver.find_element(By.CSS_SELECTOR, """p[itemprop='articleBody’]""")
However it throws the error - ......
NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"p[itemprop='articleBody’]"}
How can I fix this?
you have smart quote ’ in the selector, use find_elements* with s to get multiple elements.
elements = driver.find_elements(By.CSS_SELECTOR, 'p[itemprop="articleBody"]')
# Or
elements = driver.find_elements_by_css_selector('p[itemprop="articleBody"]')
I'm pretty new to using python in selenium.
I have been trying to select a button on my web page. Here is the piece of HTML that appears after inspecting the element of the button:
<a class="btn col-xs-3 nav-btns" ui-sref="salt.dashboard.reports.minions" href="/dashboard/reports/minions/">
<span class="ssIcons-icon_reports salt-icon-3x ng-scope active" bs-tooltip="" data-title="Reports" container="body" placement="bottom" animation="none" data-trigger="hover" ng-class="{'active': state.current.name =='salt.dashboard.reports' … || state.current.name =='salt.dashboard.reports.minions'}">
::before
</span>
</a>
I have tried everything I can think of. Here are some of the things that I have tried:
element = driver.find_element_by_class_name("btncol-xs-3")
element = driver.find_element_by_name("Reports")
element = driver.find_element_by_id("Reports")
the error that I keep getting is:
selenium.common.exceptions.NoSuchElementException: Message: Unable to
locate element: {"method":"class
name","selector":"salt.dashboard.reports"} Stacktrace:
at FirefoxDriver.prototype.findElementInternal_ (file:///tmp/tmpoRPJXA/extensions/fxdriver#googlecode.com/components/driver-component.js:10299)
at FirefoxDriver.prototype.findElement (file:///tmp/tmpoRPJXA/extensions/fxdriver#googlecode.com/components/driver-component.js:10308)
at DelayedCommand.prototype.executeInternal_/h (file:///tmp/tmpoRPJXA/extensions/fxdriver#googlecode.com/components/command-processor.js:12282)
at DelayedCommand.prototype.executeInternal_ (file:///tmp/tmpoRPJXA/extensions/fxdriver#googlecode.com/components/command-processor.js:12287)
at DelayedCommand.prototype.execute/< (file:///tmp/tmpoRPJXA/extensions/fxdriver#googlecode.com/components/command-processor.js:12229)
root#chris-salt:/home/chris/Documents/projects/python-selenium#
Find the element by data-title:
driver.find_element_by_css_selector("span[data-title=Reports]")
Or, if you need to get to the a tag:
driver.find_element_by_xpath("//a[span/#data-title = 'Reports']")
Chris,
The span that you pasted doesn't has an attribute named id.
Also, your class selector is too wide, i'd suggest using a more explicit path following the dom structure. Bare in mind that there may be multiple elements that have that class name.
Also, you are trying to find by the attribute name, which you don't have in that element.
Finally, it seems that you might be using angular. Does the input that you are looking for is created with javascript dinamically ?
And also, why are you using root to do this tests ?
Before doing the asserts, can you store the resulting html and manually checking that you indeed have that element?.