1

I would like to login to the site using selenium.

https://www.fivestars-markets.com/login/

This page is using javascript to generate login widget and that widget is located inside iframe.

I have tried following python code but without success.

Python code trial:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

browser = webdriver.Chrome()
browser.get('https://www.fivestars-markets.com/login/')
browser.implicitly_wait(15)

iframe = browser.find_elements_by_tag_name('iframe')[0]
browser.switch_to_frame(iframe)
username = browser.find_element_by_id('input_0');
username.send_keys(usernameStr)

Here is the error I got when I've executed the python code.

Error trace logs:

Traceback (most recent call last):
  File "highAndlow.py", line 16, in <module>
    username = browser.find_element_by_id('input_0');
  File "/usr/local/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py", line 360, in find_element_by_id
    return self.find_element(by=By.ID, value=id_)
  File "/usr/local/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py", line 978, in find_element
    'value': value})['value']
  File "/usr/local/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "/usr/local/lib/python2.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"id","selector":"input_0"}

Any idea ?

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
shinjiro
  • 13
  • 2

3 Answers3

1

You're switching to wrong iframe. Try to use more specific selector for iframe:

iframe = browser.find_element_by_class_name('xcomponent-component-frame')
browser.switch_to_frame(iframe)
username = browser.find_element_by_id('input_0');
username.send_keys(usernameStr)
Andersson
  • 51,635
  • 17
  • 77
  • 129
1

Seems you were almost there. I am not sure why you would use find_elements_by_tag_name() with an index [0] as the HTML DOM contains only one <iframe> tag.

As per best practices as the desired elements are within an <iframe> so you have to:

  • Induce WebDriverWait for the desired frame to be available and switch to it.
  • Induce WebDriverWait for the desired element to be clickable.
  • You can use the following solution:

    • Using CSS_SELECTOR:

      WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe.xcomponent-component-frame.xcomponent-visible")))
      WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input#input_0"))).send_keys(usernameStr)
      
    • Using XPATH:

      WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[@class='xcomponent-component-frame xcomponent-visible']")))
      WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@id='input_0']"))).send_keys(usernameStr)
      
    • 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
      

Here you can find a relevant discussion on Ways to deal with #document under iframe

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
0

Since your question is "how to login" and not "how to make the login form works", let me point out another way of doing.

If you need only one (or a few) accounts to login, you could use cookies.

The idea is simple,

  1. You create a simple Python / Selenium script that just run the browser, get the homepage and wait for any input (just to let you perform manual actions before going further)
  2. When the script is waiting, you login manually using the Selenium browser.
  3. You input something to your running script
  4. The script dump the cookies value as pickle data and save it somewhere

Then, to login you just load the homepage, load cookies, refresh, you are logged in.

I maid an anwser to dump and load cookies using Selenium & Pickle: Python: use cookie to login with Selenium

Arount
  • 9,853
  • 1
  • 30
  • 43
  • It looks greate idea to me because the idea doesn't rely on the detail of the html code. Maybe I should change my plan to use cookies. Thank you for your kind help. – shinjiro Dec 06 '18 at 11:07