I'm trying to login to a this website: https://advertising.flipkart.com/
I need to download and automate some reports as their console is not great but its been a while since I've used selenium and I'm drawing a blank. I'm trying to use the placeholder texts inside the form to identify the login fields but can't get it to work.
Here's the HTML of the form element where I've isolated the input fields for login, password, and submit button:
<form>
<div class="styles__Row-sc-18s7njp-1 gUWbda">
<div class="styles-erqysw-0 bIQCUh">
<div class="styles__HeadingWrapper-erqysw-3 cIXYhi">
<div class="styles__Title-etu0th-0 cOPdhu"> Email address </div>
</div>
<div class="styles__TextFieldWrapper-sc-19rh1qy-6 lkVOVS">
<div class="styles__Container-sc-19rh1qy-0 dhcObI">
<input type="text"
placeholder="Enter email"
name=""
autocomplete="off"
class="styles__StyledInput-sc-19rh1qy-4 cMJHIl"
value="USERNAME GOES HERE">
</div>
</div>
</div>
</div>
<div class="styles__Row-sc-18s7njp-1 eAthVO">
<div class="styles-erqysw-0 bIQCUh">
<div class="styles__HeadingWrapper-erqysw-3 cIXYhi">
<div class="styles__Title-etu0th-0 cOPdhu"> Password </div>
</div>
<div class="styles__TextFieldWrapper-sc-19rh1qy-6 lkVOVS">
<div class="styles__Container-sc-19rh1qy-0 dhcObI">
<input type="password"
placeholder="Enter password"
name=""
autocomplete="off"
class="styles__StyledInput-sc-19rh1qy-4 cMJHIl"
value="PASSWORD GOES HERE">
<div class="styles__EyeContainer-sc-19rh1qy-3 jyEHZI"><svg width="24px" height="24px"
viewBox="0 2 24 24" color="#363D41">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g>
<g>
<path
d="M18.1660156,11.75 C18.1660156,11.8776048 18.0748707,12.1601541 17.8925781,12.5976562 C17.6464831,13.1901071 17.3639339,13.686847 17.0449219,14.0878906 C16.5162734,14.7350293 15.8828162,15.2454408 15.1445312,15.6191406 C14.2330684,16.0748721 13.1849018,16.3027344 12,16.3027344 C10.8150982,16.3027344 9.76693164,16.0748721 8.85546875,15.6191406 C8.10806918,15.2454408 7.47461197,14.7350293 6.95507812,14.0878906 C6.64518074,13.6959616 6.36718873,13.1992218 6.12109375,12.5976562 C5.92968654,12.1601541 5.83398438,11.8776048 5.83398438,11.75 C5.83398438,11.6223952 5.92968654,11.3398459 6.12109375,10.9023438 C6.36718873,10.3007782 6.64518074,9.80403842 6.95507812,9.41210938 C7.4837266,8.76497072 8.11262656,8.25455916 8.84179688,7.88085938 C9.75325977,7.42512793 10.8059836,7.19726562 12,7.19726562 C13.1940164,7.19726562 14.242183,7.42512793 15.1445312,7.88085938 C15.8919308,8.25455916 16.525388,8.76497072 17.0449219,9.41210938 C17.3639339,9.81315305 17.6419259,10.3098929 17.8789062,10.9023438 C18.0703135,11.3398459 18.1660156,11.6223952 18.1660156,11.75 Z M17.1542969,11.75 C16.9264312,11.0481736 16.6302102,10.4739606 16.265625,10.0273438 C15.8372374,9.48046602 15.3177114,9.05664213 14.7070312,8.75585938 C13.9414024,8.36393033 13.0390677,8.16796875 12,8.16796875 C10.9609323,8.16796875 10.0540403,8.36393033 9.27929688,8.75585938 C8.66861674,9.06575676 8.14909068,9.48958064 7.72070312,10.0273438 C7.35611797,10.4739606 7.05989697,11.0481736 6.83203125,11.75 C7.05989697,12.4518264 7.35611797,13.0260394 7.72070312,13.4726562 C8.14909068,14.0104194 8.66861674,14.4342432 9.27929688,14.7441406 C10.0540403,15.126955 10.9586537,15.3183594 11.9931641,15.3183594 C13.0276744,15.3183594 13.9322878,15.126955 14.7070312,14.7441406 C15.326826,14.4342432 15.8463521,14.0104194 16.265625,13.4726562 L16.2792969,13.4726562 C16.6347674,13.0260394 16.9264312,12.4518264 17.1542969,11.75 Z M13.6679688,10.0683594 C14.1328148,10.5240908 14.3652344,11.0800748 14.3652344,11.7363281 C14.3652344,12.3925814 14.1350934,12.9508441 13.6748047,13.4111328 C13.2145159,13.8714216 12.6562533,14.1015625 12,14.1015625 C11.3437467,14.1015625 10.7854841,13.8714216 10.3251953,13.4111328 C9.86490655,12.9508441 9.63476562,12.3925814 9.63476562,11.7363281 C9.63476562,11.0800748 9.86490655,10.5218122 10.3251953,10.0615234 C10.7854841,9.60123468 11.3437467,9.37109375 12,9.37109375 C12.6562533,9.37109375 13.2122373,9.6035133 13.6679688,10.0683594 Z M12.984375,10.7519531 C12.7109361,10.4785143 12.3828144,10.3417969 12,10.3417969 C11.6171856,10.3417969 11.2890639,10.4785143 11.015625,10.7519531 C10.7421861,11.025392 10.6054688,11.3535137 10.6054688,11.7363281 C10.6054688,12.1191425 10.7421861,12.4472643 11.015625,12.7207031 C11.2890639,12.994142 11.6171856,13.1308594 12,13.1308594 C12.3828144,13.1308594 12.7109361,12.994142 12.984375,12.7207031 C13.2578139,12.4472643 13.3945312,12.1191425 13.3945312,11.7363281 C13.3945312,11.3535137 13.2578139,11.025392 12.984375,10.7519531 Z"
fill="#363D41" fill-rule="nonzero"></path>
</g>
</g>
</g>
</svg></div>
</div>
</div>
</div>
<div class="styles__ForgetPassWrapper-fg24yr-1 eqzIXq"><a href="/forgot-password"
class="styles__Anchor-sc-5941cr-2 kYQwHs">
<div class="styles__TextContainer-sc-5941cr-0 cCBwan">Forgot Password?</div>
</a></div>
</div>
<div class="styles__Row-sc-18s7njp-1 gUWbda">
<div class="styles__Row-sc-18s7njp-1 gUWbda">
<button type="submit"
class="styles__DefaultButton-sc-5941cr-1 hHuXf">
<div class="styles__TextContainer-sc-5941cr-0 cCBwan">Login</div>
</button>
</div>
<div class="styles__BoxContentCenter-sc-18s7njp-3 kqkvB">
<div class="styles__Label-sc-18s7njp-9 jIhEMq"> Do not have an account? </div>
<div class="styles__Row-sc-18s7njp-1 ncyfJ"><a href="/register" class="styles__Anchor-sc-5941cr-2 kYQwHs">
<div class="styles__TextContainer-sc-5941cr-0 cCBwan">Register now</div>
</a></div>
</div>
</div>
</form>
This is the current code I have.
# import selenium module
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
from selenium.common.exceptions import TimeoutException
# Login Information
url = "https://advertising.flipkart.com/"
login_id = "USERNAME"
login_password = "PASSWORD"
# Start the session
wd = webdriver.Chrome('./chromedriver')
def login(url, login_id, login_password):
""" This function will login to the website
parameters:
url: url of the website
login_id: login id of the user
login_password: password of the user
returns:
None
"""
# Open the website
wd.get(url)
# Find the input box with placeholder text "Enter email" and enter the login id
wd.find_element_by_xpath("//input[#placeholder='Enter email']").send_keys(login_id)
# Find the input box with placeholder text "Enter password" and enter the password
wd.find_element_by_xpath("//input[#placeholder='Enter password']").send_keys(login_password)
login(url, login_id, login_password)
First, you are using deprecated syntax: find_element_by_* was replaced with find_element(By.*...). The following is a correct way of logging into that website (you can adapt it to your own setup, just make sure you observe the imports, and the part after defining the browser/driver):
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
chrome_options = Options()
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument('disable-notifications')
chrome_options.add_argument("window-size=1280,720")
webdriver_service = Service("chromedriver/chromedriver") ## path to where you saved chromedriver binary
browser = webdriver.Chrome(service=webdriver_service, options=chrome_options)
url = 'https://advertising.flipkart.com/'
browser.get(url)
WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'input[placeholder="Enter email"]'))).send_keys('username#email.com')
WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'input[placeholder="Enter password"]'))).send_keys('password')
print('wrote credentials')
WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'button[type="submit"]'))).click()
print('clicked submit button')
Selenium documentation can be found at https://www.selenium.dev/documentation/
If you were to use inspect element, most browsers allow you to right click on the HTML element (the input fields in this case), and copy the XPath. So for example, for email it would be:
wd.find_element_by_xpath('//*[#id="app"]/div[1]/div[1]/div/div[2]/div/div[2]/form/div[1]/div/div[2]/div/input').send_keys(login_id)
This is not a perfect solution, but since you don't have an id or class, its one of the few solutions available. The biggest downside of this would be if the layout of the page was changed, at which point the XPath would change as well, meaning that you would have to update your script with the new XPath. However, if you only plan to use the script for yourself, this shouldn't be much of a problem.
This question already has answers here:
What is the difference between "find_element_by_name('name')" and "find_element(By.NAME, 'name')"?
(2 answers)
Closed last year.
I'm creating a program that will help students track their marks, for that I need to web scrap the site where all our grades are stored. The idea was to automate the login and then there will be a separate script that will get the information that I need. I have trouble with automated login, because there is no input field and button ID. All I could find was names input fields and class for the button.
browser = webdriver.Chrome()
browser.get(("https://www.the-site.com/"))
usernameStr = "myUsername"
passwordStr = "myPassword"
username = browser.find_element("UserName")
username.send_keys(usernameStr)
password = browser.find_element("Password")
password.send_keys(passwordStr)
nextButton = browser.find_element("btn btn-default")
nextButton.click()
This is the error that I get:
selenium.common.exceptions.InvalidArgumentException: Message: invalid argument: invalid locator
Here's the HTML for the input fields and button:
<form action="https://my.e-klase.lv?v=15" method="post" autocomplete="off">
<div class="form-group relative">
<input type="text" class="form-control" placeholder="Lietotājvārds"
autocomplete="off"
autocorrect="off"
autocapitalize="off"
spellcheck="false" name="UserName"
value="">
<div class="dummy-placeholder">Lietotājvārds</div>
</div>
<div class="form-group relative">
<input type="private" class="form-control upass"
placeholder="Parole"
autocomplete="off"
autocorrect="off"
autocapitalize="off"
name="Password">
<div class="dummy-placeholder">Parole</div>
</div>
<button type="submit" class="btn btn-default">
<span class="progress"></span>
<span class="content">Pieslēgties</span>
</button>
</form>
You can locate the elements based on any their unique attributes.
It can be id, class name(s), name and any other attribute values.
To give you more specific answer we need to see that web page elements HTML.
UPD
According to your HTML you can use the following locators:
browser = webdriver.Chrome()
browser.get(("https://www.the-site.com/"))
usernameStr = "myUsername"
passwordStr = "myPassword"
time.sleep(5)
username = browser.find_element_by_xpath("//input[#name='UserName']")
username.send_keys(usernameStr)
password = browser.find_element_by_xpath("//input[#name='Password']")
password.send_keys(passwordStr)
nextButton = browser.find_element_by_xpath("//button[#type='submit']")
nextButton.click()
This should basically work, but you should use ExpectedConditions explicit wait in order to wait for the page loaded
find_element()
find_element() finds an element given a By strategy and a locator.
You code was missing the By strategy and locator. Hence you see the error:
selenium.common.exceptions.InvalidArgumentException: Message: invalid argument: invalid locator
This usecase
As per the html you have shared, to fill in the UserName and Password field ideally you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
browser = webdriver.Chrome()
browser.get(("https://www.the-site.com/"))
WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.NAME, "UserName"))).send_keys("myUsername")
browser.find_element(By.NAME, "Password").send_keys("myPassword")
browser.find_element(By.XPATH, "//button[#class='btn btn-default']//span[text()='Pieslēgties']").click()
I'm trying to get a checkmark on "Minutes (1993-Present)" from the federal reserve's document filter page with selenium.
https://www.federalreserve.gov/monetarypolicy/materials/
This is my code. I have tried the following ways, I keep get "Message: no such element: Unable to locate element: Unable to locate element"
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
from selenium.webdriver import ActionChains
import time
PATH = "C:\Program Files (x86)\chromedriver.exe"
driver = webdriver.Chrome(PATH)
driver.get("https://www.federalreserve.gov/monetarypolicy/materials/")
link = driver.find_element_by_xpath('//*[#id="article"]/app-root/div/ng-component/div[1]/div/div/form/app-doc-types/div[2]/div/div/div[7]/label/input').click()
link = driver.find_element_by_xpath("//div[#class='form-group']/div/div[7]/label/input[contains(text(), 'Minutes (1993-Present)')]").click()
link = driver.find_element_by_css_selector('div.form-group div:nth-child(7) label input').click()
I sliced some parts of the HTML below.
<app-doc-types><div class="eventSearch__label">
<p class="form-control-static">
<strong><legend class="ng-binding">Type:</legend></strong>
</p>
</div>
<div class="eventSearch__inputs">
<div class="form-group">
<div class="row">
<div class="col-lg-6">
<label>
<input type="checkbox" class="ng-untouched ng-pristine ng-valid">
Agendas
</label>
</div><div class="col-lg-6">
<label>
<input type="checkbox" class="ng-untouched ng-pristine ng-valid">
Beige Books/Redbooks
</label>
</div><div class="col-lg-6">
<label>
<input type="checkbox" class="ng-untouched ng-pristine ng-valid">
Bluebooks
</label>
</div><div class="col-lg-6">
<label>
<input type="checkbox" class="ng-untouched ng-pristine ng-valid">
Chairman's FOMC Press Conferences
</label>
</div><div class="col-lg-6">
<label>
<input type="checkbox" class="ng-untouched ng-pristine ng-valid">
Greenbooks
</label>
</div><div class="col-lg-6">
<label>
<input type="checkbox" class="ng-untouched ng-pristine ng-valid">
Memos
</label>
</div><div class="col-lg-6">
<label>
<input type="checkbox" class="ng-valid ng-dirty ng-touched">
Minutes (1993-Present)
</label>
</div><!---->
</div>
</div>
</div>
</app-doc-types>
It takes some time for website to load. I added time.sleep(2) after opening the webpage with driver.
Your first XPath should work, however it's extremely dependent on the structure of the page, therefore it may not work due to a little modification in the HTML structure of the page.
Second XPath won't work, and actually you do not need to add text() check to the end of your path. This should work:
//div[#class='form-group']/div/div[7]/label/input
CSS Selector path should work, however your css path can be easily simplified. Check my solution below:
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
from selenium.webdriver import ActionChains
import time
driver = webdriver.Chrome()
driver.get("https://www.federalreserve.gov/monetarypolicy/materials/")
time.sleep(2)
link = driver.find_element_by_css_selector('.col-lg-6:nth-of-type(7) input').click()
Alternatively, you can use an explicit wait.
driver.get("https://www.federalreserve.gov/monetarypolicy/materials/")
element = WebDriverWait(driver , 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR , '.col-lg-6:nth-of-type(7) input')))
element.click()
you can use playwright
import asyncio
from playwright.async_api import async_playwright
async def run(playwright):
chromium = playwright.chromium # or "firefox" or "webkit".
browser = await chromium.launch()
page = await browser.new_page()
await page.goto("https://www.federalreserve.gov/monetarypolicy/materials/")
await page.click('xpath=/html/body/div[3]/div[2]/div[2]/app-root/div/ng-component/div[1]/div/div/form/app-doc-types/div[2]/div/div/div[7]/label/input')
await browser.close()
async def main():
async with async_playwright() as playwright:
await run(playwright)
asyncio.run(main())
I am using python with selenium to automate some process but I am having problems to click a radio button. This is the situation:
Code:
<div class="cart">
<form method="post" id="pmntFrm" name="chsPmntRt" action="/cart" class="form-validate">
<fieldset>
<div class="payment-field">
<input onchange="load('payment', 1)" type="radio" name="paymentmethod_id" id="payment_id_1" value="123">
<label for="payment_id_1" class="">
//foo
</label>
<input onchange="load('payment', 2)" type="radio" name="paymentmethod_id" id="payment_id_2" value="456">
<label for="payment_id_2" class="">
//foo
</label>
</div>
</fieldset>
</form>
</div>
I have tried click on it using:
driver.find_element_by_xpath(".//input[#type='radio' and #value='1']").click()
and I receive this error Message=Message: element not interactable
Also I read in other thread that maybe the problem is that the fieldset is in a different but is not.
I really apreciate if someone can help me with this topic.
Thank you and have a nice day!
To wait for the element to be clickable induce a webdriver wait and then click. Also don't use . it's for child elements not root driver.
wait = WebDriverWait(driver, 10)
wait.until(EC.element_to_be_clickable((By.XPATH,"//input[#type='radio' and #value='1']"))).click()
Or the label
wait.until(EC.element_to_be_clickable((By.XPATH,"//label[#for='payment_id_1']"))).click()
Import
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
I've been trying to reference the two inputs in the following HTML code using Selenium's get_element_by_...() with the purpose of automatically entering a username and password into the fields. I'm running into trouble with accessing the proper HTML elements.
<body>
<div id="app">
<div>
<section id="root" class="page-login">
<section class="main">
<section class="auth-page register-fill">
<div class="page-center">
<a class="switch-lang" href="/cn/login">cn</a>
<a class="btn-back" href="en/login">
<span class="isvg loaded">
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 24 24">
<path class="a" d="M0,0H24V24H0Z"></path>
<path class="b" d="M20,11H7.83l5.59-5.59L12,4,4,12l8,8,1.41-1.41L7.83,13H20Z"></path>
</svg>
</span>
</a>
<div class="auth-page-wrapper">
<h1 class="auth-page-title">Welcome Back</h1>
<h2 class="auth-page-subtitle">Login to get started</h2>
<div class="auth-page-fields">
<div class="custom-input">
<input type="text" placeholder="Email">
<label>Email</label>
</div>
<div class="custom-input custom-input-password">
<a class="forgot-link" href="en/forgot-password">Forgot Password?</a>
<input type="password" placeholder="Minimum 6 characters">
<label>Password</label>
</div>
</div>
Note: The HTML may have some mistakes, I just quickly formatted it, but the mistakes should not affect the question.
Tried:
I've tried using all the different functions of the 'form find_element_by_...' and referencing a variety of things, but all tend to return "no such element: unable to locate element ..."
I've done absolute xpaths, relative xpaths, css selectors, ids, and combinations of these.
Some examples:
username = browser.find_element_by_xpath("//input[1]")
username = browser.find_element_by_xpath("//html/body/div/div/section/.../input")
The error begins at this point in the path:
username = browser.find_element_by_xpath("//html/body/div/div/section")
I'm likely making a stupid mistake, so sorry if this question isn't great, but other StackOverflow answers all have ids and such that are referable on the input field. (eg. <input id=username ...>)
To identify the Email field you have to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:
Using CSS_SELECTOR:
username = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input[placeholder='Email']")))
Using XPATH:
username = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[#placeholder='Email']")))
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
There are more than one way to do this. But, this should work browser.find_element_by_css_selector('[placeholder="Email"]')