Logging into website using selenium with python - python

I am trying to use selenium to log into this website:
but it says the password and login are not visible. I looked around and saw that some people said to wait, but waiting does not seem to help. Here is my code:
# importing libraries
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import re, time, csv
driver = webdriver.Firefox()
driver.get("https://platform.openquake.org/account/login/")
driver.switch_to
driver.maximize_window
time.sleep(10)
username = driver.find_element_by_xpath("//input[#name='username']")
username.send_keys("hi there")
Error message is :
ElementNotVisibleException: Element is not currently visible and so may not be interacted with

Your XPATH actually matches two elements. The non-plural driver methods (find_element_by_XXX) return the first element they find a match for, which in this case is not the one you want.
A good debugging tool for situations like this is to use the plural forms (find_elements_by_XXX) and then see how many elements matched.
In this case, you should do what Tanu suggested and use a more restrictive XPATH:
username = driver.find_element_by_xpath("//div[#class='controls']/input[#id='id_username']")
password = driver.find_element_by_xpath("//div[#class='controls']/input[#id='id_password']")

Modify your xpath:
username = driver.find_element_by_xpath("//div[#class='controls']/input[#id='id_username']")

Related

Python: Cannot find object with Selenium

Can somebody please help me identify the Login/email, password, and LOG IN elements on this site?
https://lo12poznan.mobidziennik.pl/
I tried using multiple methods but my code couldn't detect them.
I just need the element identification...
I was able to simulate an incorrect login using this script below - if you provide the correct login and password, I think this would work
Script as been written using selenium==4.0.0b4 [ install it using pip install selenium==4.0.0b4]
import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
svc=Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=svc)
driver.maximize_window()
driver.get("https://lo12poznan.mobidziennik.pl/dziennik/")
time.sleep(5)
driver.find_element(By.ID,'login').send_keys('warsaw#polska.pl')
driver.find_element(By.ID,'haslo').send_keys('MyCryptic#PAASWORD098')
driver.find_element(By.CSS_SELECTOR,"input[type='submit']").click()
driver.quit()
CSS:
Login/e-mail [id="login"]
password [id="haslo"]
submit .btn.btn-block
With XPath style the locators are:
login input field
//input[#id='login']
password input field
//input[#id='haslo']
submit button
//input[#type='submit']
You can use other unique combinations there as well.
And you can use other approaches i.e. by css selector.
Don't forget adding some wait / delay before accessing the elements to let the page loaded before accessing elements there.
you can use find_element_by_id
id for user name is login
id for password is haslo
and for submit button, use find_by_css_selector :-
input[class*='btn-lg']
Remember, xpath usages is not prefer in automation if we happen to find ids. or css.

Python Selenium "Unable to locate element"

I am trying to use Selenium to sign up an email account automatically whenever I need to. It's just a fun learning project for me. For the life of me I don't understand why it can't find the element. This code works fine on the sign-in page but not the sign-up page. I have tried all different Selenium commands and even tried using the ID and class name. Either is says it can't locate the element or that it is not reachable by keyboard.
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
import time
options = Options()
driver = webdriver.Firefox(options=options, executable_path=r'geckodriver.exe')
driver.get("https://mail.protonmail.com/create/new?language=en")
time.sleep(10)
username_input = driver.find_element_by_id("username").send_keys("testusername")
Also here is the HTML code: https://i.imgur.com/ZaBMTzG.png
The username field is in iframe, you need to switch to iframe to make this work.
Below is the code that works fine :
driver.get("https://mail.protonmail.com/create/new?language=en")
driver.switch_to.frame(driver.find_element_by_css_selector("iframe[title='Registration form'][class='top']"))
driver.find_element_by_id("username").send_keys("some string")
read more about iframe here
learn more about how to switch to iframe/frame/framset using Python
selenium Bindings here
Update :
wait = WebDriverWait(driver, 30)
driver.get("https://mail.protonmail.com/create/new?language=en")
driver.switch_to.frame(driver.find_element_by_css_selector("iframe[title='Registration form'][class='top']"))
driver.find_element_by_id("username").send_keys("some string")
driver.switch_to.default_content()
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
sleep(5)
driver.switch_to.frame(driver.find_element_by_css_selector("iframe[title='Registration form'][class='bottom']"))
wait.until(EC.element_to_be_clickable((By.NAME, "submitBtn"))).click()
I'm not sure if I've seen enough code to diagnose, but I think the way you are defining username_input seems problematic. driver.find_element_by_id("username").send_keys("testusername") doesn't actually return anything so it seems like you are setting username_input = null.

Automating email creation on ProtonMail using (Python, Selenium)

I want to create 10 emails on ProtonMail.
I already automated half of the part, using PyAutoGui and Selenium but I want to make it like a checker because sometimes usernames are taken.
Now what I wanna do is this:
Generate Random Usernames
Check the usernames either by Selenium or another package(suggestions if you know any)
If the username is valid, a notepad will be created to save the valid usernames.
This is the concept of what I am trying to build now. I am truly sorry if I sound garbage but I legit started using Python a few days ago and it hasn't yet been a week so... I'm learning :P
I have automated the part where Selenium fills the form of ProtonMail for Sign In / Sign Up, but sometimes I get the error that the Username is already taken and I want the script to check if that error message pops up, and if it does, a "reserved code" line will be executed to fix the issue. Then, the code can continue. But, I want the script not to interfere with the "reserved code" if the element doesn't pop up.
If anyone is here just to get the code ready, here you go:
import selenium
import pyautogui
import time
from selenium import webdriver
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
#Variables
protonmail = "https://mail.protonmail.com/create/new?language=en"
username = input("Please enter your desired username for the email:")
password = input("Enter your password:")
driver = webdriver.Firefox()
time.sleep(4)
driver.get(protonmail)
time.sleep(7)
pyautogui.click(535, 501)
time.sleep(1)
pyautogui.typewrite(username)
time.sleep(2)
driver.find_element_by_xpath(
"/html[1]/body[1]/div[2]/div[1]/div[1]/div[1]/div[1]/form[1]/div[1]/div[2]/div[1]/div[1]/input[1]").send_keys(
password)
time.sleep(2)
driver.find_element_by_xpath(
"/html[1]/body[1]/div[2]/div[1]/div[1]/div[1]/div[1]/form[1]/div[1]/div[2]/div[2]/div[1]/input[1]").send_keys(
password)
time.sleep(2)
pyautogui.click(1284, 916)
time.sleep(2)
pyautogui.click(655, 762)
time.sleep(3)
You can use the request library to check if the username is valid:
import requests
URL = "https://mail.protonmail.com/api/users/available"
PARAMS = {"Name": "UsernameToCheck"}
# idk what these are but it seems like they are needed
HEADERS = {"x-pm-appversion": "Web_3.16.17",
"x-pm-apiversion": "3"}
r = requests.get(url=URL, params=PARAMS, headers=HEADERS)
if int(r.json()["Code"]) == 1000:
print("valid username")
else:
print("invalid username")
I've just checked the ProtonMail sign up page to locate the error message you are talking about. Based on your problem description, it seems like you want to proceed differently in your code based on the presence of this error message. Your code sample is a bit hard to read, because your clicks are all on absolute coordinates, rather than actual WebElements, so I'm not entirely sure what is being clicked throughout your example. This might be a good starting point for you:
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# Fill in all details on form
# Click Create Account - I assume you have already done these two steps
# Check for error message -- this is in an iframe
# switch to first iframe on the page which will contain the error message
iframe = driver.find_elements_by_xpath("//iframe[#title='Registration form']")[0]
# attempt to find the error message, catch the exception if it does not exist
try:
# Handle scenario where error message exists -- username is taken
error_message = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, "//p[text()='Username already used']")))
# better to write a handler method, instead of stuffing code into the try block
call_some_handler_method_here()
except TimeoutException:
# Handle scenario where error message does NOT exist -- meaning, username is not taken
call_some_other_handler_method_here()
This code will switch to the iframe which contains the error message for username already taken -- this is necessary for driver to locate the element. After that, induce WebDriverWait in a try / except block to check if the error message exists or not.
If the error message is present, you will end up inside the try block, where you can call a method to proceed accordingly.
If the error message is NOT present, meaning the username is not taken, you will end up in the except block, where you can call a different method to proceed accordingly (such as saving the attempted username to a file).

Enter data into input field not working with selenium

I'm making basic script for sing-in into Instagram.
I faced with this error
Code:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
browser = webdriver.Firefox()
browser.get('https://www.instagram.com/accounts/login/')
username = browser.find_element_by_name("username").send_keys('login')
Try to add
time.sleep(5)
before
username = browser.find_element_by_name("username").send_keys('login')
Might be page not fully loaded
The error reads 'Window not found. The browser window may have been closed'. It happened in line browser.find_element_by_tag_name("body"). The Instagram login page has two such elements, and you need only one of them. You should make the query more specific, for instance by making it return only the first element with the tag.

How to Pull Links from Google Search using Selenium, Python

I am trying to ask Google to pull up a query's relevant Search Links, in this case I am using Wikipedia, and then parse the urls of the first three via Selenium. So far I have only been able to do the first part, Googling. Here's my code:
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.ui import WebDriverWait # available since 2.4.0
from selenium.webdriver.support import expected_conditions as EC # available since 2.26.0
query = raw_input("What do you wish to search on Wikipedia?\n")
query = " " + query
# Create a new instance of the Firefox driver
driver = webdriver.Firefox()
# go to the google home page
driver.get("https://www.google.com/search?q=site%3Awikipedia.com&ie=utf-8&oe=utf-8")
# the page is ajaxy so the title is originally this:
print driver.title
# find the element that's name attribute is q (the google search box)
inputElement = driver.find_element_by_name("q")
# type in the search
inputElement.send_keys(query)
# submit the form (although google automatically searches now without submitting)
inputElement.submit()
try:
# we have to wait for the page to refresh, the last thing that seems to be updated is the title
# You should see "cheese! - Google Search"
print driver.title
driver.find_element_by_xpath("//h3[contains(text(),'Wikipedia')]").click()
finally:
driver.quit()
I am trying to use the example from Selenium's documentation, so please excuse the comments and, at times, unnecessary code.
The line of code I'm having trouble with is:
driver.find_element_by_xpath("//h3[contains(text(),'Wikipedia')]").click()
What I'm attempting to do is obtain the relevant Wikipedia link, or, more specifically, the link that the H3 'r' path directs to.
Here's a picture of a Google page that I'm describing.
In this instance, I wish to pull the link http://en.wikipedia.com/wiki/salary
Sorry for the wall of text, I'm trying to be as specific as possible. Anyways, thank you for the assistance in advance.
Best Regards!
The problem is that this XPath is not correct - there is an a element that has "Wikipedia" inside the text, not the h3 element. Fix it:
driver.find_element_by_xpath("//a[contains(text(), 'Wikipedia')]").click()
You can even go further and simplify it using:
driver.find_element_by_partial_link_text("Wikipedia").click()

Categories