2

I am trying to write a login function. When I try to login into my yahoo account, I send the correct keys for my email address, which works, but then when I click "next" it 'misses' the click and instead clicks the banner which opens up some sort of advertisement be it travel related or Norton anti-security, or something. I've been working on this issue intermittently throughout the past week surfing and digging through forums before finally making my first post.

I am aware of the different ways of element selectors via css, id, class name, xpath, etc... I tried sleep(), implicit_wait(), things along those lines. I also tried something with wait until clickable with the expected conditions module from selenium.webdriver.

I've attached an image of what I have so far. My python version is up-to-date as are my selenium and chrome driver installations. I saw a similar post already up, but the OP didn't seem to be encountering my issue. (how to click on the yahoo sign in link using selenium web driver?)

I tried this as well, and it opens the advertisement; in my executions, Norton seems to be the most frequently appearing advertisement. (login to Yahoo using Python Selenium)

I've looked at the API documentation, but there doesn't seem to be any clear direction on what I could do. I've attached screenshots of what happens on the running of the script as well as the code I have.

I got it to work for some runs where I was able to go to the next form to send my password keys, but it happened randomly and inexplicably.

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from login import password, email
from time import sleep

class yahoo():

def __init__(self):

    # INITIALIZE CHROME WEBDRIVER
    self.driver = webdriver.Chrome()
    self.driver.maximize_window()

def login(self):

    # OPEN BROWSER TO LOGIN PAGE AND MAXIMIZE
    self.driver.get("https://login.yahoo.com/config/login?.\
    src=fpctx&.intl=us&.lang=en-US&.done=https://www.yahoo.com")
    # LOGIN ACTIONS

    {# 1. send email address and click next
    self.driver.find_element_by_id('login-username').send_keys(email)
    element = WebDriverWait(self.driver, 10).until(\
            EC.presence_of_element_located((By.ID, "login-signin")))
    element.click()

    # 2. send password and click sign in
    self.driver.find_element_by_xpath('//*[@id="login-passwd"]').send_keys(password)
    self.driver.find_element_by_id('login-signin').click()}`enter code here




x = yfscreeners()
x.login()

Any help is well appreciated.

Norton advertisement instead of next form

Guy
  • 46,488
  • 10
  • 44
  • 88
  • Instead of using the id 'login-signin', have you tried to use other params to identify the element, like class, type or name ? You can add multiple parameters in the find_element_by_css_selector method, maybe it can helps – MatthiasDec Feb 18 '20 at 09:07
  • 1
    I literally threw every type of selector possible with selenium lol – David200042 Feb 25 '20 at 01:40

3 Answers3

1

To send a character sequence to the Email address field and invoke click() on the button with text as Next you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:

  • Using css_selector:

    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
    
    options = webdriver.ChromeOptions() 
    options.add_argument("start-maximized")
    options.add_experimental_option("excludeSwitches", ["enable-automation"])
    options.add_experimental_option('useAutomationExtension', False)
    driver = webdriver.Chrome(options=options, executable_path=r'C:\Utility\BrowserDrivers\chromedriver.exe')   
    driver.get('https://login.yahoo.com')
    WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input.phone-no#login-username"))).send_keys('my_username@yahoo.co.in')
    driver.find_element_by_css_selector("input#login-signin").submit()
    
  • Using xpath:

    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
    
    options = webdriver.ChromeOptions() 
    options.add_argument("start-maximized")
    options.add_experimental_option("excludeSwitches", ["enable-automation"])
    options.add_experimental_option('useAutomationExtension', False)
    driver = webdriver.Chrome(options=options, executable_path=r'C:\Utility\BrowserDrivers\chromedriver.exe')   
    driver.get('https://login.yahoo.com')
    WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//input[@class='phone-no ' and @id='login-username']"))).send_keys('my_username@yahoo.co.in')
    driver.find_element_by_xpath("//input[@id='login-signin']").submit()
    
  • Browser Snapshot:

yahoo_email_clicking

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • 1
    Wow, this worked really well, I only had to change the executable path for chrome driver on my linux machine, and the email entry. – David200042 Feb 19 '20 at 15:14
  • Okay, but I came across another issue, which would require me to add some code. I used the same method to type in the password keys and again click "next," but it seems to refresh on the password page, remove the password entry, and not complete the login... Any suggestions? Should I make a separate post? – David200042 Feb 20 '20 at 02:49
  • 1
    @RichardYim Can you raise a new question with your new requirement please. Stackoverflow contributors will be happy to help you out. – undetected Selenium Feb 20 '20 at 05:57
  • Just wanted to add this comment to this reply thread if someone needs it. Once you send the password keys, instead of "submit()" you have to "click()." Important distinction to be made there when moving up. – David200042 Feb 23 '20 at 10:18
1

I ran into the same problem. When using Selenium to log into Yahoo, no matter what I did it to try to target the "next" button it would always click the ad instead. It's almost like Yahoo intentionally designed the page this way to deter scripters (in my case the intent is quite benign :) )

In the case of entering the username, you can work around this by calling submit() on the button instead of click(), but this doesn't work for the password, it just refreshes the page.

I worked around the issue by sending a "return" keystroke to the password field instead of trying to click or submit the next/login button (this is in PHP using the MinkContext but the principle should be the same):

<?php    
$xpath = $this->getSession()->getSelectorsHandler()->selectorToXpath('named', [
  'field',
  'login-passwd'
]);
$this->getMink()->getSession()->getDriver()->getWebDriverSession()->element('xpath', $xpath)->postValue(['value' => ["\r\n"]]);
Dane Powell
  • 621
  • 7
  • 13
  • idk if my use case is "benign" I was trying scrape stocks. I ended up just scripting the click and keystroke sequence on the screener page, and scraping and parsing the resulting html code. My web scraper works, got it set up with crontab; does it every weekday. Takes only about a minute. I figured that YF seemed to be deterring crawlers. But I finished this weeks ago haha. WIll keep this in mind though. Thank you! – David200042 Jul 16 '20 at 19:46
0

Use WebDriverWait for the email field as well

wait = WebDriverWait(self.driver, 10)
wait.until(EC.visibility_of_element_located((By.ID, 'login-username'))).send_keys(email)
wait.until(EC.visibility_of_element_located((By.ID, 'login-signin'))).click()
Guy
  • 46,488
  • 10
  • 44
  • 88