Event Click Element not interactable - python-3.x

.Running my Selenium Script
I got the error:
**selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable**
What am I doing wrong?
CODE:
oCheckBox = browser.find_element_by_css_selector("input[value='para-mim']")
oCheckBox.click()
HTML
<input type="radio" name="para-quem" id="para-mim" value="para-mim">

Try this:
browser.find_element_by_xpath("//option[#value='para-mim']").click()

Try use .execute_script:
oCheckBox = browser.find_element_by_css_selector("input[value='para-mim']")
browser.execute_script("arguments[0].click();", oCheckBox)
Or use ActionChains:
from selenium.webdriver import ActionChains
oCheckBox = browser.find_element_by_css_selector("input[value='para-mim']")
action = ActionChains(browser)
action.move_to_element(oCheckBox).click(oCheckBox).perform()

Related

How do you find a url from a input button (web scraping)

I'm webscraping a asp.net website, and there is a input button that links to a page I need. I'm wondering how I can get the url to the site without using automation like Selenium.
Note: I don't need to scrape the actual page, the url contains all the info I need.
This is the code I used to get to the website but I don't know where to start with scraping the button url:
select_session_url = 'http://alisondb.legislature.state.al.us/Alison/SelectSession.aspx'
session = requests.Session()
session_payload = {"__EVENTTARGET":"ctl00$ContentPlaceHolder1$gvSessions", "__EVENTARGUMENT": "$3"}
session.post(select_session_url, session_payload, headers)
senate_payload = {"__EVENTTARGET":"ctl00$ContentPlaceHolder1$btnSenate", "__EVENTARGUMENT": "Senate"}
session.post('http://alisondb.legislature.state.al.us/Alison/SessPrefiledBills.aspx', senate_payload, headers)
page = session.get('http://alisondb.legislature.state.al.us/Alison/SESSBillsList.aspx?SELECTEDDAY=1:2019-03-05&BODY=1753&READINGTYPE=R1&READINGCODE=B&PREFILED=Y')
member_soup = BeautifulSoup(page.text, 'lxml')
member = member_soup.find_all('input', value='Jones')
The html for the button is below:
<input type="button" value="Jones" onclick="javascript:__doPostBack('ctl00$ContentPlaceHolder1$gvBills','SponsorName$47')" style="background-color:Transparent;border-color:Silver;border-style:Outset;font-size:Small;height:30px;width:100px;">
How to find the inputs onclick?
You were close by but should replace your line with:
member_soup.find('input', {"value" : "Jones"})['onclick']
Example
import requests
from bs4 import BeautifulSoup
select_session_url = 'http://alisondb.legislature.state.al.us/Alison/SelectSession.aspx'
session = requests.Session()
session_payload = {"__EVENTTARGET":"ctl00$ContentPlaceHolder1$gvSessions", "__EVENTARGUMENT": "$3"}
session.post(select_session_url, session_payload, headers)
senate_payload = {"__EVENTTARGET":"ctl00$ContentPlaceHolder1$btnSenate", "__EVENTARGUMENT": "Senate"}
session.post('http://alisondb.legislature.state.al.us/Alison/SessPrefiledBills.aspx', senate_payload, headers)
page = session.get('http://alisondb.legislature.state.al.us/Alison/SESSBillsList.aspx?SELECTEDDAY=1:2019-03-05&BODY=1753&READINGTYPE=R1&READINGCODE=B&PREFILED=Y')
member_soup = BeautifulSoup(page.text, 'lxml')
member = member_soup.find('input', {"value" : "Jones"})['onclick']
member
Output
"javascript:__doPostBack('ctl00$ContentPlaceHolder1$gvBills','SponsorName$39')"
Edit
You may interested how to start with selenium ...
from selenium import webdriver
from time import sleep
browser = webdriver.Chrome('C:\Program Files\ChromeDriver\chromedriver.exe')
browser.get('http://alisondb.legislature.state.al.us/Alison/SelectSession.aspx')
sleep(0.9)
browser.find_element_by_link_text('Regular Session 2019').click()
sleep(0.9)
browser.find_element_by_link_text('Prefiled Bills').click()
sleep(2)
browser.find_element_by_css_selector('input[value="Senate"]').click()
sleep(2)
browser.find_element_by_css_selector('input[value="Jones"]').click()
sleep(2)
print(browser.current_url)
browser.close()
Output
http://alisondb.legislature.state.al.us/Alison/Member.aspx?SPONSOR=Jones&BODY=1753&SPONSOR_OID=100453

Selenium to submit recaptcha using 2captcha Python

I am trying to submit Recaptcha on a search form using Python3, Selenium, and 2captcha.
Everything is working fine except submitting the Recaptcha after sending google-tokin in the text-area of Recaptcha.
Please guide me what am I missing?
When I look into my Selenium Webdriver window it shows Recaptcha text-area filled with google-tokin but I am not able to submit it to continue for search result.
Thankyou.
from selenium import webdriver
from time import sleep
from datetime import datetime
from twocaptcha import TwoCaptcha
import requests
## Launching webdriver
driverop = webdriver.ChromeOptions()
driverop.add_argument("--start-maximized")
driver = webdriver.Chrome("chromedriver/chromedriver",options=driverop)
url = "https://app.skipgenie.com/Account/Login"
sleep(randint(5,10))
email = "..."
password = ".."
input_data = pd.read_excel("input_data.xlsx")
user_Data = []
driver.get(url)
driver.find_element_by_id("Email").send_keys(email)
driver.find_element_by_id("Password").send_keys(password)
driver.find_element_by_class_name("btn-lg").click()
driver.find_element_by_id("firstName").send_keys(input_data.iloc[0][0])
driver.find_element_by_id("lastName").send_keys(input_data.iloc[0][1])
driver.find_element_by_id("street").send_keys(input_data.iloc[0][2])
driver.find_element_by_id("city").send_keys(input_data.iloc[0][3])
driver.find_element_by_id("state").send_keys(input_data.iloc[0][4])
driver.find_element_by_id("zip").send_keys(int(input_data.iloc[0][5]))
# 2Captcha service
service_key = 'ec.....' # 2captcha service key
google_site_key = '6LcxZtQZAAAAAA7gY9-aUIEkFTnRdPRob0Dl1k8a'
pageurl = 'https://app.skipgenie.com/Search/Search'
url = "http://2captcha.com/in.php?key=" + service_key + "&method=userrecaptcha&googlekey=" + google_site_key + "&pageurl=" + pageurl
resp = requests.get(url)
if resp.text[0:2] != 'OK':
quit('Service error. Error code:' + resp.text)
captcha_id = resp.text[3:]
fetch_url = "http://2captcha.com/res.php?key="+ service_key + "&action=get&id=" + captcha_id
for i in range(1, 10):
sleep(5) # wait 5 sec.
resp = requests.get(fetch_url)
if resp.text[0:2] == 'OK':
break
driver.execute_script('var element=document.getElementById("g-recaptcha-response"); element.style.display="";')
driver.execute_script("""
document.getElementById("g-recaptcha-response").innerHTML = arguments[0]
""", resp.text[3:])
Answering the question so the people who encounter situations like this could get help from this answer.
I was missing that after you get google token you need to display recaptcha text-area and send google-token to text-area like this
To display text-area of recaptcha.
driver.execute_script('var element=document.getElementById("g-recaptcha-response"); element.style.display="";')
after that send google token like this:
driver.execute_script("""
document.getElementById("g-recaptcha-response").innerHTML = arguments[0]
""", resp.text[3:])
then you need to make text-area display to none so the search button near repcatcha is clickable.
driver.execute_script('var element=document.getElementById("g-recaptcha-response"); element.style.display="none";')
then you need to click on the search button to get the search result.

Unable to locate element error while using find_element_by_css_selector in python

I am learning Selenium using Python. I have tried to check the button status - whether enabled or not? For that I have used mercury demo site and wrote the below code. I am getting
Unable to locate element: input[value=roundtrip]
Code which I have used:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
driver = webdriver.Firefox(executable_path="C:\\Seleinum_Python\\WedDriver\\geckodriver.exe")
driver.get("http://newtours.demoaut.com/")
# Whether the user name & password enabled and displayed
user_ele = driver.find_element_by_name("userName") # <input type="text" name="userName" size="10">
print(user_ele.is_displayed()) # Return True /False based on element status
print(user_ele.is_enabled())
pwd_ele = driver.find_element_by_name("password") #<input type="password" name="password" size="10">
print(pwd_ele.is_displayed())
print(pwd_ele.is_enabled())
user_ele.send_keys("mercury")
pwd_ele.send_keys("mercury")
driver.find_element_by_name("login").click()
roundtrip_radio= driver.find_element_by_css_selector("input[value=roundtrip]") #<input type="radio" name="tripType" value="roundtrip" checked="">
print(roundtrip_radio.is_selected())
oneway_radio= driver.find_element_by_css_selector("input[value=oneway]")
print(oneway_radio.is_selected())
driver.close()
I even tried with below combination but still I am getting the same element not found issue.
roundtrip_radio= driver.find_element_by_css_selector("input[value='roundtrip']")
roundtrip_radio= driver.find_element_by_css_selector('input[value="roundtrip"]')
roundtrip_radio= driver.find_element_by_css_selector("//input[value='roundtrip']")
roundtrip_radio= driver.find_element_by_css_selector("input[value='roundtrip']")
roundtrip_radio= driver.find_element_by_css_selector('input[name="tripType"][value="roundtrip"]')
In your css selector you can use :checked to identify selected elements.
for example :-
"input[type=radio]:checked"

Clicking a button with Selenium in Python

Goal: use Selenium and Python to search for company name on LinkedIn's search bar THEN click on the "Companies" button in the navigation to arrive to information about companies that are similar to the keyword (rather than individuals at that company). See below for an example. "CalSTRS" is the company I search for in the search bar. Then I want to click on the "Companies" navigation button.
My Helper Functions: I have defined the following helper functions (including here for reproducibility).
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
from random import randint
from selenium.webdriver.common.action_chains import ActionChains
browser = webdriver.Chrome()
def li_bot_login(usrnm, pwrd):
##-----Log into linkedin and get to your feed-----
browser.get('https://www.linkedin.com')
##-----Find the Search Bar-----
u = browser.find_element_by_name('session_key')
##-----Enter Username and Password, Enter-----
u.send_keys(usrnm)
p = browser.find_element_by_name('session_password')
p.send_keys(pwrd + Keys.ENTER)
def li_bot_search(search_term):
#------Search for term in linkedin search box and land you at the search results page------
search_box = browser.find_element_by_css_selector('artdeco-typeahead-input.ember-view > input')
search_box.send_keys(str(search_term) + Keys.ENTER)
def li_bot_close():
##-----Close the Webdriver-----
browser.close()
li_bot_login()
li_bot_search('calstrs')
time.sleep(5)
li_bot_close()
Here is the HTML of the "Companies" button element:
<button data-vertical="COMPANIES" data-ember-action="" data-ember-action-7255="7255">
Companies
</button>
And the XPath:
//*[#id="ember1202"]/div[5]/div[3]/div[1]/ul/li[5]/button
What I have tried: Admittedly, I am not very experienced with HTML and CSS so I am probably missing something obvious. Clearly, I am not selecting / interacting with the right element. So far, I have tried...
companies_btn = browser.find_element_by_link_text('Companies')
companies_btn.click()
which returns this traceback:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"link text","selector":"Companies"}
(Session info: chrome=63.0.3239.132)
(Driver info: chromedriver=2.35.528161 (5b82f2d2aae0ca24b877009200ced9065a772e73),platform=Windows NT 10.0.16299 x86_64)
and
companies_btn_xpath = '//*[#id="ember1202"]/div[5]/div[3]/div[1]/ul/li[5]/button'
browser.find_element_by_xpath(companies_btn_xpath).click()
with this traceback...
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//*[#id="ember1202"]/div[5]/div[3]/div[1]/ul/li[5]/button"}
(Session info: chrome=63.0.3239.132)
(Driver info: chromedriver=2.35.528161 (5b82f2d2aae0ca24b877009200ced9065a772e73),platform=Windows NT 10.0.16299 x86_64)
and
browser.find_element_by_css_selector('#ember1202 > div.application-outlet > div.authentication-outlet > div.neptune-grid.two-column > ul > li:nth-child(5) > button').click()
which returns this traceback...
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"#ember1202 > div.application-outlet > div.authentication-outlet > div.neptune-grid.two-column > ul > li:nth-child(5) > button"}
(Session info: chrome=63.0.3239.132)
(Driver info: chromedriver=2.35.528161 (5b82f2d2aae0ca24b877009200ced9065a772e73),platform=Windows NT 10.0.16299 x86_64)
It seem that you simply used incorrect selectors.
Note that
#id of div like "ember1002" is dynamic value, so it will be different each time you visit page: "ember1920", "ember1202", etc...
find_element_by_link_text() can be applied to links only, e.g. <a>Companies</a>, but not buttons
Try to find button by its text content:
browser.find_element_by_xpath('//button[normalize-space()="Companies"]').click()
With capybara-py (which can be used to drive Selenium), this is as easy as:
page.click_button("Companies")
Bonus: This will be resilient against changes in the implementation of the button, e.g., using <input type="submit" />, etc. It will also be resilient in the face of a delay before the button appears, as click_button() will wait for it to be visible and enabled.

RoboBrowser BadRequestKeyError(key)

I am trying to sign in to a website using RoboBrowser and I am stuck with a error message.
My code:
from robobrowser import RoboBrowser
browser = RoboBrowser()
def login():
browser.open('https://www.kijiji.ca/t-login.html')
form = browser.get_form(id="login-form")
form.fields["LoginEmailOrNickname"].value = "an_email_address"
form.fields["login-password"].value = "a_password"
form.fields["login-rememberMe"].value = "true"
browser.submit_form(form)
login()
The error message:
Traceback (most recent call last):
File "/home/rojaslee/Desktop/kijiji_poster/kijiji_poster.py", line 16, in <module>
login()
File "/home/rojaslee/Desktop/kijiji_poster/kijiji_poster.py", line 11, in login
form.fields["LoginEmailOrNickname"].value = ["an_email_address"]
File "/usr/local/lib/python3.4/dist-packages/werkzeug/datastructures.py", line 744, in __getitem__
raise exceptions.BadRequestKeyError(key)
werkzeug.exceptions.BadRequestKeyError: 400: Bad Request
Old thread, but I've been struggling with the same problem. This worked for me:
from robobrowser import Robobrowser
browser = RoboBrowser
def login():
browser.open('https://www.kijiji.ca/t-login.html')
form = browser.get_form(id="login-form")
form["EmailOrNickname"].value = "an_email_address"
form["password"].value = "a_password"
form["rememberMe"].value = "checked"
browser.submit_form(form)
The HTML code from the web site you want to log in is as follows:
<section>
<label for="LoginEmailOrNickname">Email Address or Nickname:</label>
<input id="LoginEmailOrNickname" name="emailOrNickname" req="req" type="text" value="" maxlength="128"><span class="field-message" data-for="LoginEmailOrNickname"></span>
</section>
<section>
<label for="login-password">Password:</label>
<input id="login-password" name="password" req="req" type="password" value="" maxlength="64"><span class="field-message" data-for="login-password"></span>
<a id="LoginForgottenPassword" href="/t-forgot-password.html">Forgot your password?</a>
</section>
To put a value on the form fields you have to get the name attribute, not the id.
This code should work:
form.fields["emailOrNickname"].value = "an_email_address"
form.fields["password"].value = "a_password"
form.fields["rememberMe"].value = "true"
If you need to get the fields of the form you can print them:
print form.fields
But have you tried using a 'try and except'?
I was able to get around this error using:
try:
form['userid'] = 'my_username'
form['password'] = 'my_password'
except Exception:
pass
I used a different website than you so make sure you input the correct form fields.
let me know if this helps!

Resources