python/slenium, wait till class value in html line changes - python

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

Related

Selenium - is not reachable by keyboard python

birthday = driver.find_element_by_name("date_of_birth_day")
birthday.send_keys("11092000")
birthday.send_keys(Keys.RETURN)
When I run this code I get
"input class=" web-date-input__form-input" name="date_of_birth_day" type="number"> is not
reachable by keyboard"
but the element is "Keyboard-Focusable"
input class="web-date-input__form-input" type="number" placeholder="DD" autocomplete="off" maxlength="2" max="31" min="1" name="date_of_birth_day" tabindex="3" data-testid="input-birthday-day" value="11".
I do not understand the problem
I found a way to solve it by just sending the keys without an element, I am not sure it will work in any case but it worked for me.
import actions = ActionChains(driver)
actions.send_keys("11092000")
actions.send_keys(Keys.RETURN)
actions.perform()

Radio Button Click with Requests

I have been working on a web scraping script that gets past the login page but I can't find a way to get this radio button selected as the script attempts to login.
Here's the button:
<input type="radio" name="UserType" id="UserType" value="PARENTSWEB-PARENT" tabindex="4">
When it is clicked it looks like this:
<input type="radio" name="UserType" id="UserType" value="PARENTSWEB-PARENT" tabindex="4" checked="checked">
I am using a dictionary to submit the username and password but not sure how to add the button functionality into it.
Dict:
payload={
'username':USERNAME,
'password':PASSWORD,
'DistrictCode':DistCode,
'PARENTSWEB-STUDENT':'checked'
}
I am using the requests library and lxml to submit and look at the data. But if there is a better library or another one I can also use I'm open to anything.

selenium in python browser.find_element_by_name('submit').click() not working

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')

Python Send Keys Function In Selenium

I m trying to send keys using selenium by send keys function to fill some data but unfortunately code is not working.Here is HTML CODE where i want to fill some data and Python selenium code below.What can be the problem in my code
<input type="text" style="margin-bottom:16px" value="My New Sketch" autocomplete="on" maxlength="60" minlenght="2" required="required" class="required" tabindex="1" name="title">
browser.find_element_by_css_selector(".required").send_keys(Keys.BACKSPACE)
time.sleep(5)
browser.find_element_by_css_selector(".required").send_keys("UserName");
time.sleep(8)
I am not sure why back space is used here but to clear input fields can use clear, in java
driver.findElement(By.cssSelector(".required")).clear();
if sendkeys does not works, some time initial click then sendkeys work well
driver.findElement(By.cssSelector(".required")).click();
driver.findElement(By.cssSelector(".required")).sendKeys("data here");
I hope required wait is provided.
Thank You,
Murali

Interacting with website forms

I'm trying to connect to a school url and automate the process with selenium. Originally I tried using splinter, but ran into similar problems. I can't seem to be able to interact with the username and password fields. I realized a little ways in that it is an iframe that I need to interact with. Currently I have:
import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.Firefox()
driver.get("https://my.oregonstate.edu/webapps/login/")
driver.switch_to.frame('Content') #I tried contentFrame and content as well
loginid = driver.find_elements_by_id('user_id')
loginid.send_keys("***")
passwd = driver.find_elements_by_id('password')
passwd.send_keys("***")
sub = driver.find_elements_by_id('login')
sub.click()
time.sleep(5)
driver.close()
Here is the HTML that I am trying to interact with:
The Website: https://my.oregonstate.edu/webapps/portal/frameset.jsp
The iframe:
<iframe id="contentFrame" style="height: 593px;" name="content" title="Content" src="/webapps/portal/execute/tabs/tabAction?tab_tab_group_id=_1_1" frameborder="0"></iframe>
The forms:
Username:
<input name="user_id" id="user_id" size="25" maxlength="50" type="text">
Password:
<input size="25" name="password" id="password" autocomplete="off" type="password">
It seems that selenium can locate the elements just find, but I am unable to input any information into these fields, I got the error 'List object has no attribute'. When I realized it was the iframe I tried to navigate into that but it says 'Unable to locate frame: Content'. Is there another iframe that I am missing? Or something obvious? This is my first time here so sorry if I messed something up with the code linking.
Thanks for the help.
driver.switch_to.frame() takes frame's id or name, where your frame have id = contentFrame and name = content. (The reason they didn't work is probably because of a different issue, read through please)
First, please try use either one of them, not Content (which has upper case C).
Once you have fixed the issue above, there will be another error in your code.
loginid = driver.find_elements_by_id('user_id')
loginid.send_keys("***")
driver.find_elements_by_id finds all matching elements, which is a list. So you can't use send_keys. Please use driver.find_element_by_id('user_id').
Here is the code I tested working.
from selenium import webdriver
driver = webdriver.Firefox()
driver.get("https://my.oregonstate.edu/webapps/login/")
driver.switch_to.frame('content') # all lower case to match your actual frame name
loginid = driver.find_element_by_id('user_id')
loginid.send_keys("***")
passwd = driver.find_element_by_id('password')
passwd.send_keys("***")
Regarding issue in your following comments
from selenium import webdriver
driver = webdriver.Firefox()
driver.get("https://my.oregonstate.edu/webapps/login/?action=relogin")
loginid = driver.find_element_by_id('user_id')
loginid.send_keys("***")
passwd = driver.find_element_by_id('password')
passwd.send_keys("***")
driver.find_element_by_css_selector('.submit.button-1').click()

Categories