43

I have the following three buttons that I can't figure out how to grab the text that is inside of them (e.g Outliers). I tried browser.find_element_by_link_text("Outliers").click(), but got "Unable to locate element" error. How can I do it?

enter image description here

Ratmir Asanov
  • 6,237
  • 5
  • 26
  • 40
sprogissd
  • 2,755
  • 5
  • 24
  • 45

4 Answers4

80

See: find_element_by_* commands are deprecated in selenium

In newer versions of selenium try:

from selenium.webdriver.common.by import By
browser.find_element(By.XPATH, '//button[text()="Outliers"]')

older versions of selenium:

browser.find_element_by_xpath('//button[text()="Outliers"]')

To update ALL of the older versions I found a nifty regex here, and then just fixup the import:

jmunsch
  • 22,771
  • 11
  • 93
  • 114
  • Update: find_element_by_xpath is deprecated now and one should use the equivalent `browser.find_element(By.XPATH, '//button[normalize-space()="Outliers"]')` (need to `from selenium.webdriver.common.by import By`) – Clang Jul 22 '22 at 09:32
27

There are two ways :

  1. By using text() method:

browser.find_element(By.XPATH,'//button[text()="Outliers"]')

  1. By using normalize-space() method:

browser.find_element(By.XPATH, '//button[normalize-space()="Outliers"]')

Note : It is always better to use normalize-space() method as it will work even if there are spaces present at the start of your text or at the end of text, because normalize-space() method trim the left and right side spaces

For More information on Normalize-space()

Pritam Maske
  • 2,670
  • 2
  • 22
  • 29
  • Thanks for the tip with normalize-space(), this was often an issue with the other solution for me. Just one update, find_element_by_xpath is deprecated now and one should use the equivalent `browser.find_element(By.XPATH, '//button[normalize-space()="Outliers"]')` (need to `from selenium.webdriver.common.by import By`) – Clang Jul 22 '22 at 09:31
16

Try this XPath:

"//button[@class='three-state-item btn btn-default'][.='Outliers']".

Ratmir Asanov
  • 6,237
  • 5
  • 26
  • 40
Grasshopper
  • 8,908
  • 2
  • 17
  • 32
-2

This is the solution that worked for me:

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

CHROME_DRIVER_PATH = Your Driver Path
USERNAME = YOUR USERNAME
PASSWORD = YOUR PASSWORD
SIMILAR_ACCOUNT = "idogsplanet"

class InstaFollower:
    def __init__(self, driver_path):
        self.driver = webdriver.Chrome(executable_path=driver_path)

    def login(self):
        self.driver.get("https://www.instagram.com/accounts/login/")
        time.sleep(3)
        username = self.driver.find_element_by_name("username")
        username.send_keys(USERNAME)
        password = self.driver.find_element_by_name("password")
        password.send_keys(PASSWORD)
        time.sleep(2)
        login = self.driver.find_element_by_xpath('//*[@id="loginForm"]/div/div[3]/button/div')
        login.click()

    def find_followers(self):
        time.sleep(5)
        self.driver.get("https://www.instagram.com/" + SIMILAR_ACCOUNT + "/followers")
        followers = self.driver.find_element_by_xpath('//*[@id="react-root"]/section/main/div/header/section/ul/li[2]/a')
        followers.click()
        time.sleep(1)

    def follow(self):
        all_buttons = self.driver.find_elements_by_xpath('//button[normalize-space()="Follow"]')
        modal = self.driver.find_element_by_xpath('/html/body/div[5]/div/div/div[2]')
        for button in all_buttons:
            if button.text != "Follow":
                pass
            else:
                button.click()
                time.sleep(2)
        time.sleep(10)
        self.driver.execute_script("arguments[0].scrollTop = arguments[0].scrollHeight", modal)
        self.follow()

bot = InstaFollower(CHROME_DRIVER_PATH)
bot.login()
bot.find_followers()
bot.follow()