I am trying to automate the login procedure with Selenium in Firefox with Python.
That's how a login button looks like in HTML:
<td>
<input name="cmd" value="lg" type="hidden">
<input src="ok.png" style="border-style: none;" type="image">
</td>
I have tried a following method:
loginButton = driver.find_elements_by_xpath("//input[#name='cmd' and #value='lg']")[0]
loginButton.click()
It returns the following exception with an empty message.
"selenium.common.exceptions.ElementNotInteractableException: Message: "
This method returns
"Message: Element is not visible"
loginButton = driver.find_element_by_name("cmd")
loginButton.send_keys(Keys.RETURN)
Could you please explain what I am missing?
If you want to click on input next to hidden, try
loginButton = driver.find_element_by_xpath("//input[#src='ok.png']")
# loginButton = driver.find_element_by_xpath("//input[#name='cmd' and #value='lg']/following-sibling::input")
loginButton.click()
Related
Trying to write a webscraper but I need to get into a website that requires an account. I'm going through 2 factor authentication to get in as that felt more secure than by username and password but I can't get Selenium to find the input for the 2fa code.
I tried every type of locater available and none of those work. The website does not appear to have a frame so I don't think that's the issue. I'm using an implicit wait as well so I believe the webpage has enough time to load.
I'm not really sure what I'm doing wrong at this point. I just keep getting an Unable to locate element error
Here the html for the item
<input class="sc-jzJRlG hxEkIM sc-VigVT gupvKM" data-testid="security-code" id="security-code" value="" autocomplete="off" autocorrect="off" spellcheck="false" maxlength="255" type="password" data-reactid=".0.1.0.2.1.1.0.0.1.0">
and my code
driver.implicitly_wait(10)
codeInput = driver.find_element(By.XPATH, '/html/body/div/div/div[2]/div[1]/div[3]/div/form/div/div[1]/div[2]/input')
enterButton = driver.find_element(By.XPATH, '/html/body/div/div/div[2]/div[1]/div[3]/div/form/div/div[2]/div/button')
codeInput.send_keys('123456')
action.click(enterButton)
action.perform()
and the Stacktrace
Message=Message: Unable to locate element: /html/body/div/div/div[2]/div[1]/div[3]/div/form/div/div[1]/div[2]/input
Stacktrace:
RemoteError#chrome://remote/content/shared/RemoteError.jsm:12:1
WebDriverError#chrome://remote/content/shared/webdriver/Errors.jsm:192:5
NoSuchElementError#chrome://remote/content/shared/webdriver/Errors.jsm:404:5
element.find/</<#chrome://remote/content/marionette/element.js:291:16
Source=C:\Users\user\source\repos\WebScraper\WebScraper\webscraper.py
StackTrace:
File "C:\Users\user\source\repos\WebScraper\WebScraper\webscraper.py", line 27, in <module> (Current frame)
codeInput = driver.find_element(By.XPATH, '/html/body/div/div/div[2]/div[1]/div[3]/div/form/div/div[1]/div[2]/input')
Edit: I figured it out, it would be:
wait = WebDriverWait(driver, 10)
element = wait.until(element_has_css_class((By.ID, 'mail'), "emailbox-input opentip"))
I am using selenium to create an email verifyer but I have to wait till a certain element loads, which is the input button, at the beginning its html is:
<input id="mail" type="text" onclick="select(this);" data-original-title="Your Temporary Email Address" data-placement="bottom" data-value="Loading" class="emailbox-input opentip disabledText" readonly="">
and then the class changes from class="emailbox-input opentip disabledText" to class="emailbox-input opentip":
<input id="mail" type="text" onclick="select(this);" data-original-title="Your Temporary Email Address" data-placement="bottom" data-value="Loading" class="emailbox-input opentip" readonly="">
I want the code to wait for this specific class change, how can I achieve that?
site: https://temp-mail.org/en/
Thanks!
Selenium sdk for python has Waits that can be used for this use case. There is even example with your specific use-case in official documentation:
https://selenium-python.readthedocs.io/waits.html. See: Custom Wait Conditions
I am trying to access the following HTML checkbox for a button click:
<input type="checkbox" data-ng-value="sf.name" data-ng-model="sf.checked" ng-click="ec.onStateFilterChanged(sf)" title="Select a state" class="ng-untouched ng-valid ng-dirty ng-valid-parse" value="Arizona">
using:
state = driver.find_element_by_xpath("input[#type='checkbox']").click()
but keep getting error:
selenium.common.exceptions.NoSuchElementException: Message:
what might be the element path I am looking for in order to select the checkbox?
Your xpath is most likely incorrect - you need to enter // before the element as this will find all (single slash / will work here too though as you are only trying to find one element and it will find the first match)
Try one of the following:
state = driver.find_element_by_xpath("//input[#type='checkbox']").click()
OR
state = driver.find_element_by_css_selector("input[type='checkbox']").click()
i can't find way to press button with selenium. tried to click on it by name and xpath, but it didnt worked.
this is sign in button on this site - https://account.envato.com/sign_in?to=audiojungle
this is code of button:
<input type="submit" name="commit" value="Sign in to your account" class="js-sign-in__submit e-btn--3d -color-primary -size-m -width-full h-mb2 h-mt1">
if i try to find it by x path, using - driver.find_element_by_xpath('//*[#id="sign-in-form"]/div[6]/input').click()
or using - driver.find_element_by_name('commit').click()
it comes with this problem -
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element <input type="submit" name="commit" value="Sign In"formnovalidate="formnovalidate" data-disable-with="Sign In"> is not clickable at point (789, 309). Other element would receive the click: <p style="">...</p>
i don't remember evrything i tried, but i hope you understood me. i didn't find solution in internet, so i hope you will help me, thx)
Try this:
Option 1:
wait.until(ec.visibility_of_element_located((By.XPATH,"Your xpath")
Option 2:
Check if it is not in iframe.
Option 3:
Use Action or Javascript to click on button.
Hope this helps.
I'm trying to scrape a site that needs login information, and after hours of trying to figure out why I keep getting "Login failed", I believe it is simply because the "Log in" or "Submit" button is not actually getting clicked. I realized this by saving a screenshot of the browser right when it "fails". My username and password are filled into the fields.
I've tried things like wait, elementScrollBehavior, nothing seems to work. I'd really appreciate some help with this! Code below.
def load(self):
global browser
DesiredCapabilities.PHANTOMJS["elementScrollBehavior"] = 1
#browser field
browser = webdriver.PhantomJS()
wait = WebDriverWait(browser, 10)
#browser = webdriver.Firefox()
#browser = webdriver.Chrome()
loginId = self.id
password = self.pw
browser.get('https://link.example.com')
browser.find_element_by_id('cf-login').send_keys(loginId)
browser.find_element_by_id('password').send_keys(password)
browser.find_element_by_name('submit').click()
#wait.until(EC.presence_of_element_located((By.ID, "crefli_HC_SSS_STUDENT_CENTER")))
try:
if browser.find_element_by_id('crefli_HC_SSS_STUDENT_CENTER'):
#return login status
return True
else:
return False
except:
print('element not found on page')
print(browser.current_url)
#browser.save_screenshot('~/Desktop/screen2.png')
HTML of form:
<form name="loginform" action="/oam/server/auth_cred_submit" method="post">
<div class="nonfloat-box">
Username:
<input type="text" id="cf-login" name="username" class="username inputbox" autocomplete="OFF">
</div>
<div class="float-box">
Password:
<input id="password" name="password" type="password" class="password inputbox" autocomplete="OFF">
</div>
<input type="image" src="https://www.cuny.edu/site/citizencuny/cunyfirst-login/loginbutton.jpg" onclick="javascript: return signon_validate()" alt="Submit" name="submit">
</form>
I believe I need to SOMEHOW get that bit of javascript to run. But HOW?
UPDATE: Selenium has a submit() method that automatically submits the <form> in HTML. Even using this, it does not work. As you can see in the HTML, it IS a form. At this point I do not know what else to try.
Please try this, hope it helps
from selenium.webdriver.common.keys import Keys
driver.find_element_by_name('submit').send_keys(Keys.RETURN)
(or)
driver.find_element_by_name('submit').send_keys(Keys.ENTER)
I have a feeling 'submit' is not being found by find_element_by_name. Try find_element_by_xpath(//*[#name='submit'])
HTML is needed to make a more accurate determination, but I usually use enter key to submit forms, sometimes javascript messes up the ability to submits by click and a simple enter usually does the trick
from selenium.webdriver.common.keys import Keys
def load(self):
(...)
browser.find_element_by_id('password').send_keys(password)
browser.find_element_by_id('password').send_keys(Keys.ENTER)
(...)
Otherwise, make sure you mean find_element_by_name and not find_element_by_tag_name.
Use xpath, Please try this
//input[#name='submit']
or
//input[contains(#name,'submit')AND contains(#alt,'Submit')]
You can use submit() to submit the form. It needs to be sent to the <form> tag
browser.find_element_by_id('cf-login').send_keys(loginId)
browser.find_element_by_id('password').send_keys(password)
browser.find_element_by_name('loginform').submit()
If this doesn't work you can use JavaScript click as a work around
submit = browser.find_element_by_name('submit')
browser.execute_script("arguments[0].click();", submit)
You can also try sending Enter
from selenium.webdriver.common.keys import Keys
browser.find_element_by_id('cf-login').send_keys(loginId)
password_field = browser.find_element_by_id('password')
password_field.send_keys(password)
password_field.send_keys(Keys.RETURN)
#OR
password_field.send_keys(Keys.ENTER)
When you use selenium do automatic testing or scraping ,I suggest you use the method
webdriver.find_element_by_xpath(xpathString)
because you can check the xpathwebbroser's console
Try this command on console:
$x('xpathString')