I am working with the chrome://extensions page and I met some problems when trying to access a specific element using selenium. I am trying to get the extension id of an extension that I installed. The work flow is as follows:
1. I go to the chrome://extensions page by using driver.get()
2. I get the "developer mode" toggle by using selenium element selector, and click the toggle so that extension id gets shown on the page.
3. I want to use multiple elements selector to select all "extensions-item" element on the page, find the specific extension that I installed, and retrieve the id. But I am stuck at this part because I am able to select one element but not multiple elements for some reason.
I have the following script:
def expand_shadow_element(driver, element):
shadow_root = driver.execute_script(
'return arguments[0].shadowRoot', element)
return shadow_root
def get_extension_id(driver):
root1 = driver.find_element_by_tag_name("extensions-manager")
shadow1 = expand_shadow_element(driver, root1)
shadow2 = shadow1.find_element_by_css_selector("cr-view-manager")
root3 = shadow2.find_element_by_id("items-list")
shadow3 = expand_shadow_element(driver, root3)
i = shadow3.find_element_by_tag_name("extensions-item") # This works fine, but it can only retrieve the first "extensions-item". What if I want the second one?
print("finding single element successful")
items = shadow3.find_elements_by_tag_name("extensions-item") # This line throws an error
for item in items:
shadow4 = expand_shadow_element(driver, item)
if shadow4.find_element_by_id("name").text != "Chrome Automation Extension":
return "Success"
raise "Error"
The error message is as follows:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"extensions-item"}
(Session info: chrome=78.0.3904.97)
Besides, I used find_element_by_tag_name instead of others because others do not work. To my understanding, even if I believe it is essentially the same as find_element_by_css_selector, but using this instead will throw element not found error. I do not understand why.
Anyone has any idea? I just don't know why I am able to locate one element but not a list of them. I am guessing it is because the way I manipulated shadow-dom, but through searching on the Internet I was not able to find another way of manipulating it. Any help is appreciated, thank you!
Related
Currently I'm attemping to switch from my default content, to the only iframe in the website. I don't know if it's how the site is coded, but I can't access via DOM any element.
This is the HTML structure of the site:
XPATH of site is //*[#id="iframeBody"] (When I paste this in the element inspector, I get the correct iframe). So, if I try to switch using frame_to_be_available_and_switch_to_it, this is the output:
try:
WebDriverWait(self.driver, 10).until(ec.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[#id='iframeBody' and #name='body']")))
except Exception as e:
print(e)
>>> Message: javascript error: Failed to execute 'getComputedStyle' on 'Window': parameter 1 is not of type 'Element'.
>>>(Session info: chrome=79.0.3945.88)
I also tried creating an iframe element variable, finding it via ID and XPATH and then I've used switch_to(element). Getting the same result. When I print this variable, the element is actually found:
# Also tried finding with id
element = self.driver.find_element_by_xpath('//iframe[#id='iframeBody')
print(element)
<selenium.webdriver.remote.webelement.WebElement (session="9184691b1fdcccc15dd36bbcb914ac8b", element="1ef77729-8a6e-4d3c-98bd-c95878437585")>
But when I try to switch to this iframe, I get the same result as above.
For some reason, this site is not letting me use the DOM data, actually, when I try to click a button I need to use action chains, because I get the same error.
Anybody can help me?
Did you put enough time before switching ?
also, you could directly switch as well:
driver.switch_to.default_content()
driver.switch_to.frame(driver.find_element_by_id("iframeBody"))
I'm trying to scrape every item on a site that's displayed in a grid format with infinite scrolling. However, I'm stuck on even getting the second item using xpath because it's saying:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//div[#class='el-card advertisement card is-always-shadow'][2]"}
x = 1
while x < 5:
time.sleep(5)
target = driver.find_element_by_xpath(f"//div[#class='el-card advertisement card is-always-shadow'][{x}]")
target.click()
wait.until(EC.visibility_of_element_located((By.ID, "details")))
print(driver.current_url)
time.sleep(5)
driver.back()
time.sleep(5)
WebDriverWait(driver, 3).until(EC.title_contains("Just Sold"))
time.sleep(5)
x += 1
With my f-string xpath it's able to find the first div with that class and print the URL, but the moment it completes one iteration of the while loop, it fails to find the 2nd div with that class (so 2).
I've tried monitoring it with all the time.sleep() to see exactly where it was failing because I thought maybe it was running before the page loaded and therefore it couldn't be found, but I gave it ample time to finish loading every page and yet I can't find the issue.
This is the structure of the HTML on that page:
There is a class of that name (as well as "el-card__body" which I have also tried using) within each div, one for each item being displayed.
(This is what each div looks like)
Thank you for the help in advance!
(disclaimer: this is for a research paper, I do not plan on selling/benefiting off of the information being collected)
Storing each item in a list using find_elements_by_xpath, then iterating through them did the trick, as suggested by tdelaney.
I am trying to find an element on the Autotask webpage in order to interact with it:
I'm using the following code to search within elements:
header=driver.find_element_by_css_selector('html')
body=header.find_element_by_css_selector('body')
body1=body.find_element_by_css_selector('#WorkspaceContainer')
body1.find_element_by_css_selector('#WorkspaceContainer > div:nth-child(1)')
body2=body1.find_element_by_css_selector('#WorkspaceContainer > div:nth-child(1)')
body2.find_element_by_css_selector('#PageContainer')
body3=body2.find_element_by_css_selector('#PageContainer')
body3.find_element_by_css_selector('#PageContainerFrame')
body4=body3.find_element_by_css_selector('#PageContainerFrame')
body4.find_element_by_css_selector('html')
body5=body4.find_element_by_css_selector('html')
body5.find_element_by_css_selector('body')
body6=body5.find_element_by_css_selector('body')
It seemed like I was successfully navigating through them, but it fails at this line with the exception:
body4.find_element_by_css_selector('html')
selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: {"method":"css selector","selector":"html"}
I was using mouse movements and clicks via pyautogui module to interact with the site, but I've been told that interacting with the element itself is more reliable. Can anyone assist?
Seems that you're trying to handle element inside an iframe.
To do this you need to switch to this frame at first:
body3.switch_to_frame('PageContainerFrame')
body3.find_element_by_css_selector('html')
P.S. If you need to handle just one element, you'd better to point on it directly with relative XPath instead of consecutive stepping from parent elements to child...
I'm trying to get the XPATH for Code Generator field form (Facebook) in order to fill it (of course before I need to put a code with "numbers").
In Chrome console when I get the XPATH I get:
//*[#id="approvals_code"]
And then in my test I put:
elem = driver.find_element_by_xpath("//*[#id='approvals_code']")
if elem: elem.send_keys("numbers")
elem.send_keys(Keys.ENTER)
With those I get:
StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
What means wrong field name. Does anyone know how to properly get a XPATH?
This error usually comes if element is not present in the DOM.
Or may be element is in iframe.
I am using python selenium on browser to fill in some form. I was trying to select an element in the drop-down list,
0
but if I try to find it by text using this script:
browser.find_element_by_link_text("0").click()
it result an error:
"unknown error: Element is not clickable at point (498, 612). Other element would receive the click: ..."
and if try to find it by class name:
browser.find_element_by_class_name("dropdown-toggle").click()
it result in another error: "element not visible"
is there any way I can click onto that drop-down list? Thanks very much.
I had a similar problem. You can execute a script to change the visibility of that element once you find it and then click it.
driver.execute_script("arguments[0].style.visibility = 'visible';",myElement)
myElement.click()
Try to find it by Xpath searching for partial class and text at the same time:
browser.find_element_by_xpath(//a[contains(#class, 'dropdown-toggle select') and contains(text(), '0')]).click();
you should get the element by xpath and then press it.
browser.find_element_by_xpath(xpath).
read here how to get the xpath: http://www.wikihow.com/Find-XPath-Using-Firebug
Thanks for the feedback, I've found the problem which was due to the new script being loaded by javascript as triggered by some clicks. I've created the following code to capture the exception and retrying until the element is ready:
while True:
try:
time.sleep(1)
browser.find_element_by_xpath("//div[#class='tckt']/a").click()
print("found")
break
except ElementNotVisibleException:
print("notvisible")
except WebDriverException:
print("clickduplicate")
I read it on articles says this happened a lot on radio button for Chrome webdriver, hope this helps.
Firstly click the parent element by finding it, using it's xpath->find the element you want to click within the parent element like the way you did. i.e
browser.find_element_by_link_text("0").click()
Hope this 2 steps will work for you. Otherwise please post the url with the code you've tried-It'll be easy to find out the issue.