I am trying to create an automation program. I want to click on the "Accept Cookies" shadowbox on the given website.
Here's how I have tried to achieve this:
driver = webdriver.Chrome('chromedriver')
driver.get(r'https://www.studydrive.net/')
script = '''return document.querySelector('#usercentrics-root').shadowRoot.querySelector('button[aria-label="Accept All"]')'''
accept_all_btn = driver.execute_script(script)
accept_all_btn.click()
Here's the error that I get after following this approach:
AttributeError: 'NoneType' object has no attribute 'click'
I don't know, what I am doing wrong here. Any help is appreciated. Thank you in advance.
wait=WebDriverWait(driver, 60)
driver.get("https://www.studydrive.net/")
elem = wait.until(EC.presence_of_element_located((By.ID,"usercentrics-root")))
script = '''return document.querySelector('#usercentrics-root').shadowRoot.querySelector('button[data-testid="uc-accept-all-button"]')'''
accept_all_btn = driver.execute_script(script)
accept_all_btn.click()
Simply wait for the element and then proceed to click the accept all button. No aria-label was specified so I used another attribute.
Imports:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
The element Accept all button is within a #shadow-root (open)
Solution
Tto click() on the desired element you need to use shadowRoot.querySelector()
You can use the following Locator Strategy:
driver = webdriver.Chrome(service=s, options=options)
driver.get("https://www.studydrive.net/")
time.sleep(5)
accept_all = driver.execute_script('''return document.querySelector("#usercentrics-root").shadowRoot.querySelector("button[data-testid='uc-accept-all-button']")''')
accept_all.click()
PS: The cookie popup surfaces on the screen after significant amount of time, so you may have to induce some waits
References
You can find a couple of relevant detailed discussions in:
How to locate the First name field within shadow-root (open) within the website https://www.virustotal.com using Selenium and Python
How to get past a cookie agreement page using Python and Selenium?
Unable to locate the Sign In element within #shadow-root (open) using Selenium and Python
Related
This question already has answers here:
Click on ember.js enabled element using Selenium
(5 answers)
Closed 1 year ago.
At this stage, all the script aims to do is to locate the search bar in a digital library, send the name of the resource I am looking for, click on it and get the current url. The first bit (sending keys to search bar) works fine. But I have noticed that the second try/finally block only executes when I right click and inspect any element on the page. If I don't, I get the following error message :
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"[id="ember767"]"}
My code:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.action_chains import ActionChains
PATH = "/Applications/chromedriver"
ser = Service(PATH)
driver = webdriver.Chrome(service=ser)
driver.maximize_window()
driver.implicitly_wait(20)
driver.get("https://browzine.com/libraries/1374/subjects")
print("Enter targeted Journal name:")
targeted_journal = input()
wait = WebDriverWait(driver, 10)
try:
button = driver.find_element(By.ID, "ember648")
driver.implicitly_wait(10)
ActionChains(driver).move_to_element(button).click(button).perform()
button.send_keys(targeted_journal)
button.send_keys(Keys.RETURN)
finally:
pass
# step 2 : click targeted journal and get current url
try:
driver.implicitly_wait(20)
click_journal = driver.find_element(By.ID, "ember767")
ActionChains(driver).move_to_element(click_journal).click(click_journal).perform()
targeted_url = driver.current_url
finally:
pass
print(targeted_url)
driver.quit()
Update - answer found
The ID initially collected for the targeted element was a dynamic one. It was only as such when the developer tools window was open. Therefore the script was only able to detect that particular ID when "Inspect element" was clicked as it was the only case in which the targeted element was assigned this particular ID ("ember767" in my case).
To avoid this issue, an Xpath was used to locate the element instead. See Mayank Shukla's answer below.
In some cases, element's ID or other attributes changes or attribute's value appears on mouse hover. So it's preferred to use xpath for locating such elements
In this scenario, I think the element's id is changing after you are hovering the mouse. Try using xpath and let me know if that works. Because might be after browser refresh this is happening i.e. element's id is changing.
I'm trying to close a modal with the 'x' button but I'm getting this error 'list' object has no attribute 'click' so I looked for other answers and they said to use close_button[0].click() since find_by_element stores a list but still getting error as IndexError: list index out of range
I need help to close this modal
my code
close_button=browser.find_elements_by_xpath('//*[#id="prefix-overlay-header"]/button')
close_button[0].click()
The element that I'm trying to access and close.
My 2c using Expected Conditions (waits):
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
driver = webdriver.Firefox()
wait = WebDriverWait(driver, 10)
driver.maximize_window()
driver.get('https://site.tld')
el = wait.until(EC.element_to_be_clickable((By.XPATH, '//button[text()="Close subscription dialog"]')))
el.click()
Based on your comment, you may want to use the following code after "click is executed" and which opens a new tab:
wait.until(EC.number_of_windows_to_be(2)) # wait for 2 tabs (windows) to be open
driver.switch_to_window(driver.window_handles[1]) # switch to newly opened tab
It is because your a trying to find the elements by
browser.find_elements_by path
Note that you can see elements. Elements is a list.It is plural
Try this:
browser.find_element_by_path
And then use closebutton.click()
I found the answer. As there is a space you should use css selector. The important things are the points(.)
close_button = browser.find_element_by_css_selector('.prefix-overlay-close.prefix-overlay-action-later')
close_button.click()
It worked for me in your given website. Please check once
I am new to Selenium. I am using Selenium 3.141 from anaconda on OSX. My Chrome version is 71.0 and Chromedriver version is 2.45. My goal is to use Selenium to click on a button with "Accept" on it on a webpage. I am able to instantiate the webdriver object using the executable and use the same to load the page in question. I then have a wait for 20 seconds. It's the next bit that fails. Code is unable to find the element that has to be clicked on. Attached are two images of elements associated with the button at various levels and sublevels with highlighted parts from inspection. I have tried variants such as
accept_button = driver.find_element_by_class_name('flex-x.static.h- center.v-center.bt-button.filled')
and
accept_button = driver.find_element_by_class_name('Accept')
and a few others to no avail. Please help.
Button frame:
Accept rectangle:
The desired element is an Angular element so to locate/click you have to induce WebDriverWait for the element to be clickable and you can use either of the following solutions:
Using CSS_SELECTOR:
accept_button = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "bt-button.Aceept.ng-isolate-scope[mutable-label='prelogin.translations.Accept']")))
Using XPATH:
accept_button = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//bt-button[#class='Aceept ng-isolate-scope focused' and #mutable-label='prelogin.translations.Accept']")))
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
did you see bt-button.Accept.ng-isolate-scope.focused you can use it for selecting using css selector
accept_button = driver.find_element_by_css_selector('bt-button.Accept.ng-isolate-scope.focused')
# or
accept_button = driver.find_element_by_css_selector('bt-button.Accept')
I would suggest you to check if the element you trying to interact with is in iframe.
To identify this you can: Right click on the element, If you find the option like 'This Frame' then it is an iframe; or you can just search in page source for iframe tag to identify.
you can refer to this question for further solution if indded your element is part of iframe: Select iframe using Python + Selenium
I can't find a solution how this element cannot be found by using a selenium xpath. Other button on other websites always working just fine. Usually what I would normally do is, just open up a page and inspect the element and I would right click it and copy the xpath. Done.
But this website, www.gsc.com.my (a malaysian cinema booking site). Seems not able to find the button. Is it protected by another security layer?
Lets see the code below,
from selenium import webdriver
chromedriver_path = './chromedriver.exe'
driver = webdriver.Chrome(chromedriver_path)
driver.get('https://www.gsc.com.my')
driver.find_element_by_xpath("""//*[#id="btnNext"]""").click()
The error Message:
no such element: Unable to locate element: {"method":"xpath","selector":"//*[#id="btnNext"]"}
Button is located inside an iframe, so you need to switch to that frame before clicking the button:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait as wait
from selenium.webdriver.support import expected_conditions as EC
driver.switch_to.frame('getQuickFilter_ctrl_ifrBox')
wait(driver, 10).until(EC.element_to_be_clickable((By.ID, "btnNext"))).click()
Because there are two elements with id btnNext, you'll have to specify which of them using an index, 1 for the first, 2 for the second.
driver.find_element_by_xpath("""//*[#id="btnNext"][1]""").click()
You can try with this css selector :
div.container input#btnNext
Note that you will need to switch to iframe first , cause the check button is in a iframe.
For switching to iframe :
driver.switch_to.frame(driver.find_element_by_id("getQuickFilter_ctrl_ifrBox"))
and for clicking on check Button
wait = WebDriverWait(driver, 10)
check_button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div.container input#btnNext")))
check_button.click()
How do I use Python to simply find a link containing text/id/etc and then click that element?
My imports:
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.keys import Keys
Code to go to my URL:
browser = webdriver.Firefox() # Get local session of firefox
browser.get(myURL) # Load page
#right here I want to look for element containing "Click Me" in the text
#and then click it
Look at method list of WebDriver class - http://selenium.googlecode.com/svn/trunk/docs/api/py/webdriver_remote/selenium.webdriver.remote.webdriver.html
For example, to find element by its ID and click it, the code will look like this
element = browser.find_element_by_id("your_element_id")
element.click()
Hi there are a couple of ways to find a link (or any element):
element = driver.find_element_by_id("element-id")
element = driver.find_element_by_name("element-name")
element = driver.find_element_by_xpath("//input[#id='element-id']")
element = driver.find_element_by_link_text("link-text")
element = driver.find_element_by_class_name("class-name")
I think the best option for you is find_element_by_link_text since it's a link.
Once you saved the element in a variable, you call the click function: element.click() or element.send_keys(Keys.RETURN)
Take a look to the selenium-python documentation, there are a couple of examples there.
You just use this code
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
driver = webdriver.Firefox()
driver.get("https://play.spotify.com/")# here change your link
wait=WebDriverWait(driver,250)
# it will wait for 250 seconds an element to come into view, you can change the #value
submit=wait.until(EC.presence_of_element_located((By.LINK_TEXT, 'Click Me')))
submit.click()
here wait is best fit for javascript enabled website let suppose if you load the page in webdriver but due to javascript some element loads after some second then it best suite to use wait element there.
for link containing text
browser = webdriver.firefox()
browser.find_element_by_link_text(link_text).click()
You can also do it by xpath:
Browser.find_element_by_xpath("//a[#href='you_link']").click()
Finding Element by Link Text
driver.find_element_by_link_text("")
Finding Element by Name
driver.find_element_by_name("")
Finding Element By ID
driver.find_element_by_id("")
Try SST - it is a simple yet very good test framework for python.
Install it first: http://testutils.org/sst/index.html
Then:
Imports:
from sst.actions import *
First define a variable - element - that you're after
element = assert_element(text="some words and more words")
I used this: http://testutils.org/sst/actions.html#assert-element
Then click that element:
click_element('element')
And that's it.
First start one instance of browser. Then you can use any of the following methods to get element or link. After locating the element you can use element.click() or element.send_keys(Keys.RETURN) or any other object of selenium webdriver
browser = webdriver.Firefox()
Selenium provides the following methods to locate elements in a page:
To find individual elements. These methods will return individual element.
browser.find_element_by_id(id)
browser.find_element_by_name(name)
browser.find_element_by_xpath(xpath)
browser.find_element_by_link_text(link_text)
browser.find_element_by_partial_link_text(partial_link_text)
browser.find_element_by_tag_name(tag_name)
browser.find_element_by_class_name(class_name)
browser.find_element_by_css_selector(css_selector)
To find multiple elements (these methods will return a list). Later you can iterate through the list or with elementlist[n] you can locate individual element from list.
browser.find_elements_by_name(name)
browser.find_elements_by_xpath(xpath)
browser.find_elements_by_link_text(link_text)
browser.find_elements_by_partial_link_text(partial_link_text)
browser.find_elements_by_tag_name(tag_name)
browser.find_elements_by_class_name(class_name)
browser.find_elements_by_css_selector(css_selector)
browser.find_element_by_xpath("")
browser.find_element_by_id("")
browser.find_element_by_name("")
browser.find_element_by_class_name("")
Inside the ("") you have to put the respective xpath, id, name, class_name, etc...