Getting an attribute from a table row with Selenium | Python - python

I'm trying to find how can I see if this button (image) it's already clicked or not:
But I haven't been able to do it and I need to interact with this button because it allows me to edit the price of some items and protect them if I don't wan't, the problem is that I need to check if it's clicked or not before doing it.
I have tried many times to identify when it's clicked or not, but I don't see any change on button attributes so I don't know how to do it. I also tried checking on price item and I see one change when it's clicked:
When it's editable, there is an attribute named "contenteditable" and it's value equals true, but when it's not editable this attribute dissapear and changes for a attribute named "disabled" equals true:
This are the lines of code that I have been using to get this attribute values:
cod = WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, '//*[#id="tbodyDatos"]/tr[1]/td[5]/div'))).get_attribute("disabled")
cod = WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, '//*[#id="tbodyDatos"]/tr[1]/td[5]/div'))).get_attribute("attributes[1]")
cod = WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, '//*[#id="tbodyDatos"]/tr[1]/td[5]/div'))).get_attribute("attributes[1].nodeValue")
I would appreciate it so much if anyone can help me.
¡Thanks!

The expanded <i> along with it's decendants would have possibly given us some hint about some specific attribute to validate if the checkbox is checked or not.
Solution
You can still probe the if the checkbox is checked or not with respect to the attribute of the adjascent <div> attribute as follows:
try:
WebDriverWait(driver, 5).until(EC.element_to_be_clickable((By.XPATH, '//*[#id="tbodyDatos"]/tr[1]/td[5]/div'))).click()
print("Checkbox unchecked")
except (TimeoutException, ElementNotInteractableException, WebDriverException):
print("Checkbox checked")
Note : You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException, ElementNotInteractableException, WebDriverException

Related

Button click using Selenium not actionable

I am trying to fill in a registration form and click submit. But Selenium says the Registration button is not actionable. I have tried using actionchains and a couple of other techniques but generally get the same error.
selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable
My code...
driver.get('https://discover.workato.com/automate-2022/p/1?utm_source=Automate+2022&utm_medium=employee+referral&utm_campaign=MCoblentz')
time.sleep(3)
first_name = driver.find_element_by_xpath('//*[#id="FirstName"]')
first_name.send_keys(line[1])
skipping a few more fields to the button click (and neither the by class name or the xpath work)...
Button = driver.find_element(By.class name("mktoButtonWrap"))
# Button = driver.find_element_by_xpath('//*[#id="mktoForm_3468"]/div[17]/span')
Button.click()
For the life of me, I can't figure out:
Why the button is not actionable and what I need to do to click it. (Major problem)
Why Python won't run with the following find_element line (minor annoyance)
Button = driver.find_element(By.xpath('//*[#id="mktoForm_3468"]/div[17]/span')
Python is throwing an error that
'AttributeError: type object 'By' has no attribute 'xpath'
But I'm initializing with:
from selenium.webdriver.common.by import By
Your syntax is incorrect. It should be:
Button = driver.find_element(By.XPATH, '//*[#id="mktoForm_3468"]/div[17]/span')
If you import By correctly (from selenium.webdriver.common.by import By), your IDE should autocorrect and show correct options:
You need to consider a couple of things here as follows:
Instead of:
Button = driver.find_element(By.class name("mktoButtonWrap"))
It should have been:
Button = driver.find_element(By.CLASS_NAME, "mktoButtonWrap")
Similarly,
Button = driver.find_element(By.XPATH, '//*[#id="mktoForm_3468"]/div[17]/span')
Further, this error message...
selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable
indicates that the desired element is not interactable.
Solution
To click on Register you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following locator strategies:
Using XPATH:
driver.get("https://discover.workato.com/automate-2022/p/1?utm_source=Automate+2022&utm_medium=employee+referral&utm_campaign=MCoblentz")
driver.execute_script("arguments[0].click();", WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[#class='mktoButton' and text()='Register']"))))
Note: You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

How to click an input type=checkbox from an aria-expanded menu using selenium python?

i have been trying to click an input as type: checkbox but it doesn't seem to work. I need to press one of the size options but when i expand the size-picker-form using this piece of code:
sizelistspot = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, '//*[#id="picker-trigger"]'))) sizelistspot = driver.find_element(By.XPATH, '//*[#id="picker-trigger"]').click()
and then use this piece of code to check if the form is located:
sizelist = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.NAME, 'size-picker-form'))) print('I found the size menu!!!')
I watch it run because i run non-headless and i see the dropdown menu expand so then i try to select a size with this piece of code:
sizechoice = driver.find_element(By.ID, 'size-picker-JOC12N001-A180150000').click() print('I selected the size!!!')
But i recieve the error: 'selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable' Why can't i click the size whilst i can manually? And what is the right way to do it. This is the link to the site: https://www.zalando.nl/jordan-air-jordan-1-mid-sneakers-hoog-joc12n001-a18.html I am still a beginner so there is a big chance there are some mistakes in my code. Thanks!
//div[./*[#id='size-picker-JOC12N001-A180150000']]
Just click the div that contains that id instead the input tag has 0x0 size and doesn't seem to be interactable.
wait=WebDriverWait(driver,60)
driver.get('https://www.zalando.nl/jordan-air-jordan-1-mid-sneakers-hoog-joc12n001-a18.html')
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,"#uc-btn-accept-banner"))).click()
sizelistspot = wait.until(EC.element_to_be_clickable((By.XPATH, '//*[#id="picker-trigger"]')))
sizelistspot.click()
wait.until(EC.element_to_be_clickable((By.XPATH, '//div[./*[#id="size-picker-JOC12N001-A180150000"]]'))).click()
Imports:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
Outputs:

Unable to select a menu item with selenium

I am making a screen scraper using the Selenium Python library and I have already made some code so that I can log in. For some reason I am now stuck on the main menu and can't select any of the options. I have tried using CSS Selector, Class Name, and XPATH and none have been able to select any of the possible choices. No matter what happens, I always get a TimeoutException even with a long delay.
The portion of the page I am trying to scrape from is here.
The relevant code is as follows:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
# Open browser and go to the Webex login page
driver = webdriver.Chrome()
driver.get('https://admin.webex.com')
delay = 10 # seconds
long_delay = 20
# Login portion removed
# Menu selection goes here.
# I have tried the following with no luck
# The following lines produce a TimeoutException error
# Selecting menu item
WebDriverWait(driver, long_delay).until(EC.presence_of_element_located((By.XPATH, "span[#class='left-nav-item__link']"))).click()
WebDriverWait(driver, long_delay).until(EC.presence_of_element_located((By.XPATH, '//mch-left-nav-item-group[4]/ul/mch-left-nav-item[3]/li/span'))).click()
WebDriverWait(driver, long_delay).until(EC.presence_of_element_located((By.XPATH, "//webex-root/webex-main[#class='control-hub-container']//webex-sidebar/mch-left-nav/nav/mch-left-nav-item-group[4]/ul/mch-left-nav-item[3]//span[#class='left-nav-item__link']"))).click()
WebDriverWait(driver, long_delay).until(EC.presence_of_element_located((By.CSS_SELECTOR, "span[class='left-nav-item__link']"))).click()
WebDriverWait(driver, delay).until(EC.presence_of_element_located((By.CSS_SELECTOR, "[aria-label] mch-left-nav-item-group:nth-of-type(4) mch-left-nav-item:nth-of-type(3) .left-nav-item__link"))).click()
# Selecting group of items
WebDriverWait(driver, delay).until(EC.presence_of_all_elements_located((By.CLASS_NAME, 'left-nav-item')))
WebDriverWait(driver, delay).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, 'li.left-nav-item')))
# Selecting parent
WebDriverWait(driver, long_delay).until(EC.presence_of_element_located((By.CSS_SELECTOR, "li[data-test-name='calling']")))
Does anyone have an idea why I'm not able to select any element?
Try xpath for the third one:
WebDriverWait(driver, long_delay).until(EC.presence_of_element_located((By.XPATH, "span[#class='left-nav-item__link']"))).click()
To anyone having this issue.
When a new tab is opened while you are using Selenium, even though you are viewing the new page, Selenium is not. You have to switch to the correct window. Something such as the following can help you with that.
driver.switch_to.window(driver.window_handles[NUMBER])

Why am I receiving an ElementClickInterceptedException error?

The question on the survey asks: What days of the week are you consistently available? I would like to check Sunday.
I am duplicating the code I see from an online video, however, I am receiving this error. Some people are suggesting that a pop-up may be blocking the program from working correctly but I do not see a pop up.
I have tried using chromedriver and geckodriver. The error is present in both.
The code to see if Sunday is selected works properly:
status=driver.find_element_by_id("RESULT_CheckBox-8_0").is_selected()
print(status)
output:
False
Here is my code:
from selenium import webdriver
driver=webdriver.Chrome(executable_path="my_webdriver_path"\\chromedriver.exe
driver.get("https://fs2.formsite.com/meherpavan/form2/index.html?1537702596407")
What days of the week are you consistently available?
I would now like to check the Sunday box. Here is my code:
status=driver.find_element_by_id("RESULT_CheckBox-8_0").click()
print(status)
I would like the Sunday box checked but I am receiving this error:
selenium.common.exceptions.ElementClickInterceptedException: Message: Element <input id="RESULT_CheckBox-8_0" class="multiple_choice" name="RESULT_CheckBox-8" type="checkbox"> is not clickable at point (313,599) because another element <label> obscures it
I do not see another element that obscures the program. Does anyone have any suggestions? I am new to coding so any help would be greatly appreciated.
The problem you're having is related to the same values that are being used for different attributes in the label and input tags.
As you can see the 'for' attribute of the label has the same value as the 'id' attribute (wich doesn't allways have to be a unique value) of the eventhough you are using 'find_element_by_id'.
To fix this you could use a different locator like XPATH. You can get a xpath by right clicking on the element (when you are inspecting the code with f12) and than select [copy] - [xpath]
Here is some code that should work (note: I have placed the chromedriver.exe in the same location as the .py file it self):
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://fs2.formsite.com/meherpavan/form2/index.html?1537702596407')
status = driver.find_element_by_id("RESULT_CheckBox-8_0").is_selected()
if status:
pass
else:
driver.find_element_by_xpath("//*[#id='q15']/table/tbody/tr/td[1]/label").click()
Don't forget to eventually close the driver, otherwise it will stay in de background as a running procces.
You can do so by:
driver.close()
Hope this helps!
Try use ActionChains to click the element.
element = driver.find_element_by_id("RESULT_CheckBox-8_0")
ActionChains(driver).move_to_element(element).click(element).perform()
status = driver.find_element_by_id("RESULT_CheckBox-8_0").is_selected()
print(status)
Following import:
from selenium.webdriver import ActionChains
To click() on the checkbox with text as Sunday you can use the following Locator Strategy:
Using XPATH:
driver.get("https://fs2.formsite.com/meherpavan/form2/index.html?1537702596407")
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//label[starts-with(#for, 'RESULT_CheckBox-') and contains(., 'Sunday')]"))).click()
Note : You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
Browser Snapshot:

How to locate a particulat checkbox from a series of checkboxes using Selenium and Python 3.7.4

I'm trying to develop a bot that automatically handles the deletion of various posts from a website. I have stumbled across a major problem which does not allow me to proceed any further.
The page I've achieved to open presents various checkboxes with the following input:
<input type="checkbox" name="ids[]" value="305664759" onclick="toggleDeleteButtons()">
What I have to do is check simultaneously each checkbox and then click on delete button. Then a popup will appear, where I have to click another "Delete" button with the following input:
<input id="btnDelAds" class="button" href="javascript:void(0)" onclick="document.manageads.cmd.value='del';if (submit_batch_delete()){document.manageads.submit();}else{closeDialogDelete();}">
And then another popup will appear for confirming, but that's another problem.
In fact, the troubles come when I try to find the checkboxes.
This is the code for handling the first part of the site, and findind the checkboxes:
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.keys import Keys
#HANDLING ACCESS
email = "somemail"
password = "somepass"
driver = webdriver.Firefox()
driver.get("https://www.somesite.it/account/manageads")
login_field = driver.find_element_by_id("login_email")
login_field.clear()
login_field.send_keys(email)
login_field = driver.find_element_by_id("login_passwd")
login_field.clear()
login_field.send_keys(password)
login_field.send_keys(Keys.ENTER)
#HANDLING DELETE OF POSTS
while True:
try:
elem = driver.find_element_by_xpath("//input[#type='checkbox' and contains(#name, 'id')")
print("Found")
except NoSuchElementException:
print("End")
break
elem.click()
(I've censored site url and credentials)
print("Found") clause is obviously not executed. The idea was to check consecutively every checkbox, probably I've done this in the wrong way.
What I get instead is "END" in console.
Any help will be strongly appreciated. Thanks in advance.
To trigger the presence of the popup with text as Delete you have to induce WebDriverWait for the desired element_to_be_clickable() and you can use either of the following Locator Strategies:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input[name^='ids'][onclick^='toggleDeleteButtons'][type='checkbox']"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[starts-with(#name, 'ids') and starts-with(#onclick, 'toggleDeleteButtons')][#type='checkbox']"))).click()
Note : You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
You can find a relevant discussion in How to locate a button with a dynamicID

Categories