I'm trying to display text in what seems to be a container in web using selenium webdriver for python.
Here is the inspect element -
<div style="overflow-x: hidden;">
<div class="view-container" style="flex-direction: row;
transition: all 0s ease 0s; transform: translate(0%, 0px); direction: ltr;
display: flex; will-change: transform;">
<div aria-hidden="false" data-swipeable="true" style="width: 100%; flex-
shrink: 0; overflow: auto;">
<div>
<div class="qs-text">What is the answer to this question?</div>
I want it to display "What is the answer to this question"
I'm trying to use the below, but it doesn't return anything. -
element = driver.find_element_by_class_name("qs-text").text
print(element)
I tried find_element_by_css_selector("qs-text").text but that didn't help either.
Can you please tell me what I'm doing wrong
How about this:
element = driver.find_element_by_xpath("//*[contains(#class, 'qs-text') and contains(text(), 'answer')]")
print(element)
Related
I'm currently a student trying to learn how to make a bot. I've been successful by myself traversing through a website until I need to send keys to an iframe. I tried the following to get a NoSuchElementException.
#imports from the beginning
from selenium import webdriver as wd
from selenium.common.exceptions import NoSuchElementException
import chromedriver_binary
iframe = wd.find_element_by_xpath('//*[#id="card-number-container"]/iframe')
wd.switch_to.frame(iframe)
num = wd.find_element_by_xpath('//*[#id="card-number-container"]')
type(num)
num.send_keys("867-5309")
I tried switching to the iframe to interact with it. The error starts when defining num, but I have no idea what else to put to get there. Here's some of the HTML from the website.
<div id="card-number-container" class="_3lT_PetJ2w_rU8njR_SoIK _1ysVkT9CIcv98OnRX5h1Rj flex-microform">
<iframe hspace="0" vspace="0" frameborder="0" scrolling="no" allowtransparency="true" marginwidth="0" marginheight="0" src="https://flex.cybersource.com/cybersource/assets/microform/0.11.4/iframe.html?keyId=03eSdEAPS81iBTM0NCSfE2l3z43E8yw1#{"microformId":"cca792b9-2c83-422c-875b-bdb03b080eee","fieldId":"914ffbab-2597-40e3-9cd0-b5098cea829f","jwt":"eyJraWQiOiJ3ZiIsImFsZyI6IlJTMjU2In0.eyJmbHgiOnsicGF0aCI6Ii9mbGV4L3YyL3Rva2VucyIsImRhdGEiOiI5SGorT1h6Z3lWc2xIc0FxVjE3bEJSQUFFQjJZU1VaQzJjY0dLK0xFWndOVEtMRXhkTGVLS3NSZFRVQjZEODdGWEFTcHM2a3RPTWIwbUNiWTBDZUlOYVE5eTVJSEd4TVgzb2Ziby9keGZCZGVvaFhpRHl1V2tlQXRpZlFneXpXR21KaDUiLCJvcmlnaW4iOiJodHRwczovL2ZsZXguY3liZXJzb3VyY2UuY29tIiwiandrIjp7Imt0eSI6IlJTQSIsImUiOiJBUUFCIiwidXNlIjoiZW5jIiwibiI6ImlHbEJXdmlVVmlzTHpvZ0d1S0VNSDdjNVNtQVQxenYybXh0bExNU1k2a05XaUNQWW1RYW5BS2xRemp5MjN1NzlROG5SZk56aW50a3JWR1hhYk8ycndOQTRaYTBTdXp0ODVhU2steDdNSU9PSDVrQkRpeEJGWmc0dXQ2RDhZRHhHUW5uR25BZEZGZHF5Umx4VnhiZU53WUFxOHpxZFJ1UG9VckY0ZDYxZGFwejJ6ZFU1Z2QyZWFLZXEwQTdCTE9CdjhTbThLU1R6bDY3VndKNmJvX0VLM3FsUldBd3NiLXRSMFIzV0xZTFBDb2lVcThMeUNkVWpjSG84ckQtaGw1VzZ3ekkxR0x3S21RRVN3d0ZLdmZDSmwzTWs1TFQ0NU1WUmtHX1ViNlFBMkZwaDNKOXhGNkY2clNVM2Y0WnVFNlpEQnlIeXZGekVpdlJYMURjWVFxblpuUSIsImtpZCI6IjAzZVNkRUFQUzgxaUJUTTBOQ1NmRTJsM3o0M0U4eXcxIn19LCJjdHgiOlt7ImRhdGEiOnsidGFyZ2V0T3JpZ2lucyI6WyJodHRwczovL3d3dy5wb2tlbW9uY2VudGVyLmNvbSIsImh0dHBzOi8vdGVzdC5wb2tlbW9uY2VudGVyLmNvbSIsImh0dHA6Ly9sb2NhbGhvc3Q6MzAwMCJdLCJtZk9yaWdpbiI6Imh0dHBzOi8vZmxleC5jeWJlcnNvdXJjZS5jb20ifSwidHlwZSI6Im1mLTAuMTEuMCJ9XSwiaXNzIjoiRmxleCBBUEkiLCJleHAiOjE2MzQyNDg5OTIsImlhdCI6MTYzNDI0ODA5MiwianRpIjoiYWF6VWc3QThadXJXZG8yZyJ9.BsUePIvHdd5gkjdKMQ2iaBxyiakGWK9fe0bZNdaCheKfThTqG2HvsipskZ6ec42mira64uEFoCR43qGT7NIoGnGy-CmZ5pYWeuM8yzULD6pSPYhN42afQN08Mht9KjeKSL7W-NlTqT_a3KPadYsm2PIAACDj3hRhVWf0A0Avkd88EN0Yuch47KiVBVJb4QtVONcIVum0rIvr5msnj2zaJyC6WvHhiUu8UutOHqeoqHT3pxdcQNoW6xai6yQjK38yUAVcfKhZpcSnlC-be5FYK38eYSjlAp0XgFSAi6_nllsAs8oj9OoB-A57HpBRyNS0QFVLSt3bmoQky2HMr8gGGg","microformConfig":{"styles":{"input":{"font-size":"12px"},":disabled":{"cursor":"not-allowed"},"valid":{"color":"#43a047"},"invalid":{"color":"#d32f2f"}}},"config":{"placeholder":"Card Number..."},"fieldType":"number"}" style="overflow: hidden; position: relative; border: none; width: 100%; height: 100%;" cd_frame_id_="e0aaadb108c0aacce0bb0c878467c1c7"></iframe>
</div>
<div class="ui-dialog ui-widget ui-widget-content ui-corner-all ui-draggable" tabindex="-1" role="dialog" aria-labelledby="ui-dialog-title-imageModel" style="display: block; z-index: 1002; outline: 0px; height: auto; width: 700px; top: 225.5px; left: 278.5px;"><div class="ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix"><span class="ui-dialog-title" id="ui-dialog-title-imageModel">ATTENTION TAX PAYERS!!!!!</span><span class="ui-icon ui-icon-closethick">close</span></div><div id="imageModel" class="ui-dialog-content ui-widget-content" style="width: auto; min-height: 0px; height: 92.4px;" scrolltop="0" scrollleft="0">
<ul><li class="redFont"> Please insist on getting Form 16/16A from your Deductor downloaded only from Traces.Valid form 16/16A.<i><u> click here.</u></i></li></ul>
<div class="floatLeft margintop20"><input type="checkbox" id="Details" name="Details" onclick="checkModal('modalPagee')"> I agree to the usage and acceptance of Form 16 / 16A generated from TRACES</div>
<div class="floatLeft margintop20">
<input value="Proceed" type="button" class="button" id="btn" disabled="disabled" onclick="goCancel()">
</div>
</div></div>
This is the HTML code on which I am working, Here I want to select the input element of type checkbox, when I was trying it as
check_box = find_element_by_id("Details").click() I was failing to select it .
if need of more details in
"https://www.incometax.gov.in/iec/foportal" please visit this site,
when after login, goto -> e-file -> income_tax_returns -> view for 26as and continue, Then we will get another window opened and will get a popup here in pop up we need to select the checkbox.
That details is in new tab, you need to switch the focus like below :
wait = WebDriverWait(driver, 10)
new_handle = driver.window_handles
print(len(new_handle))
driver.switch_to.window(new_handle[1])
wait.until(EC.element_to_be_clickable((By.ID, "Details"))).click()
Try:
check_box = find_element_by_xpath('//*[#id="Details"]').click()
Using python and selenium to select an option in a combobox drop down ng select. I want to select the 'MALE' option in a dropdown select. I am trying to use XPath.
The code I use:
driver.find_element_by_id("sex_0").click()
driver.find_element_by_xpath("//*[contains(text(), 'MALE')]").click()
Copy and pasted the HTML:
Please Select OptionFEMALEMALE
Inspect element of the HTML:
<ng-select _ngcontent-uau-c14="" bindlabel="cdDescr" bindvalue="cd" class="custom ng-select ng-select-single ng-select-searchable ng-untouched ng-pristine ng-valid ng-select-opened ng-select-bottom" placeholder="Please Select Option" role="listbox" title="Please Select Option" id="sex_0">
<div class="ng-select-container">
<div class="ng-value-container"><div class="ng-placeholder">Please Select Option</div><!----><!---->
<div class="ng-input" style="top: 0px;"><input role="combobox" type="text" autocomplete="ac08684b8af8" autocorrect="off" autocapitalize="off" aria-expanded="true" style="position: relative; top: 0px; left: -10px; padding-left: 10px; border: none !important; height: 45px; width: 468px;" aria-owns="ac08684b8af8" aria-activedescendant="ac08684b8af8-0"></div></div><!----><!---->
<span class="ng-arrow-wrapper"><span class="ng-arrow"></span></span></div><!---->
<ng-dropdown-panel class="ng-dropdown-panel ng-select-bottom" id="ac08684b8af8" style="opacity: 1;"><!---->
<div class="ng-dropdown-panel-items scroll-host"><div></div>
<div><!----><!---->
<div class="ng-option ng-option-marked" role="option" aria-selected="false" id="ac08684b8af8-0"><!----><!----><span class="ng-option-label">FEMALE</span></div>
<div class="ng-option" role="option" aria-selected="false" id="ac08684b8af8-1"><!----><!----><span class="ng-option-label">MALE</span></div>
<!----><!----><!----><!----></div></div><!----></ng-dropdown-panel></ng-select>
The problem:
It will select FEMALE instead of MALE because the XPath text "FEMALE" contains the text "MALE". I assume that the 'id="ac08684b8af8"' is randomly generated with each use, which means I can't use Selenium find element by id. I tried select using selenium but I get the error: "element of type ng select not select". Hence I used XPath. The "ng-option-marked" is just a feature when the cursor hovers above the dropdown selection.
How should I solve this problem?
Answer is in the comments by KunduK.
driver.find_element_by_xpath("//*[text()='MALE']").click()
I have a web element with a tooltip that shows the following message:
● Client Book Revenue $20,966,618
The HTML code for that tooltip is below. I am able to hover over the web element using Selenium Webdriver which makes the tooltip visible, but I can't figure out how to get the text from it. Could somebody please help?
<div class="highcharts-tooltip" style="position: absolute; left: 755px; top: 0px; display: block; opacity: 1; pointer-events: none; visibility: visible;">
<span style="position: absolute; font-family: "Roboto",sans-serif; font-size: 12px; white-space: nowrap; color: rgb(51, 51, 51); margin-left: 0px; margin-top: 0px; left: 0px; top: 0px;">
<div class="client-rate-bench-chart">
<table class="table rdo-table-tooltip">
<tbody>
<tr>
<td>
<span style="color:rgba(45,108,162,1)">●</span>
Client Book Revenue
</td>
<td> $20,966,618 </td>
</tr>
</tbody>
</table>
</div>
</span>
</div>
You can grab the table and then grab the first instance of <tr>
from bs4 import BeautifulSoup
from selenium import webdriver
driver = webdriver.Firefox()
driver.get(URL)
html = driver.page_source # this is how you get the HTML
soup = BeautifulSoup(html)
table = soup.find('table', class_='rdo-table-tooltip')
tooltip = table.find('tr')
text = tooltip.text
text will have a lot of extra whitespace because of how the HTML is formatted, but you can strip that out - just split on all whitespace and then re-join the elements like this
final_text = ' '.join(text.split())
print final_text
# ● Client Book Revenue $20,966,618
For multiple <tr>s you can use .find_all('tr') and then use a list comprehension to get a list of the contents of the rows. It would look something like this
soup = BeautifulSoup(html)
table = soup.find('table', class_='rdo-table-tooltip')
tooltips = table.find_all('tr')
text = [' '.join(tooltip.text.split()) for tooltip in tooltips]
Then text will be a list of strings containing the text from each <tr>
As an alternative you could use re.findall to return all the instances of text between tags. This will involve some cleaning up afterwards but I have found it pretty handy in general when working with Selenium.
import re
tooltips = re.findall('<tr>(.*?)<tr>', html.replace('\n', ''))
for tooltip in tooltips:
print tooltip
<div class="j-C j-C-yj" style="max-height: none; -moz-user-select: none; visibility: visible; left: 218px; top: 105px; display: none;" role="menu" aria-haspopup="true">
<div id=":1r" class="j-qn" style="-moz-user-select: none;" role="separator"></div>
<div id=":1u" class="j-qn" style="-moz-user-select: none;" role="separator"></div>
</div>
so far i am creating xpath to select element with id=":1r" is
"(//div[contains(#class,'j-C') and contains(#class ,'j-C-yj')]/div)[1])"
i had also tried
"(//div[contains(#class,'j-C') and contains(#class ,'j-C-yj')]/div)[1])"
but none is working please help !
P.S : I cannot find element with id as id of the page is created dynamically
Just use xpath('.//div[contains(#class, "j-C") and contains(#class, "j-C-yj")]') as another answer already showed you.
Another Updates:
As OP kept changing the constraints of the question, here is the full solution does exactly what OP eants.
Sample: I'm using lxml to parse your string and do the xpath
from lxml import etree
s = '''<div class="j-C j-C-yj" style="max-height: none; -moz-user-select: none; visibility: visible; left: 218px; top: 105px; display: none;" role="menu" aria-haspopup="true">
...: <div id=":1r" class="j-qn" style="-moz-user-select: none;" role="separator"></div>
...: <div id=":1u" class="j-qn" style="-moz-user-select: none;" role="separator"></div>
...: </div>'''
# I need to wrap your string with <root> element otherwise first div will become the root
tree = etree.fromstring('<root>'+s+'</root>')
# xpath always returns a list, so just loop through the list and the first element is what you want
for node in tree.xpath('.//div[contains(#class, "j-C") and contains(#class, "j-C-yj")]'):
print etree.tostring(node[0])
<div id=":1r" class="j-qn" style="-moz-user-select: none;" role="separator"/>
Seems like there is a problem in your xpath towards the end. Try this piece of code:
driver.find_element_by_xpath("//div[contains(#class,'j-C') and contains(#class ,'j-C-yj')]/div[1]")