can sizzle return elements that do not have any attributes? - attributes

I am experimenting with using a sizzle query to extract elements with out attributes from a webpage.
I can easily return an element by specifying its attribute.
Ex: doc.Tables.Filter(Find.BySelector("[ID='abc']")) returns elements with ID='abc'
Is there a way to return all the elements that do not have any attributes at all?
This is what Im shooting for:
doc.Tables.Filter(Find.BySelector("[]")) 'return all element with no attributes
Thanks
Ken

Related

filtering out elements found with beautiful soup based on a key word in any attribute

Here is an example of an url.
url = 'https://rapaxray.com'
# logo
html_content = requests.get(url, headers=headers).text
soup = BeautifulSoup(html_content, "lxml")
images_found = soup.findAll('img', {'src' : re.compile(r'(jpe?g)|(png)|(svg)$')})
images_found
First I'm narrowing down the list of elements to the ones containing jpg, png or svg in a tag. In this case I only get 3 elements. Then I would like to filter those elements to show me only the ones that have a key word 'logo' in ANY attribute.
The element I'm looking for in this example looks like this:
'img alt="Radiology Associates, P.A." class="attachment-full size-full astra-logo-svg" loading="lazy" src="https://rapaxray.com/wp-content/uploads/2019/09/RAPA100.svg"/'
I want to filter out this element out of all elements based on condition that it has a key word 'logo' in ANY of its attributes
The challenge is that:
I have thousands of urls, and key word logo could be in a different attribute for different url
logic: if 'logo' in ANY(attribute for attribute in list_of_possible_attributes_that_this_element_has) doesn't work the same way as list comprehensions because I couldn't find the way of how to access any possible attribute without using its specific name
Checking all specific names is also problematic because particular attribute could exist in one element but not the other which throws error
Case above is also extra challenging because attribute value is a list, so we would need to flatten it to be able to check if the key word is in it.
For most of the urls the element I'm looking for is not returned as the top one like in this example so choosing top first is not an option.
Is there a way of filtering out elements based on a key word in ANY of its attributes? (without prior knowledge of what the name of the attribute is?).
If I understood you correctly, you could use a filter function similar to this answer to search for all tags such that any tag attribute's value contains val:
def my_filter(tag, val):
types = ['.jpg','.jpeg','.svg','.png']
if tag is not None and tag.name == "img" and tag.has_attr("src"):
if all(y not in tag['src'] for y in types):
return False
for key in tag.attrs.keys():
if isinstance(tag[key], list):
if any(val in entry for entry in tag[key]):
return True
else:
if val in tag[key]:
return True
return False
res = soup.find_all(lambda tag: my_filter(tag, "logo"))

Is it possible to find an element by the role attribute in protractor?

As I say in the title, is it possible to find an element by the role attribute in protractor? The attribute is as follows:
role = "menuitem"
I don't know if this item can be found by its attribute
Yes, you can. Here are examples of that:
$('[role = "menuitem"]'); // get one element
$$('[role = "menuitem"]'); // get list of the elements
element(by.css('[role = "menuitem"]')); // get one element
element.all(by.css('[role = "menuitem"]')); // get list of the elements

How to find elements that do not include a certain class name with selenium and python

I want to find all the elements that contain a certain class name but skip the ones the also contain another class name beside the one that i am searching for
I have the element <div class="examplenameA"> and the element <div class="examplenameA examplenameB">
At the moment i am doing this to overcome my problem:
items = driver.find_elements_by_class_name('examplenameA')
for item in items:
cname = item.get_attribute('class')
if 'examplenameB' in cname:
pass
else:
rest of code
I only want the elements that have the class name examplenameA and i want to skip the ones that also contain examplenameB
To find all the elements with class attribute as examplenameA leaving out the ones with class attribute as examplenameB you can use the following solution:
css_selector:
items = driver.find_elements_by_css_selector("div.examplenameA:not(.examplenameB)")
xpath:
items = driver.find_element_by_xpath("//div[contains(#class, 'examplenameA') and not(#class='examplenameB')]")
You can use xpath in this case. So as per your example you need to use something like driver.find_elements_by_xpath('//div[#class='examplenameA'). This will give you only the elements whose class is examplenameA
So how xpath works is : Xpath=//tagname[#attribute='value']
Hence the class is considered as the attribute & xpath will try to match the exact given value, in this case examplenameA, so <div class="examplenameA examplenameB"> will be ignored
In case of find_elements_by_class_name method, it will try to match the element which has the class as examplenameA, so the <div class="examplenameA examplenameB"> will also be matched
Hope this helps

ie getelementsbyID with same ID

i have a script that works with internet explorder (ie) and i need to loop the select fields, that it zelf is no ploblem bu the 4 elements got the same ID (on the same page).
How do i let it loop through the 4 fields?
Can i make them more spesified?
the code i use is the following:
ie.document.getElementByID("DownloadImage").Click
The ie code is the following:
field 1
<a id="DownloadButton" href="javascript:__doPostBack('ctl00$ctl00$MainContent$MainContent$ctl00$declaratiebestandView$RetourInformatieGrid$ctl03$DownloadButton','')">CZ_Specificatie_150005697.pdf</a>
field 2
<a id="DownloadButton" href="javascript:__doPostBack('ctl00$ctl00$MainContent$MainContent$ctl00$declaratiebestandView$RetourInformatieGrid$ctl03$DownloadButton','')">CZ_Specificatie_150005697.pdf</a><input name="ctl00$ctl00$MainContent$MainContent$ctl00$declaratiebestandView$RetourInformatieGrid$ctl03$DownloadImage" class="inlineButton" id="DownloadImage" type="image" src="../images/download.png" text="CZ_Specificatie_150005697.pdf">
then it opens the download screen, and then my code continue's (and works :) )
You can loop them by using querySelectorAll to gather all the elements with an id attribute whose values match what you are after. You can distinguish between them by index. This method will allow you to gather them even though the ids are repeating. However, the HTML you have shared downloads the same document so a loop doesn't seem necessary.
Dim nodeList As Object, i As Long
Set nodeList = ie.document.querySelectorAll("[id=DownloadButton]")
For i = 0 to nodeList.Length-1
nodeList.item(i).Click
Next
That loops all of the matching elements and clicks
By index will be specific but if you familiarize yourself with CSS selectors there are a vast number of possibilities for specifying an element.
The id in HTLM must be unique. If it is not unique it is no valid HTML and should be fixed.
HTML4:
http://www.w3.org/TR/html4/struct/global.html
Section 7.5.2:
id = name [CS]
This attribute assigns a name to an element. This name must be unique in a document.
HTML5:
http://www.w3.org/TR/html5/dom.html#the-id-attribute
The id attribute specifies its element's unique identifier (ID). The
value must be unique amongst all the IDs in the element's home subtree
and must contain at least one character. The value must not contain
any space characters.

Appcelerator adding elements before and after specific elements

Using appcelerator, how do you go about inserting elements before and after specific elements. Such as
<View id='element'>Some Content</View>
Using $.element.add() the new element will be inside it but i need it to go either before or after. In simple terms is there an equivalent to .before and.after in jQuery?
Many thanks
You can use the method insertAt (docs).
If the parent view's layout is horizontal or vertial, then you'll see the children views displayed according to their array positions.
There are 2 workarounds for insert elements before the actual views:
Save the $.elements.children in a array, and unshift the new elements to the array, and add all those views in array to the $.elements;
While you adding the views, set the left or top property (depending on your design), and every time you add a new child, run a loop of the children and increase their left or top property; ex (child views with 200):
$.elements.children[0].left = 0;
$.elements.children[1].left = 200;
$.elements.children[2].left = 400;

Resources