Selenium Python3 - Unable to find element by its name - python

The code of the HTML element is as follows:
<input aria-label="Phone number, username, or email" aria-required="true" autocapitalize="none" autocorrect="off" maxlength="75" name="username" type="text" class="_2hvTZ pexuQ zyHYP" value="">
selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: [name="username"]
I get the error above when I execute this code:
from selenium.webdriver import Firefox
class Efrit:
#Initializing the bot
def __init__(self, username, password):
self.username = username # it could also be e-mail or phone number
self.password = password
#Credentials to log into Instagram:
def log(self):
driver = Firefox('/usr/local/bin')
driver.get("https://www.instagram.com/")
username_location = driver.find_element_by_name('username')
password_location = driver.find_element_by_name('password')
bot = Efrit('test, 'test')
bot.log()

As said in the comments by JaSON, the login form is not in page source and it takes time to render. You have to use wait
Explicit Wait
from selenium.webdriver import Firefox
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
class Efrit:
#Initializing the bot
def __init__(self, username, password):
self.username = username # it could also be e-mail or phone number
self.password = password
#Credentials to log into Instagram:
def log(self):
driver = Firefox('/usr/local/bin')
driver.get("https://www.instagram.com/")
delay = 6 # seconds
try:
username_location = WebDriverWait(driver, delay).until(EC.presence_of_element_located((By.NAME, 'username')))
password_location = driver.find_element_by_name('password')
print(username_location, password_location)
except TimeoutException:
print("Loading took too much time!")
driver.quit()
bot = Efrit('test', 'test')
bot.log()

You can use explicit wait:
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver.get("https://www.instagram.com/")
wait = WebDriverWait(driver, 20)
wait.until(EC.visibility_of_element_located((SelectBy.CSS, "/input[name=username]")))
username_location = driver.find_element_by_css_selector('input[name=username]')
password_location = driver.find_element_by_css_selector('input[name=password]')
To wait for login button use element_to_be_clickable
wait.until(EC.element_to_be_clickable(
(SelectBy.CSS_SELECTOR, ".sqdOP.L3NKy.y3zKF")))
login = driver.find_element_by_css_selector(".sqdOP.L3NKy.y3zKF")
login.click()
You can also set the global implicit wait.
https://selenium-python.readthedocs.io/waits.html (refer to P.5.2 for instructions).

Related

Finding elements using selenium in python

I am trying to find and then fill in the username and password of Instagrams login page using:
from selenium.webdriver.common.keys import Keys
import os
from selenium import webdriver
dirname = os.path.dirname(__file__)
filename = os.path.join(dirname, 'Chromedriver')
driver = webdriver.Chrome(executable_path = filename)
driver.get("https://www.instagram.com")
username = driver.find_element_by_name("username")
password = driver.find_element_by_name("password")
username.send_keys("blankspace")
password.send_keys("blankspace")
however, I keep getting an error that it cant detect the element even though the name is correct
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"[name="username"]"}
The HTML:
<input aria-label="Phone number, username, or email" aria-required="true" autocapitalize="off" autocorrect="off" maxlength="75" name="username" type="text" class="_2hvTZ pexuQ zyHYP" value="">
You have to close the cookie consent popup first before accessing the form fields:
import os
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
dirname = os.path.dirname(__file__)
filename = os.path.join(dirname, 'Chromedriver')
driver = webdriver.Firefox()
driver.get("https://www.instagram.com")
WebDriverWait(driver, 5).until(
EC.presence_of_element_located((By.CSS_SELECTOR, "button.aOOlW.bIiDR"))
)
driver.find_element(By.CSS_SELECTOR, "button.aOOlW.bIiDR").click()
username = driver.find_element(By.NAME, "username")
password = driver.find_element(By.NAME, "password")
username.send_keys("blankspace")
password.send_keys("blankspace")
driver.close()
Also consider using the updated methods find_element():
DeprecationWarning: find_element_by_* commands are deprecated. Please use find_element() instea
I would check out Selenium documentation! Link. By going off the docs you could try the following:
username = browser.find_element(By.NAME, "username")
password = browser.find_element(By.NAME, "password")
username.send_keys("text")
password.send_keys("text")
Though I would use XPATH instead as it would be quicker:
username = browser.find_element(By.XPATH, '//[#id="loginForm"]/div/div[1]/div/label/input')
password = browser.find_element(By.XPATH, '//*[#id="loginForm"]/div/div[2]/div/label/input')
username.send_keys("text")
password.send_keys("text")
Enjoy!
The answer to anyone who cares to know is that Instagram loads in the body of the page after you get to it so you just have to add a delay before you start looking for the elements. Thats to #edd for pointing that out
driver.get("https://www.instagram.com")
time.sleep(5)
username = driver.find_element_by_name("username")
password = driver.find_element_by_name("password")
username.send_keys("blankspace")
password.send_keys("blankspace")

selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":""}

I am making a bot to sign into discord and write some stuff, although when i sign in, there is a pop up message which i have to close(click the 'X' button) to go to my desired channel. But through my code, it is not closing the pop up message, it just says
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//*[#id="app-mount"]/div[5]/div[2]/div/div/div/div[1]/div[2]/button"}
This is my code:
from selenium import webdriver
from selenium.webdriver.common import by
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time, os
class dankmemer_bot:
def __init__(self):
PATH = "C:\Program Files (x86)\chromedriver.exe"
self.driver = webdriver.Chrome(PATH)
def login(self):
driver = self.driver
driver.get('https://discord.com/channels/#me/12345678901234567')
gmail = driver.find_element_by_name('email')
gmail.send_keys('example#gmail.com')
password = driver.find_element_by_name('password')
password.send_keys(os.environ.get('password_example'))
gmail.send_keys(Keys.RETURN)
#The IMPORTANT part
def close_tab(self):
driver = self.driver
button = driver.find_element_by_xpath('/html/body/div[1]/div[5]/div[2]/div/div/div/div[1]/div[2]/button')
button.click()
try:
element = WebDriverWait(driver=10).until(
EC.presence_of_element_located((By.XPATH, '/html/body/div[1]/div[5]/div[2]/div/div/div/div[1]/div[2]/button'))
)
except:
driver.quit()
def search_for_channel(self):
driver = self.driver
search_for_dankmemer = driver.find_element_by_class_name('searchBar-6Kv8R2')
search_for_dankmemer.send_keys('dank-memer')
mybot = dankmemer_bot()
mybot.login()
mybot.close_tab()
mybot.search_for_channel()
and this is the html:
<button aria-label="Close" type="button" class="closeButton-ryIVwg close-hZ94c6 button-38aScr lookBlank-3eh9lL colorBrand-3pXr91 grow-q77ONN"><div class="contents-18-Yxp"><svg class="closeIcon-150W3V" aria-hidden="false" width="24" height="24" viewBox="0 0 24 24"><path fill="currentColor" d="M18.4 4L12 10.4L5.6 4L4 5.6L10.4 12L4 18.4L5.6 20L12 13.6L18.4 20L20 18.4L13.6 12L20 5.6L18.4 4Z"></path></svg></div></button>
To Close pop up or alert we can use this code
driver.switch_to_alert()
Then write the code to close the pop up
For example:
driver.find_element_by_xpath('xpath')

Why isn't the webpage loding while scraping linkedin?

In this code I am trying to scrape a Linkedin profile using Selenium
but the driver is not able to load the page I guess IP has been
blocked and I am new to the concept of proxy rotating or any concept
that is used in such cases. It would be a great help if you could help
me understand how this is done.
from selenium import webdriver
import time
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome(executable_path=r'C:\Users\chromedriver.exe')
def linkedin_login():
global driver
options = webdriver.ChromeOptions()
options.add_argument("start-maximized")
options.add_experimental_option('excludeswitches', ['enable-automation'])
options.add_experimental_option("detach", True)
try:
driver.get('https://www.linkedin.com/login')
username = 'username'
password = 'password'
WebDriverWait(driver, 30).until(EC.element_to_be_clickable((By.ID, 'username'))).send_keys(username)
driver.find_element_by_id('password').send_keys(password)
driver.find_element_by_class_name('btn__primary--large from__button--floating').click()
time.sleep(8)
except ImportError:
print('Closing')
def search_profiles():
search_profile = input('What profile do you want to search?')
search_profile = search_profile.split()
search = search_profile[0] + "%20" + search_profile[1]
The "Sign In" button's class name is incorrect, specifically is missing a dot(.)
Instead of:
driver.find_element_by_class_name('btn__primary--large from__button--floating').click()
Use:
driver.find_element_by_class_name('btn__primary--large.from__button--floating').click()
That will click the button.
Also, if you run the code you shared, you are calling the webdriver but not calling your function.
I tested the below code and worked fine (remember to update your path and LinkedIn credentials):
from selenium import webdriver
import time
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome(executable_path='/home/armentaahumada/Downloads/chromedriver')
def linkedin_login():
global driver
options = webdriver.ChromeOptions()
options.add_argument("start-maximized")
options.add_experimental_option('excludeswitches', ['enable-automation'])
options.add_experimental_option("detach", True)
try:
driver.get('https://www.linkedin.com/login')
username = 'username'
password = 'password'
WebDriverWait(driver, 30).until(EC.element_to_be_clickable((By.ID, 'username'))).send_keys(username)
driver.find_element_by_id('password').send_keys(password)
driver.find_element_by_class_name('btn__primary--large.from__button--floating').click()
time.sleep(8)
except ImportError:
print('Closing')
def search_profiles():
search_profile = input('What profile do you want to search?')
search_profile = search_profile.split()
search = search_profile[0] + "%20" + search_profile[1]
linkedin_login()

Element not interactable (Input field) when sending keys

I'm trying to login to this website using Selenium:
https://www.gamingintelligence.com/my-account
I've done this so far:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
username = 'my_user'
password = 'my_pass'
chrome_options = Options()
chrome_options.add_argument("--incognito")
driver = webdriver.Chrome(chrome_options=chrome_options, executable_path='./chromedriver')
url = "https://www.gamingintelligence.com/my-account"
driver.get(url)
driver.find_element_by_xpath('//*[#id="nav-login-tab"]').click()
driver.find_element_by_xpath('//*[#id="username"]').send_keys(username)
But I get this error:
ElementNotInteractableException: Message: element not interactable
The HTML is:
<input type="text" class="form-control xh-highlight" name="username"
id="username" autocomplete="username" value="" required="" style="background-
image: ...">
To solve exactly this issue you'll need to add explicit wait:
import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
username = 'my_user'
password = 'my_pass'
chrome_options = Options()
chrome_options.add_argument("--incognito")
driver = webdriver.Chrome(chrome_options=chrome_options, executable_path='/snap/bin/chromium.chromedriver')
url = "https://www.gamingintelligence.com/my-account"
driver.get(url)
wait = WebDriverWait(driver, 20)
wait.until(EC.element_to_be_clickable((By.XPATH, '//*[#id="nav-login-tab"]')))
driver.find_element_by_xpath('//*[#id="nav-login-tab"]').click()
field = wait.until(EC.element_to_be_clickable((By.XPATH, '//*[#id="username"]')))
driver.find_element_by_xpath('//*[#id="username"]').send_keys(username)
Or, you can set implicit wait, just after driver.get():
driver.implicitly_wait(15)
First way is more reliable.

Selenium send_keys says: Element is not currently interactable and may not be manipulated

I want to send key to a login form. the problem is that an error says:
Element is not currently interactable and may not be manipulated
This is my code:
url = 'http://tx3.travian.ir'
hero_url = 'http://tx3.travian.ir/spieler.php?uid=19865'
driver = webdriver.PhantomJS(r'phantomjs/bin/phantomjs')
try:
driver.set_page_load_timeout(15)
driver.get(url)
except:
Debug.PrintException()
wait = WebDriverWait(driver, 10)
username = wait.until(EC.visibility_of_element_located((By.NAME, 'name')))
password = wait.until(EC.visibility_of_element_located((By.NAME, 'password')))
username.send_keys('user')
password.send_keys('pass')
login_btn = driver.find_element_by_id('s1')
login_btn.click()
driver.get(hero_url)
driver.close()
What's wrong?
You defined WebDriverWait but you never use it
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions
wait = WebDriverWait(driver, 10)
username = wait.until(expected_conditions.visibility_of_element_located((By.NAME, 'name')))
I have used your own code and made 5 adjustments as follows:
Set the window_size to (1400,1000)
For username field instead of (By.NAME, 'name') I have used (By.XPATH, "//input[#name='name']")
For password field instead of (By.NAME, 'password') I have used (By.XPATH, "//input[#name='password']")
For login_btn button instead of find_element_by_id('s1') I have used find_element_by_xpath("//button[#id='s1']")
Finally, I have added a print statement to confirm the End of Script.
Here is the working code block:
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
url = 'http://tx3.travian.ir'
hero_url = 'http://tx3.travian.ir/spieler.php?uid=19865'
driver = webdriver.PhantomJS(executable_path=r'C:\\Utility\\phantomjs-2.1.1-windows\\bin\\phantomjs.exe')
try:
driver.set_page_load_timeout(15)
driver.set_window_size(1400,1000)
driver.get(url)
except:
# Debug.PrintException()
pass
wait = WebDriverWait(driver, 10)
username = wait.until(EC.element_to_be_clickable((By.XPATH, "//input[#name='name']")))
password = wait.until(EC.element_to_be_clickable((By.XPATH, "//input[#name='password']")))
username.send_keys('user')
password.send_keys('pass')
login_btn = driver.find_element_by_xpath("//button[#id='s1']")
login_btn.click()
driver.get(hero_url)
driver.close()
print("Driver Closed")
This code block prints the following on my console:
Driver Closed
Try click at input box and then Enter text.
sometimes, thread.sleep(ms) in java also helps.

Categories