Issue in locating web element selenium - python

I am unable to locate a web element on a website, The web elements of the website are dynamic and the elements which i am trying to locate have very similar attributes to that of others with just small differences like changes in integers. These integers also change when i refresh the page so i am unable to locate can someone help?
I tried following but there maybe mistakes in syntaxes:
With contains text = WebDriverWait(browser, 15).until(EC.presence_of_element_located( (By.XPATH,"//div[contains(text(),'Type here...')]") ))
Absolute Xpath and Rel Xpath(these changes)
Contains sibling, contains parents but the parent and sibling elements are also unable to locate
here is the html of the element <div contenteditable="true" class="cke_textarea_inline cke_editable cke_editable_inline cke_contents_ltr placeholder cke_show_borders" tabindex="0" spellcheck="true" role="textbox" aria-label="Rich Text Editor, editor15" title="Rich Text Editor, editor15" aria-describedby="cke_849" style="position: relative;" xpath="1">enter question here</div>

There are spaces being added () which some time cause issue, please deleting that space. Also if you can share html then we might be able to help. WebDriverWait(browser,15).until(EC.presence_of_element_located((By.XPATH,"//div[contains(text(),'Type here...')]")))
I removing space doesn't work then you can try below xpath-
//div[text()='enter question here'][contains(#aria-label,'Rich Text Editor')]

If there are really no attributes you would consider reliable, you can access the element by the text inside of it. I'd recommend two things: Don't do this unless you find no other choice, and don't just use //div, add as much XPATH info to the path as you can.
driver.find_element_by_xpath('//div[text()="enter question here"]')
OR
driver.find_element_by_xpath('//div[contains(text(),"enter question")]')

Related

How do I click on this item using Selenium?

Im trying to automate the download of report using selenium. To get to the page where the report is I have to click on an image with this code
<div class="leaflet-marker-icon single-icon-container running hover asset leaflet-zoom-hide leaflet-clickable" tabindex="0" style="margin-left: -22px; margin-top: -41px; width: 44px; height: 44px; opacity: 1; transform: translate3d(525px, 238px, 0px); z-index: 238;"><div class="icon-value" lid="219058"></div></div>
I tried with
wtg = driver.find_elements_by_class_name(
"leaflet-marker-icon single-icon-container running hover asset leaflet-zoom-hide leaflet-clickable")
wtg.click()
but nothing happens.
There are 7 elements with the same class, and a unique "id " tha looks like lid="219058" but I dont know how to select that.
leaflet-marker-icon single-icon-container running hover asset leaflet-zoom-hide leaflet-clickable contains multiple class names while driver.find_element_by_class_name method intends to get a single class name.
I can't give you a correct locator for this element since you didn't share the page link, however if you wish to locate that element based on these class names combination you can use CSS Selector or XPath as following:
wtg = driver.find_element_by_css_selector(".leaflet-marker-icon.single-icon-container.running.hover.asset.leaflet-zoom-hide.leaflet-clickable")
wtg.click()
Or
wtg = driver.find_element_by_xpath("//*[#class='leaflet-marker-icon single-icon-container running hover asset leaflet-zoom-hide leaflet-clickable']")
wtg.click()
Also you should use driver.find_element_by_class_name, not driver.find_elements_by_class_name since driver.find_elements_by_class_name will give you a list of web elements, not a single web element that can be clicked directly.
Alternatively you can use the first index inside the list of received web elements as described by FLAK-ZOSO
Generally speaking, the best practice when building web scrapers is to always use xpath, since xpath can apply all the filters (id, class, etc) in a more flexible way (in some cases though, performance in selenium might be decreased).
I recommend you check this article on how to write xpaths for various needs: https://www.softwaretestinghelp.com/xpath-writing-cheat-sheet-tutorial-examples/
For your particular use case, I would use:
driver.find_element_by_xpath('//div[#lid="219058"]')
This will actually click on the inner div (notice how the lid is actually inside the nested div). If you wish to click on the outer div you can use:
driver.find_element_by_xpath('//div[#lid="219058"]/parent::div')
I again recommend you to learn Xpath syntax and always use it, it is way easier to manipulate than the other selenium selectors and is also faster in case you ever choose to implement a C compiled html parser such as lxml to parse the elements.
Remember that driver.find_elements_by_class_name() returns a list.
You have to do something like this when using this get/find method:
driver.find_elements_by_class_name('class')[0] #If you want the first of the page
In your case you need to use the css_selector because you have multiple classes, like suggested by #Prophet.
You can also use only one of the classes and simply use the class_name selector.
In your case, if you need the first element of the page with that class, you have to add [0].

selenium exact match based on text

If I have some HTML:
<span class="select2-selection__rendered" id="select2-plotResults-container" role="textbox" aria-readonly="true" title="50">50</span>
And I want to find it using something like:
driver.find_element_by_xpath('//*[contains(text(), "50")]')
The problem is that there is 500 somewhere before on the webpage and it's picking up on that, is there way to search for a perfect match to 50?
Instead of contains, search for a specific text value:
driver.find_element_by_xpath('//*[text()="50"]')
And if you know it will be a span element, you can be a little more specific:
driver.find_element_by_xpath('//span[text()="50"]')
Note that your question asks how to find an element by its text value. If possible and would apply to your situation, you should look for a specific class or id, if known and consistent.
You can search for it by its absolute Xpath. For that, inspect the page and find the element. Then right-click it and copy its Xpath or full Xpath.
Otherwise you can use the id:
driver.find_element_by_id("select2-plotResults-container")
Here is more on locating elements.
use something like this
msg_box=driver.find_element_by_class_name('_3u328') and driver.find_element_by_xpath('//div[#data-tab = "{}"]'.format('1'))

Selecting inner text when using find element by css selector python, selenium and create a loop

im trying to get all link text from a tag p and with a specific class. Then create a loop to find all other similar elements.
how it looks
so far i am using this :
the value i want is in
<div class='some other class'>
<p class='machine-name install-info-entry x-hidden-focus'> text i want
</p> ==$0
installations = browser.find_elements_by_css_selector('p.machine-name.install-info-entry.x-hidden-focus')
any help is appreciated. thanks.
You can just use .text
installations = browser.find_elements_by_css_selector('p.machine-name.install-info-entry.x-hidden-focus')
for installation in installations:
print(installation.text)
Note that installations is a list of web elements, whereas installation is just a web element from the list.
UPDATE1:
If you want to extract the attribute from a web element, then you can follow this code:
print(installation.get_attribute("attribute name"))
You should pass your desired attribute name in get_attribute method.
You can read innerHTML attribute to get source of the content of the element or outerHTML for source with the current element.
installation.get_attribute('innerHTML')
Hope this will be helpful.

Xpath clicking not working at all

Quick info: I'm using Mac OS, Python 3.
I have like 800 links that need to be clicked on a page (and many more pages to go so need automation).
They were hidden because you only see those links when you hover over.
I fixed that by injecting CSS rule (just saying in case its the reason it's not working).
When I try to find elements by xpath it does not want to click the links afterwards and it also doesn't find all of them always just 4 (even when more are displayed in view).
HTML:
Display
When i click ok copy xpath in inspect it gives me:
//*[#id="tiles"]/li[3]/div[2]/ul/li[2]/a
But it doesn't work when I use it like this:
driver.find_elements_by_xpath('//*[#id="tiles"]/li[3]/div[2]/ul/li[2]/a')
So two questions:
How do I get them all?
How do I get it to click on each of them?
The pattern in the XPath is the same, with the /li[3] being the only number that changes, for this I created a for loop to create them all based on the count on page which I did successfully.
So if it can be done with the XPaths generated by myself that are corresponding to when I copy XPath in inspector then I only need question 2 answered.
PS.: this is HTML of parent of that first HTML:
<li onclick="openPopup(event, 'collect', {item_id: 165214})" class="collect" data-item-id="165214">Display</li>
This XPath,
//a[.="Display"]
will select all a links with anchor text equal to "Display".
As per your question, the HTML you have shared and your code attempts there is no necessity to get the <li> tags. Instead we will get the <a> tags in a list. So to answer your first question How do I get them all you can use the following line of code :
all_Display = driver.find_elements_by_xpath("//*[#id='tiles']//li/div[2]/ul/li[#class='collect']/a[#title='Display']")
Next to click on each of them you have to create a loop to iterate through all the <a> tag as follows :
all_Display = driver.find_elements_by_xpath("//*[#id='tiles']//li/div[2]/ul/li[#class='collect']/a[#title='Display']")
for each_Display in all_Display :
each_Display.click()
Using an XPath with elements by position is not ideal. Instead use a CSS selector to match the attributes for the targeted elements.
Something like:
all_Display = driver.find_elements_by_css_selector("#tiles li[onclick][data-item-id] a[title]")
You can then click them in a loop if none of them is loading a new page:
for element in all_Display:
element.click()

Find text and elements with python and selenium?

When I go to a certain webpage I am trying to find a certain element and piece of text:
<span class="Bold Orange Large">0</span>
This didn't work: (It gave an error of compound class names or something...)
elem = browser.find_elements_by_class_name("Bold Orange Large")
So I tried this: (but I'm not sure it worked because I don't really understand the right way to do css selectors in selenium...)
elem = browser.find_elements_by_css_selector("span[class='Bold Orange Large']")
Once I find the span element, I want to find the number that is inside...
num = elem.(what to put here??)
Any help with css selectors, class names, and finding element text would be great!!
Thanks.
EDIT:
My other problem is that there are multiple of those exact span elements but with different numbers inside..how can I deal with that?
you're correct in your usage of css selectors! Also your first attempt was failing because there are spaces in the class name and selenium does not seem to be able to find standalone identifiers with spacing at all. I think that is a bad development practice to begin with, so its not your problem. Selenium itself does not include an html editor, because its already been done before.
Try looking here: How to find/replace text in html while preserving html tags/structure.
Also this one is relevant and popular as well: RegEx match open tags except XHTML self-contained tags

Categories

Resources