简体   繁体   English

使用 Python-Selenium 自动登录 GMAIL

[英]Automating GMAIL login using Python-Selenium

I am trying to automate logging into GMail using Selenium package of Python.我正在尝试使用 Python 的 Selenium 包自动登录 GMail。 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/fxdriver@googlecode.com/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此外,我试图通过将其与此处给出的类似问题的答案进行比较来找出代码中的错误: 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?有人可以指导我走正确的道路并让我知道我在哪里犯了错误吗?

PS: This is my first post on stackoverflow. PS:这是我在 stackoverflow 上的第一篇文章。 Please excuse me for any mistake that I have made in posting the question请原谅我在发布问题时犯的任何错误

You are trying to find the Passwd id of the element which is not loaded in dom yet.您正在尝试查找尚未加载到 dom 中的元素的Passwd id。 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推荐的方法是browser.implicitly_wait(num_of_seconds)看到这个

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. 2020 年使用 Gmail 登录要困难得多,因为 Gmail 将 selenium 操作的窗口作为机器人窗口,并会给出这样的消息。 img of error错误的img

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.您可以登录到另一个网站,因为谷歌将使用另一个网站(如 StackOverflow)或其他一些使用 Gmail 登录的网站接受它作为安全登录。

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

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()

You can use key to avoid one more search for next element您可以使用 key 来避免再次搜索下一个元素

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)

You can do this but I would not recommend automation something like gmail.你可以这样做,但我不推荐像 gmail 这样的自动化。 It would not be a good practise.这不会是一个好的做法。 For testing emails - I would suggest a tool like - https://putsbox.com/对于测试电子邮件 - 我建议使用一个工具 - https://putsbox.com/

The method shearching for ID is no longer working for me too .剪切 ID 的方法也不再适用于我。

I checked the docs and found out a bunch of other methods to get to success .我检查了文档并发现了许多其他方法来获得成功。

Try searching the element by NAME , it works.尝试按 NAME 搜索元素,它有效。

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

CLASS_NAME 班级名称

I have another solution that works without any hustle.我有另一种解决方案,无需任何喧嚣。 Use Seleniumwire with undetected browser v2未检测到的浏览器 v2 中使用Seleniumwire

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除此之外,seleniumwire 还有很多很棒的功能,请查看 github仓库

The problem is gmail changed the way login works.问题是 gmail 改变了登录的方式。 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()

The best way is to use explicit waits when you need to wait any element.最好的方法是在需要等待任何元素时使用显式等待。 It's better than time.sleep(1).它比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.希望能帮到你。

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")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM