Clicking radio button Selenium/Python - python

I am creating a Linkedin job scraper in order of most recent, but I am finding it really difficult to target the 'Most recent' radio button as shown below.
So far, the 'Most relevant' menu is clicked on, but will not click on 'Most recent'. Help would be appreciated I can't seem to figure this one out :/
Code snippet
driver.get('https://uk.linkedin.com/jobs/bioinformatics-jobs?position=1&pageNum=0')
driver.implicitly_wait(10)
driver.find_element_by_class_name('collapsible-dropdown').click() # Clicks 'sort-by' menu.
driver.find_element_by_xpath('//*[#id="sortBy-0"]').click() # Error!
HTML
<button aria-expanded="true" aria-label="Sort By filter. Most relevant filter is currently applied. Clicking this button displays all Sort By filter options." class="filter-button filter-button--selected dropdown-to-modal__button collapsible-dropdown__button" data-tracking-control-name="public_jobs_sortBy" type="button">
Most relevant
<icon class="filter-button__icon"></icon>
</button>
<div class="collapsible-dropdown__list no-focus-ring" tabindex="-1">
<!-- -->
<fieldset class="filter-values-container">
<legend class="filter-values-container__legend sr-only">Sort By filter options</legend>
<div class="filter-values-container__filter-values">
<div class="filter-values-container__filter-value">
<input checked="" form="jserp-filters" id="sortBy-0" name="sortBy" type="radio" value="R"/>
<label for="sortBy-0">
Most relevant
</label>
</div>
<div class="filter-values-container__filter-value">
<input form="jserp-filters" id="sortBy-1" name="sortBy" type="radio" value="DD"/>
<label for="sortBy-1">
Most recent
</label>
</div>
</div>
</fieldset>
<button aria-label="Apply filters" class="filter__submit-button" data-tracking-control-name="public_jobs_sortBy" form="jserp-filters" type="submit">
Done
</button>
</div>
<div class="filter-values-container__filter-value">
<input id="sortBy-1" form="jserp-filters" name="sortBy" value="DD" type="radio">
<label for="sortBy-1">
Most recent
</label>
</div>
</div>
</fieldset>
<button class="filter__submit-button" aria-label="Apply filters" form="jserp-filters" data-tracking-control-name="public_jobs_sortBy" type="submit">
Done
</button>
</div>

try this
driver.find_element_by_xpath('//*[#id="jserp-filters"]/ul/li[1]/div/div/div/fieldset/div/div[2]').click()
your xpath was incomplete

Things to be noted down :
You need Explicit waits.
JS intervention.
Reliable locators.
Prefer CSS over Xpath.
Code :-
driver = webdriver.Chrome(driver_path)
driver.maximize_window()
driver.get("https://uk.linkedin.com/jobs/bioinformatics-jobs?position=1&pageNum=0")
WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div.collapsible-dropdown>button[data-tracking-control-name='public_jobs_sortBy']"))).click()
driver.execute_script("arguments[0].click();", driver.find_element_by_css_selector("input[value='DD']"))
Imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

Related

Cannot click on radio button in fieldset

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

Python Selenium Click a button with class

I'm new to python selenium and I'm trying to click on a button which has the following HTML structure:
<div class="wpsafe-top text-center">
<h1><strong><span style="color: #ce2525;">Click on Submit to Get Link</span></strong></h1><br>
<form action="https://url.com/post" method="post">
<input type="hidden" name="getlink" value="NVudM3E">
<input type="hidden" name="newwpsafelink" value="eyJsaW5rIjoiTlZ1ZE0zRSIsImFkczEiOiIiLCJhZHMyIjoiIiwibG9nbyI6IiIsImltYWdlMSI6Imh0dHA6XC9cL3RlY2hjb2RlY3MuY29tXC93cC1jb250ZW50XC91cGxvYWRzXC8yMDE5XC8xMlwvZ2VuLnBuZyIsImltYWdlMiI6Imh0dHA6XC9cL3RlY2hjb2RlY3MuY29tXC93cC1jb250ZW50XC91cGxvYWRzXC8yMDE5XC8xMlwvcGx6LnBuZyIsImltYWdlMyI6Imh0dHA6XC9cL3RlY2hjb2RlY3MuY29tXC93cC1jb250ZW50XC91cGxvYWRzXC8yMDE5XC8xMlwvY2xrLnBuZyIsImxpbmtyIjoiaHR0cHM6XC9cL3RlY2hjb2RlY3MuY29tP3NhZmVsaW5rX3JlZGlyZWN0PTUlNUIlOUQzcSIsImRlbGF5dGV4dCI6IjxiPjxoMiBzdHlsZT0nY29sb3I6cmVkJz5Mb2FkaW5nIExpbmsgLi4uIFdhaXQgPHNwYW4gaWQ9XCJ3cHNhZmUtdGltZVwiPjEyPFwvc3Bhbj4gU2Vjb25kczxcL2gyPjxcL2I+IiwiZGVsYXkiOiIxMiIsImFkYiI6IjIiLCJhZGIxIjoiIiwiYWRiMiI6IiJ9">
<input class="btn btn-primary" type="submit" value="Submit">
</form>
</div>
I have tried this to click on Submit Button.
driver.find_element_by_css_selector('btn btn-primary').click()
But i always end up with error
Message: no such element: Unable to locate element: {"method":"css selector","selector":".btn btn-primary"}
find_element_by_css_selector('btn btn-primary') will look fir an element with tag btn-primary that has ancestor element with tag btn.
You need to tell the driver those are classes with .
driver.find_element_by_css_selector('.btn.btn-primary').click()
Or explicitly
driver.find_element_by_css_selector('[class="btn btn-primary"]').click()

Select checkbox using selenium in python

I want to select a checkbox using selenium in python. Following is the HTML of the checkbox. The span element is getting highlighted when hovering the mouse over checkbox
HTML
<div id="rc-anchor-container" class="rc-anchor rc-anchor-normal rc-anchor-light">
<div id="recaptcha-accessible-status" class="rc-anchor-aria-status" aria-hidden="true">Recaptcha requires verification. </div>
<div class="rc-anchor-error-msg-container" style="display:none"><span class="rc-anchor-error-msg" aria-hidden="true"></span></div>
<div class="rc-anchor-content">
<div class="rc-inline-block">
<div class="rc-anchor-center-container">
<div class="rc-anchor-center-item rc-anchor-checkbox-holder"><span class="recaptcha-checkbox goog-inline-block recaptcha-checkbox-unchecked rc-anchor-checkbox" role="checkbox" aria-checked="false" id="recaptcha-anchor" tabindex="0" dir="ltr" aria-labelledby="recaptcha-anchor-label"><div class="recaptcha-checkbox-border" role="presentation"></div><div class="recaptcha-checkbox-borderAnimation" role="presentation"></div><div class="recaptcha-checkbox-spinner" role="presentation"></div><div class="recaptcha-checkbox-spinnerAnimation" role="presentation"></div><div class="recaptcha-checkbox-checkmark" role="presentation"></div></span></div>
</div>
</div>
<div class="rc-inline-block">
<div class="rc-anchor-center-container">
<label class="rc-anchor-center-item rc-anchor-checkbox-label" aria-hidden="true" role="presentation" id="recaptcha-anchor-label"><span aria-live="polite" aria-labelledby="recaptcha-accessible-status"></span>I'm not a robot</label>
</div>
</div>
</div>
<div class="rc-anchor-normal-footer">
<div class="rc-anchor-logo-portrait" aria-hidden="true" role="presentation">
<div class="rc-anchor-logo-img rc-anchor-logo-img-portrait"></div>
<div class="rc-anchor-logo-text">reCAPTCHA</div>
</div>
<div class="rc-anchor-pt">Privacy<span aria-hidden="true" role="presentation"> - </span>Terms</div>
</div>
</div>
I am trying the following code but it is giving following exception selenium.common.exceptions.NoSuchElementException
My Code
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
chromedriver = 'C:\Program Files (x86)\Google\Chrome\chromedriver'
browser = webdriver.Chrome(chromedriver)
browser.get(url)
checkBox = browser.find_element_by_id("recaptcha-anchor")
checkBox.click()
This is a recaptha stuff .. it's not like normal elements in the page
you have to navigate with selenium to the captcha frame .. then you can deal with the checkbox element..
to do that you need first to save the main window handle to be get back to it when you're done with the recaptcha
# save the main window handle
mainwindow = browser.current_window_handle
# get the recapthca iframe then navigate to it
frame = browser.find_element_by_tag_name("iframe")
browser.switch_to.frame(frame)
# now you can access the checkbox element
browser.find_element_by_id("recaptcha-anchor").click()
# navigate back to main window
browser.switch_to.window(mainwindow)
for further info about how to deal with the recaptcha challenge check this link

Upload a photo in selenium python when file path input is not visible

This is a html code of upload a photo:
<div id="choose-photo" class="controls avatar-settings inline-upload-avatar dropdown center">
<div class="uploader-image uploader-avatar clearfix">
<div class="dropdown-menu">
<div class="dropdown-caret">
<span class="caret-outer"></span>
<span class="caret-inner"></span>
</div>
<ul tabindex="-1" role="menu" aria-hidden="true">
<li id="photo-choose-existing" class="photo-choose-existing upload-photo" role="presentation">
<button type="button" class="dropdown-link" role="menuitem">Prześlij zdjęcie</button>
<div class="photo-selector">
<button class="btn" type="button">
Zmień zdjęcie
</button>
<span class="photo-file-name">Nie wybrano pliku</span>
<div class="image-selector">
<input type="hidden" name="media_file_name" class="file-name">
<input type="hidden" name="media_data_empty" class="file-data">
<label class="t1-label">
<span class="u-hiddenVisually">Dodaj zdjęcie</span>
<input type="file" name="media_empty" class="file-input js-tooltip" tabindex="-1" accept="image/gif,image/jpeg,image/jpg,image/png" data-original-title="Dodaj zdjęcie">
</label>
</div>
</div>
</li>
<li id="photo-choose-webcam" class="u-hidden" role="presentation">
<button type="button" class="dropdown-link">Zrób zdjęcie</button>
</li>
<li id="photo-delete-image" class="u-hidden" role="presentation">
<button type="button" class="dropdown-link" role="menuitem">Usuń</button>
</li>
<li class="dropdown-divider" role="presentation"></li>
<li class="cancel-options" role="presentation">
<button type="button" class="dropdown-link" role="menuitem">Anuluj</button>
</li>
</ul>
</div>
</div>
</div>
I've created a simple method to send text to input (it's not visible on screen):
fileInput = driver.find_element_by_name('media_empty')
fileInput.send_keys(path)
But it doesn't do anything. Also I'm getting not any errors.
So, here's a second method, which may work:
<div class="ProfileAvatarEditing-buttonContainer">
<button class="ProfileAvatarEditing-button u-boxShadowInsetUserColorHover" type="button" tabindex="2">
<div class="ProfileAvatarEditing-addAvatarHelp">
<span class="Icon Icon--cameraPlus"></span>
<p>Dodaj zdjęcie profilowe</p>
</div>
<div class="ProfileAvatarEditing-changeAvatarHelp">
<span class="Icon Icon--camera"></span>
<p>Zmień zdjęcie profilowe</p>
</div>
<div class="ProfileAvatarEditing-dropAvatarHelp">
<span class="Icon Icon--cameraPlus"></span>
<p>Upuść zdięcie profilowe tutaj</p>
</div>
</button>
Here user can drap and drop file. I've found this question: Selenium: Drag and Drop from file system to webdriver? however I still don't know how can I use it in this situation.
So the question is how to send file path to the input to trigger file upload. In this case when you choose a file from file dialog or drag and drop it you'll see confirm window with preview on your photo. So then all what's left to do is to click confirm. But I don't know how to send it in the first place.
Any help will be appreciated.
edit:
I've found a solution (my own answer below):
fileInput = driver.find_element_by_xpath('//*[#id="photo-choose-existing"]/div/div/label/input')
fileInput.send_keys(path)
but there's one more problem: photo is uploaded but file dialog still opens - I don't know how to close it. I tried accesing it:
dialog = driver.switch_to.active_element['value']
but I don't know how to close it.
Strangely enough I found send_keys do indeed work. When I inspected html code in different browser it wasn't "media_empty" anymore, but a different name ("media[]" or something similar). Instead I've used xpath and I was stunned that it actually worked:
fileInput = driver.find_element_by_xpath('//*[#id="photo-choose-existing"]/div/div/label/input')
fileInput.send_keys(path)
try using below code:
fileInput = driver.find_element_by_css_selector("div.image-selector label.t1-label input")
driver.execute_script("arguments[0].setAttribute('value', 'YOUR_PATH_HERE')",fileInput)
Assuming that element is present on page if not explicitly wait for element to exist on page.
then try this:
driver.execute_script("document.getElementById('ID_HERE').setAttribute('value', 'PATH_HERE')");
hope this will help you!

Selenium Python. Click on radio-button does not any affect

First of all sorry for my english.
I have a page with radio-buttons.
Here is the html code of the button I want to click.
<label class="radio-button__radio radio-button__radio_side_right radio-button__radio_next-for-pressed_yes" for="uniq13988671">
<input id="uniq13988671" class="radio-button__control" type="radio" value="1000">
<span class="radio-button__text">все</span>
</label>
my python script with selennium:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver import ActionChains as ac
driver = webdriver.Firefox()
driver.get("url_with_elements")
driver.implicitly_wait(20)
my_button = driver.find_element_by_css_selector("input[value='1000']")
ac(driver).move_to_element(my_button).perform()
my_button.click()
This button should reload the page with all elements (at least 1000) but it doesn't work.
Ther's no any errors and element respond on method .get_attribute('id')
>>> my_button.get_attribute('id')
u'uniq13988671'
here is full html code of row with radio-buttons:
<td class="b-layout-table__cell">
<div class="b-banners-per-page i-bem b-banners-per-page_js_inited" onclick="return {"b-banners-per-page":{"urlObject":{"hash":"","query":{"cmd":"setPageSize","subcmd":"showCamp","cid":"8868621","ulogin":"*mylogin*"},"file":"main.NWluTm99mAw1N.pl","directory":"/registered/","path":"/registered/main.NWluTm99mAw1N.pl","relative":"/registered/main.NWluTm99mAw1N.pl","port":"","host":"direct.yandex.ru","password":"","user":"","userInfo":"","authority":"direct.yandex.ru","protocol":"https","source":"https://direct.yandex.ru/registered/main.NWluTm99mAw1N.pl"},"optimalBannersOnPage":20}}">
<span class="b-banners-per-page__title">Объявлений на странице: </span>
<div class="b-banners-per-page__buttons">
<span class="radio-button radio-button_size_s radio-button_theme_normal i-bem radio-button_js_inited" onclick="return {"radio-button":{}}">
<label class="radio-button__radio radio-button__radio_side_left" for="uniq13988675">
<label class="radio-button__radio radio-button__radio_checked_yes radio-button__radio_pressed_yes" for="uniq13988674">
<label class="radio-button__radio radio-button__radio_next-for-pressed_yes" for="uniq13988673">
<label class="radio-button__radio" for="uniq13988672">
<label class="radio-button__radio radio-button__radio_side_right" for="uniq13988671">
<input id="uniq13988671" class="radio-button__control" type="radio" value="1000">
<span class="radio-button__text">все</span>
</label>
</span>
</div>
</div>
</td>
Here's the image of how it looks like "step by step"
http://i.imgur.com/LYqKyqx.png
I'm looking at other questions but they don't help me.
Thanks for any help.
ADD: If i use Selenium IDE addon for firefox. this button clicked fine.
If need more info - please ask.
I've handle my problem use construction like that:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver import ActionChains as ac
driver = webdriver.Firefox()
driver.get("url_with_elements")
driver.implicitly_wait(20)
# my_button = driver.find_element_by_css_selector("input[value='1000']")
button_parent = driver.find_element_by_xpath("//td[2]/div/div/span/label[5]")
ac(driver).move_to_element(button_parent).perform()
button_parent.click()
ac(driver).send_keys(Keys.SPACE).perform()

Categories

Resources