简体   繁体   English

使用 Python 登录到 Gmail 并检测到登录失败

[英]Logging into Gmail using Python with detecting failed login

I know that multiple people have asked a similar question about this however, I would like to know how to login to gmail (or google account) using python.我知道很多人对此提出了类似的问题,但是我想知道如何使用 python 登录到 gmail(或谷歌帐户)。 I have a code already (see below) that can loggin the user to gmail using selenium.我已经有一个代码(见下文),可以使用 selenium 将用户登录到 gmail。 However I noticed a few problems.但是我注意到了一些问题。

  1. The browser closes when the program stops/closes.当程序停止/关闭时浏览器关闭。
  2. It can not detect a failed login.它无法检测到失败的登录。

Both problems really need to be solved for me to be able to work on my project.这两个问题确实需要解决,我才能在我的项目上工作。 I don't mind using something else than selenium like pyautogui to open google.我不介意使用 pyautogui 之类的 selenium 以外的其他东西来打开谷歌。 However, it needs to be able to detect a failed login and then close the browser, if the login is successful the browser should stay open for the user to use.但是,它需要能够检测到登录失败然后关闭浏览器,如果登录成功,浏览器应该保持打开状态供用户使用。

My code:我的代码:

from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager

def gmail_login(username, password):
    gmailId = username
    passWord = password
    driver = webdriver.Chrome(ChromeDriverManager().install())
    try:
        driver.get(r'https://accounts.google.com/signin/v2/identifier?continue=' + \
                   'https%3A%2F%2Fmail.google.com%2Fmail%2F&service=mail&sacu=1&rip=1' + \
                   '&flowName=GlifWebSignIn&flowEntry = ServiceLogin')
        driver.implicitly_wait(3)

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

        nextButton = driver.find_elements_by_xpath('//*[@id ="identifierNext"]')
        nextButton[0].click()

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

        nextButton = driver.find_elements_by_xpath('//*[@id ="passwordNext"]')
        nextButton[0].click()

    except:
        driver.close()


gmail_login("email@gmail.com", "Password")

I tought of checking the url after the program has finished if it is equal to a logged in url however that didn't really work too well and now I am out of ideas.在程序完成后,如果它等于登录的 url,我会检查 url,但是它并没有真正工作得太好,现在我没有想法了。

Updated 02-14-2021 2021 年 2 月 14 日更新


I was able to extract this error message:我能够提取此错误消息:

在此处输入图像描述

using this code:使用此代码:

signin_failure = driver.find_elements_by_xpath("//*[contains(text(),'Couldn’t sign you in')]")
if signin_failure[1].text == 'Couldn’t sign you in':
   print('something went wrong')

In a normal gmail login you will get one of these two error messages:在正常的 gmail 登录中,您将收到以下两条错误消息之一:

  • Couldn't find your Google Account找不到您的 Google 帐户
  • Wrong password.密码错误。 Try again or click Forgot password to reset it重试或单击忘记密码以重置它

The XPATH to get these error messages is:获取这些错误消息的 XPATH 是:

wrong_email = driver.find_elements_by_xpath("//*[contains(text(),'Couldn’t find your Google Account')]")

wrong_password = driver.find_elements_by_xpath("//*[contains(text(),'Wrong password. Try again or click Forgot password to reset it')]")

if you want to close the browser after an error message, such as Couldn't sign you in then add a driver.close() statement.如果您想在出现错误消息(例如无法登录)后关闭浏览器,请添加driver.close()语句。

signin_failure = driver.find_elements_by_xpath("//*[contains(text(),'Couldn’t sign you in')]")
if signin_failure[1].text == 'Couldn’t sign you in':
   print('something went wrong')
   driver.close()

If you want to keep the browser open then don't use the driver.close() statement, but add this experimental_option如果你想保持浏览器打开,那么不要使用driver.close()语句,而是添加这个experimental_option

chrome_options.add_experimental_option("detach", True)

I was also able to throw these error messages:我还能够抛出这些错误消息:

signin_failure = driver.find_elements_by_xpath("//*[contains(text(),'Couldn’t sign you in')]")

# this message was throw when the next button was clicked prior to entering a username
no_input = driver.find_elements_by_xpath("//*[contains(text(),'Enter a valid email of phone number')]")

PSEUDOCODE CODE:伪代码:

This is how you could do it, but you might have to adjust the code as you test.这就是您可以做到的方式,但您可能必须在测试时调整代码。

def gmail_login(username, password):
    driver = webdriver.Chrome(ChromeDriverManager().install())
    try:
        driver.get(r'https://accounts.google.com/signin/v2/identifier?continue=' + \
                   'https%3A%2F%2Fmail.google.com%2Fmail%2F&service=mail&sacu=1&rip=1' + \
                   '&flowName=GlifWebSignIn&flowEntry = ServiceLogin')
        driver.implicitly_wait(3)

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

        nextButton = driver.find_elements_by_xpath('//*[@id ="identifierNext"]')
        nextButton[0].click()

        wrong_email = driver.find_elements_by_xpath("//*[contains(text(),'Couldn’t find your Google Account')]")

        # you need to check this slice
        if wrong_email[1].text == 'Couldn’t find your Google Account':
            print('something went wrong')
            driver.close()

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

            nextButton = driver.find_elements_by_xpath('//*[@id ="passwordNext"]')
            nextButton[0].click()

            wrong_password = driver.find_elements_by_xpath("//*[contains(text(),'Wrong password. Try again or click Forgot password to reset it')]")

            # you need to check this slice
            if wrong_password[1].text == 'Wrong password. Try again or click Forgot password to reset it':
                print('something went wrong')
                driver.close()

    except:
        driver.close()

Original post原帖


Google forbids using automated scripts for logging into Gmail. Google 禁止使用自动化脚本登录 Gmail。 I have tried using selenium and I get this warning .我尝试使用 selenium 并收到此警告

无法登录

When I click Learn More I get this message.当我单击了解更多时,我会收到此消息。

在此处输入图像描述

Please note this line: Are being controlled through software automation rather than a human请注意这一行:正在通过软件自动化而不是人为控制

Here are other question where they discuss work arounds for this Google direct login issue:以下是他们讨论此 Google 直接登录问题的解决方法的其他问题:

You should be looking at the Gmail API for programmatic access, it will work a lot better than trying to drive the UI like selenium does.您应该查看 Gmail API 以进行编程访问,它比尝试像 selenium 那样驱动 UI 效果要好得多。 https://developers.google.com/gmail/api/quickstart/python https://developers.google.com/gmail/api/quickstart/python

I have no time right now to code, but:我现在没有时间编码,但是:

To make your browser stay open just delete your driver.close() function, this is what makes it to stop when program reach it.要让您的浏览器保持打开状态,只需删除您的 driver.close() function,这就是它在程序到达时停止的原因。

To solve your problem, just try to make a successfull login and a failing one, look for a WebElement in both that indicates one of the events in an unique way, then, put the driver.close() in an if declaration only if selenium finds the WebElement in viewport after the login (failed one), otherwise do not let it execute the instruction.要解决您的问题,只需尝试成功登录和失败登录,在两者中查找以独特方式指示其中一个事件的 WebElement,然后仅在 selenium 时将 driver.close() 放入 if 声明中登录后在视口中找到WebElement(失败),否则不要让它执行指令。

Easy as that.就这么简单。

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

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