I am trying to use login to an Investors Business Daily service using python for selenium using a CSS selector. I found a unique atribute under an input tag which runs successfullyl in the chrome browser console:
$$("[data-gigya-placeholder='Email']")
However, the coresponding python does not work:
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://myibd.investors.com/secure/signin.aspx?eurl=https://marketsmith.investors.com/")
login = driver.find_element_by_css_selector("[data-gigya-placeholder='Email']")
Full error log:
NoSuchElementException Traceback (most recent call last) ~\AppData\Local\Temp/ipykernel_26004/2365346870.py in 1 # find the element for entering the username 2 #login = driver.find_element_by_css_selector("input[data-gigya-placeholder='Email']") ----> 3 login = driver.find_element_by_css_selector("[data-gigya-placeholder='Email']") 4 5
~\miniconda3\envs\selenium_env\lib\site-packages\selenium\webdriver\remote\webdriver.py in find_element_by_css_selector(self, css_selector) 596 element = driver.find_element_by_css_selector('#foo') 597 """ --> 598 return self.find_element(by=By.CSS_SELECTOR, value=css_selector) 599 600 def find_elements_by_css_selector(self, css_selector):
~\miniconda3\envs\selenium_env\lib\site-packages\selenium\webdriver\remote\webdriver.py in find_element(self, by, value) 974 by = By.CSS_SELECTOR 975 value = '[name="%s"]' % value --> 976 return self.execute(Command.FIND_ELEMENT, { 977 'using': by, 978 'value': value})['value']
~\miniconda3\envs\selenium_env\lib\site-packages\selenium\webdriver\remote\webdriver.py in execute(self, driver_command, params) 319 response = self.command_executor.execute(driver_command, params) 320 if response: --> 321 self.error_handler.check_response(response) 322 response['value'] = self._unwrap_value( 323 response.get('value', None))
~\miniconda3\envs\selenium_env\lib\site-packages\selenium\webdriver\remote\errorhandler.py in check_response(self, response) 240 alert_text = value['alert'].get('text') 241 raise exception_class(message, screen, stacktrace, alert_text) --> 242 raise exception_class(message, screen, stacktrace) 243 244 def _value_or_default(self, obj, key, default):
NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"[data-gigya-placeholder='Email']"}
I've tried an alternative python syntax which results in a similar error message:
login = driver.find_element(By.CSS_SELECTOR, "[data-gigya-placeholder='Email']")
Full Error Log:
NoSuchElementException Traceback (most recent call last) ~\AppData\Local\Temp/ipykernel_23192/47655697.py in ----> 1 login = driver.find_element(By.CSS_SELECTOR, "[data-gigya-placeholder='Email']")
~\miniconda3\envs\selenium_env\lib\site-packages\selenium\webdriver\remote\webdriver.py in find_element(self, by, value) 974 by = By.CSS_SELECTOR 975 value = '[name="%s"]' % value --> 976 return self.execute(Command.FIND_ELEMENT, { 977 'using': by, 978 'value': value})['value']
~\miniconda3\envs\selenium_env\lib\site-packages\selenium\webdriver\remote\webdriver.py in execute(self, driver_command, params) 319 response = self.command_executor.execute(driver_command, params) 320 if response: --> 321 self.error_handler.check_response(response) 322 response['value'] = self._unwrap_value( 323 response.get('value', None))
~\miniconda3\envs\selenium_env\lib\site-packages\selenium\webdriver\remote\errorhandler.py in check_response(self, response) 240 alert_text = value['alert'].get('text') 241 raise exception_class(message, screen, stacktrace, alert_text) --> 242 raise exception_class(message, screen, stacktrace) 243 244 def _value_or_default(self, obj, key, default):
NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"[data-gigya-placeholder='Email']"}
CodePudding user response:
First of all this element is inside the iframe, so you have to switch to that iframe in order to access that element.
Also you are missing a wait / delay.
You should wait for the element to be ready before accessing it.
The best way to do that is to use explicit waits of expected conditions.
Try the following:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
wait = WebDriverWait(driver, 20)
driver.get("https://myibd.investors.com/secure/signin.aspx?eurl=https://marketsmith.investors.com/")
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"#signin-iframe")))
login = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "[data-gigya-placeholder='Email']")))