How to send keys to this element - python

I am using Python selenium chrome driver and i am stuck at filling out the csc and the year of the creditcard information field ( look at picture ). The credit card number and month works fine with this code:
iframe = driver.find_element_by_xpath("//iframe[#class='js-iframe']")
driver.switch_to.frame(iframe)
inputCC = WebDriverWait(driver, 30).until(
lambda driver: driver.find_element_by_id("encryptedCardNumber")
)
inputCC.send_keys("1111222233334444")
driver.switch_to.default_content()
time.sleep(1)
iframe = driver.find_element_by_xpath("//iframe[#class='js-iframe']")
driver.switch_to.frame(iframe)
inputCC = WebDriverWait(driver, 30).until(
lambda driver: driver.find_element_by_id("encryptedExpiryMonth")
)
inputCC.send_keys("08")
driver.switch_to.default_content()
I tried to use the same for the csc and year with changing the id but it didnt work.
How to do it?

I don't run your code, but I checked the HTML & your code. Here's what I think:
Because //iframe[#class='js-iframe'] is a very general XPATH, you need to be more specific. In your site, you have many iframes with the same XPATH.
You can fill the Month because after calling iframe = driver.find_element_by_xpath("//iframe[#class='js-iframe']"), it gives you the FIRST iframe, which contains the Month.
Your code fails for Year/CSC because it uses the FIRST iframe (which contains Month) to locate Year & CSC.
To fix, you have 2 methods.
Write the correct XPATH.
Month iframe: //span[#data-cse="encryptedExpiryMonth"]/iframe
Year iframe: //span[#data-cse="encryptedExpiryYear"]/iframe
CSC iframe: //span[#data-cse="encryptedSecurityCode"]/iframe
Find a list of iframes
iframe_list = driver.find_elements_by_xpath("//iframe[#class='js-iframe']")
month_iframe = iframe_list[0]
year_iframe = iframe_list[1]
csc_iframe = iframe_list[2]

Related

Instagram Following Selenium Python

I am trying to figure out how to get Selenium to click the following section of an Instagram account, here is the html for it.
<a class=" _81NM2" href="/peacocktv/following/" tabindex="0"><span class="g47SY lOXF2">219</span> following</a>
When using instagram, the direct /username/following link does not actually bring up the following list, you would have to click the field manually on the website for it to appear.
log_in = WebDriverWait(driver, 8).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[type = 'submit']"))).click()
not_now = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//button[contains(text(), "Not Now")]')))
not_now.click()
'''not_now2 = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//button[contains(text(), "Not Now")]')))
not_now2.click()'''
search_select = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//input[#placeholder = 'Search']")))
search_select.clear()
'''search_select.send_keys("russwest44", Keys.ENTER)
search_select.send_keys(Keys.ENTER)'''
# Clicks who the person is following:
following = driver.find_elements_by_xpath("//button[contains(text(),'following')]")
following.click()
Which is the best way to come up with the solution
Seems like couple of issues with your current code:
# Clicks who the person is following:
following = driver.find_elements_by_xpath("//button[contains(text(),'following')]")
following.click()
if you pay attention, you've shared HTML with a tag, so your xpath should be
//a[contains(text(),'following')]
not
//button[contains(text(),'following')]
also, you are using find_elements_by_xpath it would return a list of web elements. you can not directly trigger .click on it.
either switch to find_element or
following[0].click()

Selenium cant locate element inside ::before ::after

Element to be located
I am trying to locate a span element inside a webpage, I have tried by XPath but its raise timeout error, I want to locate title span element inside Facebook marketplace product. url
here is my code :
def title_detector():
title = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, 'path'))).text
list_data = title.split("ISBN", 1)
Try this xpath //span[contains(text(),'isbn')]
You can't locate pseudo elements with XPath, only with CSS selector.
I see it's FaceBook with it's ugly class names...
I'm not sure this will work for you, maybe these class names are dynamic, but it worked for me this time.
Anyway, the css_locator for that span element is .dati1w0a.qt6c0cv9.hv4rvrfc.discj3wi .d2edcug0.hpfvmrgz.qv66sw1b.c1et5uql.lr9zc1uh.a8c37x1j.keod5gw0.nxhoafnm.aigsh9s9.qg6bub1s.fe6kdd0r.mau55g9w.c8b282yb.iv3no6db.o0t2es00.f530mmz5.hnhda86s.oo9gr5id
So, since we are trying to get it's before we can do it with the following JavaScript script:
span_locator = `.dati1w0a.qt6c0cv9.hv4rvrfc.discj3wi .d2edcug0.hpfvmrgz.qv66sw1b.c1et5uql.lr9zc1uh.a8c37x1j.keod5gw0.nxhoafnm.aigsh9s9.qg6bub1s.fe6kdd0r.mau55g9w.c8b282yb.iv3no6db.o0t2es00.f530mmz5.hnhda86s.oo9gr5id`
script = "return window.getComputedStyle(document.querySelector('{}'),':before').getPropertyValue('content')".format(span_locator)
print(driver.execute_script(script).strip())
In case the css selector above not working since the class names are dynamic there - try to locate that span with some stable css_locator, it is possible. Just have to try it several times until you see which class names are stable and which are not.
UPD:
You don't need to locate the pseudo elements there, will be enough to catch that span itself. So, it will be enough something like this:
span_locator = `.dati1w0a.qt6c0cv9.hv4rvrfc.discj3wi .d2edcug0.hpfvmrgz.qv66sw1b.c1et5uql.lr9zc1uh.a8c37x1j.keod5gw0.nxhoafnm.aigsh9s9.qg6bub1s.fe6kdd0r.mau55g9w.c8b282yb.iv3no6db.o0t2es00.f530mmz5.hnhda86s.oo9gr5id`
def title_detector():
title = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CSS_SELECTOR, 'span_locator'))).text
title = title.strip()
list_data = title.split("ISBN", 1)

How to get div text by id with selenium

I am trying to get a book's description text from its amazon webpage. I get the book's image and title and price fine by using driver.find_element_by_id, but when it comes to the description which is in a div with id="iframeContent", it doesn't work. Why? I have also tried WebDriverWait but no luck.
I use the following code:
def get_product_description(self, url):
"""Returns the product description of the Amazon URL."""
self.driver.get(url)
try:
product_desc = self.driver.find_element_by_id("iframeContent")
except:
pass
if product_desc is None:
product_desc = "Not available"
return product_desc
Since that element is inside the iframe you have to switch to that iframe in order to access elements inside the iframe.
So first you have to locate the iframe
iframe = driver.find_element_by_id("bookDesc_iframe")
then switch to it with
driver.switch_to.frame(iframe)
Now you can access the element located by the div#iframeContent css_selector
And finally you should get out from the iframe to the default content with
driver.switch_to.default_content()
Credits to the author
you need to use text method from selenium.
try:
product_desc = self.driver.find_element_by_id("iframeContent").text
print(product_desc)
except:
pass
Update 1:
There's a iframe involved so you need to change the focus of webdriver to iframe first
iframe = self.driver.find_element_by_id("bookDesc_iframe")
self.driver.switch_to.frame(iframe)
product_desc = self.driver.find_element_by_id("iframeContent").text
print(product_desc)
Now you can access every element which is inside bookDesc_iframe iframe, but the elements which are outside this frame you need to set the webdriver focus to default first, something like this below :
self.driver.switch_to.default_content()

Selenium calendar picker: I can click manually but Selenium cant click

I am attempting to choose date on a calendar on this website. On the first calendar (date from) I can choose the desired date using Selenium, however, I get the following error while clicking on the desired month even though the exact element is found.
ElementNotInteractableException:element not interactable
To me, it seems weird because I can click on the month manually.
Here is what I have tried so far
from selenium import webdriver
import time
year = 2019
month = 'JAN'
driver_path = 'pathtochromedriver\chromedriver.exe'
url = 'https://app.cpcbccr.com/ccr/#/caaqm-dashboard-all/caaqm-landing/data'
driver = webdriver.Chrome(driver_path)
driver.get(url)
time.sleep(8)
# find desired calendar
to_date = driver.find_element_by_xpath('//*[#id="date2"]/angular2-date-picker/div/div[1]/i')
to_date.click()
# Click on year dropdown
to_year = driver.find_element_by_xpath('//*[#id="date2"]/angular2-date-picker/div/div[2]/div[3]/div')
to_year.click()
driver.find_element_by_xpath('//*[#id="{}"]'.format(year)).click()
# Click on month dropdown
to_month = driver.find_element_by_xpath('//*[#id="date2"]/angular2-date-picker/div/div[2]/div[2]/div')
to_month.click()
mm = driver.find_element_by_xpath('//*[#id="{}"]'.format(month))
mm.click()
Mistake in code mm = driver.find_element_by_xpath('//*[#id="{}"]'.format(month)). You find first element in DOM(which combined with element data instead data2) and it is not visible yet.
There is workig code
mm = driver.find_element_by_id('date2').find_element_by_class_name('months-view').find_element_by_id(month)
mm.click()
Also good deal, to use WebDriverWait, because the site is very slow.
for example
to_date = WebDriverWait(driver, 10).until(
expected_conditions.presence_of_element_located(
(By.XPATH, '//*[#id="date2"]/angular2-date-picker/div/div[1]/i')))

Webscrape table from CME, including selection of desired table from drop down menu

The below code works. It returns data in the default loaded table (making use of answer provided here: link, but how to access the other tables (that can be found by clicking on the 'Contracts' button and selecting from the menu a different contract, eg. Mar 2019)?
driver.get("http://www.cmegroup.com/tools-information/quikstrike/treasury-analytics.html")
# Need to include some more time here for data in iframe to load?
driver.implicitly_wait(3)
driver.switch_to.frame(driver.find_element_by_tag_name("iframe"))
soup = BeautifulSoup(driver.page_source, 'html.parser')
CMEtreasuryAnalytics._table = soup.select('table.grid')[0]
I tried this but get the following error returned: NoSuchFrameException: Message: no such frame: element is not a frame
driver.get("http://www.cmegroup.com/tools-nformation/quikstrike/treasury-analytics.html")
cDate = 'Dec 2018'
driver.switch_to.frame(driver.find_element_by_tag_name("iframe"))
elements = driver.find_elements_by_class_name("square-corners ")
options = [element.get_attribute("innerText") for element in elements]
if cDate in options:
element = elements[options.index(cDate)]
else:
pass
driver.switch_to.frame(element)
I've also tryed to 'click()' but couldn't get that to work either. I'm new to selenium and would appreciate some pointers on how to access the said data. I'm using python and chrome webdriver.
OK. I think I worked it out. The menu lies within the iFrame,
so after getting the element details, then need to click() the menu, then element.click(), then scrape the displayed data. The final code follows, but I don't know if it's the most straightforward way to approach it.
driver.get("http://www.cmegroup.com/tools-nformation/quikstrike/treasury-analytics.html")
cDate = 'Jun 2019'
driver.switch_to.frame(driver.find_element_by_tag_name("iframe"))
elements = driver.find_elements_by_class_name("square-corners ")
options = [element.get_attribute("innerText") for element in elements]
if cDate in options:
element = elements[options.index(cDate)]
else:
pass
# Click the dropdown menu labelled 'Contracts'
driver.find_element_by_xpath('//*[#id="ctl00_MainContent_ucViewControl_IntegratedStrikeAsYield_ucContractPicker_ucTrigger_lnkTrigger"]').click()
driver.implicitly_wait(1)
element.click()
driver.switch_to.frame(driver.find_element_by_tag_name("iframe"))
soup = BeautifulSoup(driver.page_source, 'html.parser')
CMEtreasuryAnalytics._table = soup.select('table.grid')[0]
Update:
The above worked for a while but then started failing with the below message. So maybe this is the right track but I need better way to select an option from the drop down list labelled 'Contracts'. How to do that?
Message: unknown error: Element is not clickable at point (511, 475). Other element would receive the click: <

Categories

Resources