45

I'm trying to automatically generate lots of users on the webpage kahoot.it using selenium to make them appear in front of the class, however, I get this error message when trying to access the inputSession item (where you write the gameID to enter the game)

from selenium import webdriver
from selenium.webdriver.common.keys import Keys

driver = webdriver.Firefox()
driver.get("http://www.kahoot.it")

gameID = driver.find_element_by_id("inputSession")
username = driver.find_element_by_id("username")

gameID.send_keys("53384")

This is the error:

selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element:
{"method":"id","selector":"inputSession"}
Zoe
  • 27,060
  • 21
  • 118
  • 148
Morten Stulen
  • 1,243
  • 1
  • 14
  • 26

9 Answers9

54

Looks like it takes time to load the webpage, and hence the detection of webelement wasn't happening. You can either use @shri's code above or just add these two statements just below the code driver = webdriver.Firefox():

driver.maximize_window() # For maximizing window
driver.implicitly_wait(20) # gives an implicit wait for 20 seconds
swiss_knight
  • 5,787
  • 8
  • 50
  • 92
Subh
  • 4,354
  • 1
  • 13
  • 32
43

Could be a race condition where the find element is executing before it is present on the page. Take a look at the wait timeout documentation. Here is an example from the docs

from selenium import webdriver
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.Firefox()
driver.get("http://somedomain/url_that_delays_loading")
try:
    element = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.ID, "myDynamicElement"))
    )
finally:
    driver.quit()
shri046
  • 1,148
  • 11
  • 12
4

In my case, the error was caused by the element I was looking for being inside an iframe. This meant I had to change frame before looking for the element:

from selenium import webdriver
    
driver = webdriver.Chrome()
driver.get("https://www.google.co.uk/maps")

frame_0 = driver.find_element_by_class_name('widget-consent-frame')
driver.switch_to.frame(frame_0)

agree_btn_0 = driver.find_element_by_id('introAgreeButton')
agree_btn_0.click()

Reddit source

kohane15
  • 809
  • 12
  • 16
Claudio Paladini
  • 1,000
  • 1
  • 10
  • 20
3

You can also use below as an alternative to the above two solutions:

import time
time.sleep(30) 
Tikkaty
  • 772
  • 1
  • 8
  • 24
  • 3
    driver.implicitly_wait(30) is a better option because this sleep ALWAYS wait 30' (not only when need it) – walter Mar 04 '20 at 10:16
2

It seems that your browser did not read proper HTML texts/tags, use a delay function that'll help the page to load first and then get all tags from the page.

driver = webdriver.Chrome('./chromedriver.exe')
# load the page
driver.get('https://www.instagram.com/accounts/login/')
# use delay function to get all tags
driver.implicitly_wait(20)
# access tag
driver.find_element_by_name('username').send_keys(self.username)
a zEnItH
  • 137
  • 3
  • 11
1

this worked for me (the try/finally didn't, kept hitting the finally/browser.close())

from selenium import webdriver

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.Firefox()
driver.get('mywebsite.com')

username = None
while(username == None):
    username = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.ID, "username"))
    )
username.send_keys('myusername@email.com')
lowlife
  • 11
  • 1
1

Also for some, it may be due to opening the new tabs when clicking the button(not in this question particularly). Then you can switch tabs by command.

driver.switch_to.window(driver.window_handles[1]) #for switching to second tab
kishmat
  • 11
  • 1
1

I had the same problem as you and this solution saved me:

from selenium.webdriver.support import expected_conditions as EC

wait = WebDriverWait(driver, 10)
element = wait.until(EC.element_to_be_clickable((By.ID, 'someid')))
Elias Holzmann
  • 3,216
  • 2
  • 17
  • 33
0

it just means the function is executing before button can be clicked. Example solution:

from selenium import sleep
# load the page first and then pause
sleep(3)
# pauses executing the next line for 3 seconds
Nikaido
  • 4,443
  • 5
  • 30
  • 47
Omry
  • 1
  • 2