6

I am trying to automate logging into GMail using Selenium package of Python. However, I am not able to accomplish the task and get the following error:

Traceback (most recent call last):
  File "C:\Users\Surojit\Desktop\Python\automaticpasswordFiller.py", line   21, in <module>
    passwordElem = browser.find_element_by_id('Passwd')
  File "C:\Users\Surojit\AppData\Local\Programs\Python\Python35-32\lib\site- packages\selenium\webdriver\remote\webdriver.py", line 266, in  find_element_by_id
    return self.find_element(by=By.ID, value=id_)
  File "C:\Users\Surojit\AppData\Local\Programs\Python\Python35-32\lib\site- packages\selenium\webdriver\remote\webdriver.py", line 744, in find_element
    {'using': by, 'value': value})['value']
  File "C:\Users\Surojit\AppData\Local\Programs\Python\Python35-32\lib\site-  packages\selenium\webdriver\remote\webdriver.py", line 233, in execute
    self.error_handler.check_response(response)
  File "C:\Users\Surojit\AppData\Local\Programs\Python\Python35-32\lib\site- packages\selenium\webdriver\remote\errorhandler.py", line 194, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: Unable to locate  element: {"method":"id","selector":"Passwd"}
Stacktrace:
    at FirefoxDriver.prototype.findElementInternal_   (file:///C:/Users/Surojit/AppData/Local/Temp/tmpceecsm46/extensions/fxdriver@goo glecode.com/components/driver-component.js:10770)
     at FirefoxDriver.prototype.findElement   (file:///C:/Users/Surojit/AppData/Local/Temp/tmpceecsm46/extensions/fxdriver@goo  glecode.com/components/driver-component.js:10779)
    at DelayedCommand.prototype.executeInternal_/h   (file:///C:/Users/Surojit/AppData/Local/Temp/tmpceecsm46/extensions/fxdriver@goo    glecode.com/components/command-processor.js:12661)
    at DelayedCommand.prototype.executeInternal_    (file:///C:/Users/Surojit/AppData/Local/Temp/tmpceecsm46/extensions/fxdriver@goo glecode.com/components/command-processor.js:12666)
    at DelayedCommand.prototype.execute/<   (file:///C:/Users/Surojit/AppData/Local/Temp/tmpceecsm46/extensions/[email protected]/components/command-processor.js:12608) 

The simple code that I have written is:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
import time

browser = webdriver.Firefox()
browser.get('http://gmail.com')
action = webdriver.ActionChains(browser)
emailElem = browser.find_element_by_id('Email')
emailElem.send_keys("MyUserName")
browser.find_element_by_name('signIn').click()
#browser.get('https://accounts.google.com/ServiceLogin?         service=mail&continue=https://mail.google.com/mail/#password')
passwordElem = browser.find_element_by_id('Passwd')
passwordElem.send_keys("MyPassword")
browser.find_element_by_name('signIn').click()

Also, I have tried to find out the error in my code by comparing it to an answer given to a similar question here at: Auto connect on my Gmail account with Python Selenium

Can someone please guide me on the right path and let me know where I am making a mistake?

P.S: This is my first post on stackoverflow. Please excuse me for any mistake that I have made in posting the question

2
  • 2
    You could use a proper API, rather than something that can break at any moment? developers.google.com/gmail/api/quickstart/python Commented Apr 2, 2016 at 20:24
  • I'm looking for a solution like this for Google Hangouts however the API only works for GSuite I believe. For personal google hangout chats there is no API Commented Dec 6, 2018 at 22:24

11 Answers 11

10

You are trying to find the Passwd id of the element which is not loaded in dom yet. Try adding some delay so that the page could load.

emailElem = browser.find_element_by_id('Email')
emailElem.send_keys('MyUserName')
nextButton = browser.find_element_by_id('next')
nextButton.click()
time.sleep(1)
passwordElem = browser.find_element_by_id('Passwd')
passwordElem.send_keys('MyPassword')
signinButton = browser.find_element_by_id('signIn')
signinButton.click()

recommended method is browser.implicitly_wait(num_of_seconds) see this

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! @dnit13. This works perfectly, I was missing the sleep command.
6

In 2020 signing in with Gmail is much more tougher because Gmail takes selenium operated window as a bot window and will give a message like this one.img of error

But now I have found a successful way to log in without any error or warning by google.

you can log in to another website as google will accept it as secure login using another website like StackOverflow or some other website with Gmail login.

def gmail_sign_in(email, password):
    driver = webdriver.Chrome()

    driver.get('https://stackoverflow.com/users/signup?ssrc=head&returnurl=%2fusers%2fstory%2fcurrent')

    driver.find_element_by_xpath('//*[@id="openid-buttons"]/button[1]').click()

    driver.find_element_by_xpath('//*[@id="identifierId"]').send_keys(email)

    input = WebDriverWait(driver, 10).until(
        EC.element_to_be_clickable((By.XPATH, '//*[@id="identifierNext"]/span/span'))
    )
    input.click()

    driver.implicitly_wait(1)

    driver.find_element_by_xpath('//*[@id="password"]/div[1]/div/div[1]/input').send_keys(password)

    input = WebDriverWait(driver, 10).until(
        EC.element_to_be_clickable((By.XPATH, '//*[@id="passwordNext"]/span/span'))
    )
    input.click()
    driver.implicitly_wait(1)
    driver.get('https://www.google.com/')

hope the code is understandable just this function and put your email and password make sure you have the appropriate imports.

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

Comments

4

I hope that, it will be helpful for automate the gmail in updated chrome version.

from selenium import webdriver
import time


driver = webdriver.Chrome()
driver.get("http://gmail.com")

driver.find_element_by_id("identifierId").send_keys('your mail id')
driver.find_element_by_id("identifierNext").click()
time.sleep(5)
driver.find_element_by_name("password").send_keys('your password')
driver.find_element_by_id("passwordNext").click()
time.sleep(5)

driver.get("https://accounts.google.com/SignOutOptions?hl=en&continue=https://mail.google.com/mail&service=mail")
driver.find_element_by_xpath('//button[normalize-space()="Sign out"]').click()
driver.close()

Comments

3

I have another solution that works without any hustle. Use Seleniumwire with undetected browser v2

from seleniumwire.undetected_chromedriver.v2 import Chrome, ChromeOptions
options = {}
chrome_options = ChromeOptions()
chrome_options.add_argument('--user-data-dir=hash')
chrome_options.add_argument("--disable-gpu")
chrome_options.add_argument("--incognito")
chrome_options.add_argument("--disable-dev-shm-usage")
# chrome_options.add_argument("--headless")
driver = Chrome(seleniumwire_options=options, options=chrome_options)

# use selenium methods as usual to navigate through elements and you will be able to log in.

In addition to this, seleniumwire has many awesome features, checkout github repository

Comments

1

You can use key to avoid one more search for next element

from selenium.webdriver.common.keys import Keys

   def login_gmail(email,password):

     browser.find_element_by_name('Email').send_keys(email+Keys.ENTER)
     time.sleep(2)
     browser.find_element_by_name('Passwd').send_keys(password+Keys.ENTER)

Comments

1

You can do this but I would not recommend automation something like gmail. It would not be a good practise. For testing emails - I would suggest a tool like - https://putsbox.com/

Comments

1

The method shearching for ID is no longer working for me too .

I checked the docs and found out a bunch of other methods to get to success .

Try searching the element by NAME , it works.

password = wait.until(
EC.element_to_be_clickable((By.NAME,'password')))

CLASS_NAME

1 Comment

This is the updated one...Gmail has its password "id" to "class".
0

The problem is gmail changed the way login works. You insert your email on one page then click next and then you get a new page where you insert the password and click on sign in. Try something like this:

from selenium import webdriver
browser = webdriver.Firefox()

browser.get('http://gmail.com')

emailElem = browser.find_element_by_id('Email')
emailElem.send_keys('MyUserName')
nextButton = browser.find_element_by_id('next')
nextButton.click()
passwordElem = browser.find_element_by_id('Passwd')
passwordElem.send_keys('MyPassword')
signinButton = browser.find_element_by_id('signIn')
signinButton.click()

Comments

0

The best way is to use explicit waits when you need to wait any element. It's better than time.sleep(1).

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

browser = webdriver.Firefox()
browser.get('http://gmail.com')
wait = WebDriverWait(browser, 10)

password_elem = wait.until(EC.presence_of_element_located((By.ID,'Passwd')))
password_elem.send_keys("MyPassword")
browser.find_element_by_name('signIn').click()

Hope, this will help you.

Comments

0

This is a more updated version

def loginToGmail():
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
from time import sleep




chrome_driver = "C:/Python37/chromedriver.exe"
browser = webdriver.Chrome(chrome_driver) 
browser.get('https://gmail.com')

if "inbox" in browser.current_url:
    print("Logged in")
else:
    identifier=WebDriverWait(browser, 30).until(EC.presence_of_element_located((By.NAME, "identifier"))) 
    identifier.send_keys(LOGIN)
    nextBtn = browser.find_element_by_id ('identifierNext')
    nextBtn.click()
    sleep(1)
    password=WebDriverWait(browser, 30).until(EC.presence_of_element_located((By.NAME, "password")))
    password.send_keys(PASSWD)
    nextBtn = browser.find_element_by_id('passwordNext')
    nextBtn.click()

    waitTimer=0
    logged=False
    while waitTimer<30 and not logged:
        sleep(1)
        waitTimer+=1
        if "inbox" in browser.current_url: 
            logged=True
            print("Logged in")

Comments

0

LATEST SOLUTION 2022-02-23 From terminal pip install undetected-chromedriver then do the following steps, as shown below.
NOTE: indent your code inside if name == main, as i have done, only then the program will work

import undetected_chromedriver as uc
from time import sleep
from selenium.webdriver.common.by import By


if __name__ == '__main__':
    
    driver = uc.Chrome()
    driver.get('https://accounts.google.com/')

    # add email
    driver.find_element(By.XPATH, '//*[@id="identifierId"]').send_keys(YOUR EMAIL)
    driver.find_element(By.XPATH, '//*[@id="identifierNext"]/div/button/span').click()
    sleep(3)
    driver.find_element(By.XPATH, '//*[@id="password"]/div[1]/div/div[1]/input').send_keys(YOUR PASSWORD)
    driver.find_element(By.XPATH, '//*[@id="passwordNext"]/div/button/span').click()
    sleep(10)


Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.