Python Selenium find element by xpath or by id issue - python

I am trying to enter text into a text box on a web page but I am unable to locate it. I've tried finding it by xpath using the placeholder but may have had the wrong syntax as it was throwing an error.
The error I get with the below python is element not interactable - but it's a text field? surely it's intractable?
HTML:
<div class="name-filter-input"> == $0
<input placeholder="Search" ng-model="filter"
class="ng-pristine ng-valid">
</div>
My Python:
browser.find_element_by_class_name('name-filter-input')
campaign_text_field = browser.find_element_by_class_name('name-filter-input')
campaign_text_field.send_keys(x)

It seems you are trying to interact with the division instead of the input field.
Could you try changing the class name as so:
campaign_text_field = browser.find_element_by_class_name('ng-pristine ng-valid')

Use CSS Selector for the input element.
campaign_text_field = browser.find_element_by_css_selector('input.ng-pristine.ng-valid')
campaign_text_field.send_keys("XXX")
For the best practice induce WebDriverWait() and wait for element_to_be_clickable()
WebDriverWait(browser,20).until(EC.element_to_be_clickable((By.CSS_SELECTOR,'input.ng-pristine.ng-valid'))).send_keys("XXX")
Add following libraries.
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

Related

How to click on checkbox filter with selenium Python?

I'm trying to click on a checkbox filter on a website with selenium python. This is a part of its HTML code linked to one of the checkbox options.
<div class="shopee-checkbox" bis_skin_checked="1">
<label class="shopee-checkbox__control">
<input type="checkbox" name="" value="Jabodetabek">
<div class="shopee-checkbox__box" bis_skin_checked="1">
<i> </i>
</div>
<span class="shopee-checkbox__label">Jabodetabek</span>
</label>
</div>
I tried following, but it didn't work.
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get('https://shopee.co.id/search?keyword=baju%20laki-laki')
time.sleep(5)
driver.find_element(By.XPATH, "//input[#value='JABODETABEK']").click()
I read the answers to similar questions, mostly they suggest using 'id' and 'name' to find the element. However, in this input tag, there are only 'type' and 'value'.
Here is one way to select that checkbox:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
[...]
wait = WebDriverWait(driver, 25)
[..]
wait.until(EC.element_to_be_clickable((By.XPATH, '//span[text()="Jabodetabek"]'))).click()
print('clicked on Jabodetabek')
Selenium documentation can be found here.
#value for the checkbox in the xpath is incorrect. The selenium web locator techniques are case sensitive. So make sure to use exact values while identifying objects. Changing your xpath to below would fix the issue.
driver.find_element(By.XPATH, "//input[#value='Jabodetabek']").click()

Unable to Locate Element with Selenium Python despite xPath

I can't locate element on website and insert numerical value inside using Selenium on Firefox with Python.
I am using firefox add-in to get the xPath for the input field, I receive:
/html/body/div1/section/div/div/div/div/form/div1/div/div[4]/div2/div/div/div/div1/div1/table/tbody/tr1/td3/div/input
however with Python code objDriver.find_element_by_xpath("...") - I receive "Unable to locate element:" -> like xpath is wrong
If I use it on the let's say border of the input field, I get following xPath:
/html/body/div1/section/div/div/div/div/form/div1/div/div[4]/div2/div/div/div/div1/div1/table/tbody/tr1/td3
This element I can allocate using objDriver.find_element_by_xpath("...") but it is not input field, so I can't insert value
If I click "Inspect" in Firefox, I get:
CSS Path:
html body div.main-content section.section div.block-one_col_1 div.container-fluid.wrapper div.row div.col-12 form#id_form-process.form-horizontal.formfactory div.row div.col-md div#fieldgroup_variants.fieldset div#fieldgroup_variants__fields.fieldset__content div.form-group.row.formfield_variantsCalculator.fieldpk_2533.mb-0.is-valid div.col-md-6.col-12 div.d-flex.flex-row div.w-100 div.table-scroll table.table.table--step tbody#tableContent.table tr.table-row.table-row--count td div.form-group.group1 input.form-control.variant-value.variant1.touched
xPath:
/html/body/div/section/div/div/div/div/form/div[1]/div/div[4]/div[2]/div/div/div/div[1]/div[1]/table/tbody/tr[1]/td[3]/div/input
HTML part I am interested in:
<td data-risk="6.1"><div class="form-group group1" data-excluded="false" data-risk="6.1"><input name="1" class="form-control variant-value variant1 touched" data-editable="true" data-risk="6.1" data-visible-sum="true" data-dynamic="false"></div></td>
Do you have any idea how can I locate the field I need?
General view of Input field:
When getting xPath of the border:
When getting xPath of the Input field:
Can you try with the below xpath with Explicit waits :
wait = WebDriverWait(driver, 10)
wait.until(EC.element_to_be_clickable((By.XPATH, "//input[#name= '1' and contains(#class, 'variant-value')]"))).send_keys('10000')
Imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
Try with xPath = //input[#class="form-control variant-value variant1 touched"][#id="1"]

How to find an input using selenium

I need to submit this form by clicking with selenium on the following input:
<div align="center">
<input type="submit" class="boton" value="Aceptar">
</div>
I tried:
driver.find_element_by_xpath("//input[#value='Aceptar']").click()
I also tried with the class name "boton" but doesn't work,
To click on the input element you need to switch to iframe first.
Induce WebDriverWait() and wait for frame_to_be_available_and_switch_to_it()
Induce WebDriverWait() and wait for element_to_be_clickable()
WebDriverWait(driver,10).until(EC.frame_to_be_available_and_switch_to_it((By.NAME,"busqueda")))
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//input[#value='Aceptar'][#class='boton']"))).click()
You need to import below libraries.
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
Update
Input element present inside nested iframes.Inorder to access you need to switch to nested iframes.
WebDriverWait(driver,10).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe.iframeTGR")))
WebDriverWait(driver,10).until(EC.frame_to_be_available_and_switch_to_it((By.NAME,"busqueda")))
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//input[#value='Aceptar'][#class='boton']"))).click()
You can use Javascript executor to do it.
button = driver.find_element_by_xpath("//input[#value='Aceptar']")
driver.execute_script("arguments[0].click();", button)
utilize execute_script in order to set the value attribute of an input field. check out the following code block:
input_field= driver.find_element_by_xpath("//input[#value='Aceptar']")
driver.execute_script("[0].click();",input_field)

Unable to extract an attribute using the Selenium package

The general idea is to extract DOM using Selenium packages.
Specifically, the objective is to extract the value of max which reside in the class pagination__input hide-phone as shown below
<div class="pagination__input hide-phone">
<input type="number" name="page" max="12" value="1">
</div>
The website is accessible from this link.
To achieve this, the following code were drafted.
maxPage = self.browser.find_elements_by_css_selector( "[class='pagination__input hide-phone']" )
valueMax=maxPage.get_attribute( 'max' )
However, the following error was thrown.
AttributeError: 'list' object has no attribute 'get_attribute'
May I know what is the problem.
Thanks in advance.
Edit 2
As suggested by #Kunduk.
As per #Kunduk, the following line has been tailor accordingly. Specifically, add the self.
print( WebDriverWait( self.browser, 10 ).until( EC.visibility_of_element_located(
(By.CSS_SELECTOR, "div.pagination__input.hide-phone>input[name='page']") ) ).get_attribute( "max" ) )
However, I got the following error
Edit 1:
As suggested by #Josh
pages = self.browser.find_elements_by_css_selector( "[class='pagination__input hide-phone']" )
maxPages = [page for page in pages if page.get_attribute('max')]
However, it return the result of [],also as shown by the figure below:
Use this selector div.pagination__input > input and induce WebDriverWait() :
driver.get('https://www.freepik.com/search?dates=any&format=search&page=1&query=Polygonal%20Human&sort=popular')
element = WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.CSS_SELECTOR, 'div.pagination__input > input')))
print(element.get_attribute('max'))
To get the max value of the page induce WebDriverWait() and wait for presence_of_element_located() and following css selector.
driver.get("https://www.freepik.com/search?dates=any&format=search&page=1&query=Polygonal%20Human&sort=popular")
print(WebDriverWait(driver,10).until(EC.presence_of_element_located((By.CSS_SELECTOR,"div.pagination__input.hide-phone>input[name='page']"))).get_attribute("max"))
You need to import following libraries.
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
snapshpt:

How do i click on the link while using selenium python

I'm new to python and selenium.
This is an HTML snippet of the page im trying to scrape a page this
I want to scrape on the basis of data-attr1 given in the html snippet.
Please share some code to find this link and click on it.
<a class="js-track-click challenge-list-item" data-analytics="ChallengeListChallengeName" data-js-track="Challenge-Title" data-attr1="grading" data-attr3="code" data-attr4="true" data-attr5="true" data-attr7="10" data-attr-10="0.9" data-attr11="false" href="/challenges/grading"><div class="single-item challenges-list-view-v2 first-challenge cursor"><div id="contest-challenges-problem" class="individual-challenge-card-v2 content--list-v2 track_content"><div class="content--list_body"><header class="content--list_header-v2"><div class="challenge-name-details "><div class="pull-left inline-block"><h4 class="challengecard-title">Grading Students<div class="card-details pmT"><span class="difficulty easy detail-item">Easy</span><span class="max-score detail-item">Max Score: 10</span><span class="success-ratio detail-item">Success Rate: 96.59%</span></div></h4></div></div><span class="bookmark-cta"><button class="ui-btn ui-btn-normal ui-btn-plain star-button" tabindex="0" aria-label="Add bookmark"><div class="ui-content align-icon-right"><span class="ui-text"><i class="js-bookmark star-icon ui-icon-star"></i></span></div></button></span><div class="cta-container"><div class="ctas"><div class="challenge-submit-btn"><button class="ui-btn ui-btn-normal primary-cta ui-btn-line-primary" tabindex="0"><div class="ui-content align-icon-right has-icon"><span class="ui-text">Solved</span><i class="ui-icon-check-circle ui-btn-icon"></i></div></button></div></div></div></header></div></div><div class="__react_component_tooltip place-top type-dark " data-id="tooltip"></div></div></a>
If the page is not loading as fast as expected you can try:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//a[#data-attr1='grading']"))).click()
You can click on the element using the xpath:
element = driver.find_element_by_xpath("//a[#data-attr1='grading']")
element.click();
Since there is no name id or class available directly you can use xpath.
The element that you are looking for is in div with class challenges-list and you want to click on first link inside it. You can use this xpath
//a[#data-attr1='grading']
And for clicking you can do
driver.find_element_by_xpath("//a[#data-attr1='grading']").click()
Use double-click with Actionchains because click might not work in Python.
eg.
from selenium.webdriver import ActionChains
# Get the element however you want
element = driver.find_element_by_xpath("//a[#data-attr1='grading']")
ActionChains(driver).double_click(settings_icon).perform()

Categories