0

Every time I load up python script the Xpath for the Facebook login button and popup button has to changed manually every time before I login. How do I change this so that I dont have to enter the XPath manually?

from selenium import webdriver
from time import sleep

class TinderBot():
    def __init__(self):
        self.driver = webdriver.Chrome()

    def login(self):
        self.driver.get('https://tinder.com')

        sleep(3)

        #fbxpath = //button[@type = 'button' and @aria-label = 'Log in with Facebook']

        fb_btn = self.driver.find_element_by_xpath('//*[@id="content"]/div/div[1]/div/div/main/div/div[2]/div[2]/div/div/span/div[2]/button')
        fb_btn.click()

        base_window = self.driver.window_handles[0]
        self.driver.switch_to_window(self.driver.window_handles[1])
        fbemail = self.driver.find_element_by_xpath('//*[@id="email"]')
        fbemail.send_keys('ara_98425@yahoo.com')

        fbpass = self.driver.find_element_by_xpath('//*[@id="pass"]')
        fbpass.send_keys('BlackToast5')

        login_btn = self.driver.find_element_by_xpath('//*[@id="u_0_0"]')
        login_btn.click()

        self.driver.switch_to_window(base_window)

        popup1 = self.driver.find_element_by_xpath('//*[@id="modal-manager"]/div/div/div/div/div[3]/button[1]')
        popup1.click()

        popup2 = self.driver.find_element_by_xpath('//*[@id="modal-manager"]/div/div/div/div/div[3]/button[1]')
        popup2.click()

bot = TinderBot()
bot.login()

This is the error I get:

File "tind_bt.py", line 16, in login
    fb_btn = self.driver.find_element_by_xpath('//*[@id="content"]/div/div[1]/div/div/main/div/div[2]/div[2]/div/div/span/div[2]/button')
  File "C:\ProgramData\Anaconda3\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 394, in find_element_by_xpath
    return self.find_element(by=By.XPATH, value=xpath)
  File "C:\ProgramData\Anaconda3\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 978, in find_element
    'value': value})['value']
  File "C:\ProgramData\Anaconda3\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "C:\ProgramData\Anaconda3\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//*[@id="content"]/div/div[1]/div/div/main/div/div[2]/div[2]/div/div/span/div[2]/button"}
  (Session info: chrome=80.0.3987.106)
Guy
  • 46,488
  • 10
  • 44
  • 88

2 Answers2

1

You were close. To invoke click() on the element with text as Log in with Facebook you need to induce WebDriverWait for the element_to_be_clickable() reaching till the child <span> and you can use either of the following Locator Strategies:

  • Using CSS_SELECTOR:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[type = 'button'][aria-label = 'Log in with Facebook'] span"))).click()
    
  • Using XPATH:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[@type = 'button' and @aria-label = 'Log in with Facebook']//span"))).click()
    
  • Note : You have to add the following imports :

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    
  • Browser Snapshot:

tinder_facebook_login


Reference

You can find a detailed relevant discussion in:

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
-2

Maybe you can implement the WebDriverWait and see if that takes care of the problem.

This might get you started - Selenium WebDriver wait till element is displayed

Here's the Python documentation for explicit waits - https://selenium-python.readthedocs.io/waits.html

Leo Santos
  • 190
  • 3
  • 11