I would like to select elements by the class name, but only with a specific name(first-level-li), if there are other classes with the name that I am trying to select but followed for other names
(<li class="first-level-li no-second-level shop-link">
<li class="first-level-li no-second-level ">)
, I need to ignore them, how can I do this?
Example:
firstLevelMenu = self.driver.find_elements_by_class_name ( "first-level-li" )
website
<li class="first-level-li no-second-level shop-link">
<li class="first-level-li no-second-level ">
<li class="first-level-li ">
firstlevelMenu = self.driver.find_elements_by_xpath("//li[#class='first-level-li ']")
Docs are here http://selenium-python.readthedocs.io/locating-elements.html
You can use xpath to do the same:
self.driver.find_elements_by_xpath("//li[#class='first-level-li']")
This finds the element that has the exact class name.
You can use xpath as mentioned above with following function too which will directly return object of specific element, instead of list.
self.driver.find_element_by_xpath("//li[#class='first-level-li ']")
Related
I have a web page something like:
<div class='product-pod-padding'>
<a class='header product-pod--ie-fix' href='link1'/>
<div> SKU#1</div>
</div>
<div class='product-pod-padding'>
<a class='header product-pod--ie-fix' href='link2'/>
<div> SKU#2</div>
</div>
<div class='product-pod-padding'>
<a class='header product-pod--ie-fix' href='link3'/>
<div> SKU#3</div>
</div>
When I tried to loop through the products with the following code, it will give us expected outcome:
products=driver.find_elements_by_xpath("//div[#class='product-pod-padding']")
for index, product in enumerate(products):
print(product.text)
SKU#1
SKU#2
SKU#3
However, if I try to locate the href of each product, it will only return the first item's link:
products=driver.find_elements_by_xpath("//div[#class='product-pod-padding']")
for index, product in enumerate(products):
print(index)
print(product.text)
url=product.find_element_by_xpath("//a[#class='header product-pod--ie-fix']").get_attribute('href')
print(url)
SKU#1
link1
SKU#2
link1
SKU#3
link1
What should I do to get the corrected links?
This should make your code functional:
[...]
products=driver.find_elements_by_xpath("//div[#class='product-pod-padding']")
for index, product in enumerate(products):
print(index)
print(product.text)
url=product.find_element_by_xpath(".//a[#class='header product-pod--ie-fix']").get_attribute('href')
print(url)
[..]
The crux here is the dot in front of xpath, which means searching within the element only.
You need to use a relative XPath in order to locate a node inside another node.
//a[#class='header product-pod--ie-fix'] will always return a first match from the beginning of the DOM.
You need to put a dot . on the front of the XPath locator
".//a[#class='header product-pod--ie-fix']"
This will retrieve you a desired element inside a parent element:
url=product.find_element_by_xpath(".//a[#class='header product-pod--ie-fix']").get_attribute('href')
So, your entire code could be as following:
products=driver.find_elements_by_xpath("//div[#class='product-pod-padding']")
for index, product in enumerate(products):
print(index)
url=product.find_element_by_xpath(".//a[#class='header product-pod--ie-fix']").get_attribute('href')
print(url)
My html code looks like:
<li>
<div class="level1">
<div id="li_hw2" class="toggle open" </div>
<ul style="" mw="220">
<li>
<div class ="level2">
...
</li>
</ul>
I am currently on the element with the id = "li_hw2", which was found by
level_1_elem = self.driver.find_element(By.ID, "li_hw2")
Now i want to go from level_1_elem to class = "level2". Is it possible to go to the parent li and than to level2? Maybe with xpath?
Hint: It is neccassary to go via the parent li and not directly to the element level2 with
self.driver.find_element(By.Class_Name, "level2")
The best-suited locator for your usecase is xpath, since you want to traverse upward as well as downwards in the HTMLDOM.
level_1_elem = self.driver.find_element(By.XPATH, "//div[#class='li_hw2']")
and then using level_1_elem web element, You can do the following :
to directly go to following-sibling
level_1_elem.find_element(By.XPATH, ".//following-sibling::ul/descendant::div[#class='level2']")
Are you sure about the html i think the ul should group all the li if it s the case then it s easy if not i realy dont get that html.
//div[#class="level1"]/parent::li/parent::ul/li/div[#class="level2"]
I have this html code
<ul class="select-items">
<li class="select-items-item" data-label="<first>">Number 1</li>
</ul>
and I want to add a new li like <li class="select-items-item" data-label="<second>">Number 2</li>
What i tried so far :
I click the list using the xpath ( that works fine because I can see the list open),
addAttribute to the element (that is the tricky part, not working),
add javascript code ( not working either)
liItem = """
var ul = document.getElementByXpath('//*[#class="select-items"]');
var li = document.createElement("li");
li.appendChild(document.createTextNode("Element 4"));
ul.appendChild(li);
"""
driver.execute_script(liItem);
Any suggestions?
To add the following <li> i.e.
<li class="select-items-item" data-label="<second>">Number 2</li>
You can use the following line of code:
scriptTxt = """
var ul = document.getElementsByClassName('select-items').item(0);
var li = document.createElement('li');
li.setAttribute('textContent', 'Number 2');
ul.appendChild(li);body.appendChild(li);
"""
driver.execute_script(scriptTxt)
References
You can find a couple of relevant detailed discussions in:
Unable to find_element_by_id when element is created via execute_script
I have to crawl data with Scrapy like this:
<div class="data"
data-name="{"id":"566565", "name":"data1"}"
data-property="{"length":"444", "height":"678"}"
>
data1
</div>
<div class="data"
data-name="{"id":"566566", "name":"data2"}"
data-property="{"length":"555", "height":"777"}"
>
data2
</div>
I need data-name and data-property attributes. My selector is:
selections = Selector(response).xpath('//div[#class="data"]/attribute::data-property').extract()
How can I include data-name attribute in selections?
The following XPath should return data-property and data-name attributes :
//div[#class='data']/attribute::*[name()='data-property' or name()='data-name']
XPath Demo : http://www.xpathtester.com/xpath/e720602b62461f3600989be73eb15aec
If you need to return the two attributes as a pair in a certain format for each parent div, then this can't be done using pure XPath 1.0. Some python would be required, maybe using list comprehension (not tested) :
selections = [div.xpath('concat(#data-property, " ", #data-name)').extract() \
for div in Selector(response).xpath('//div[#class="data"]')]
Further to question here.
<a id='1234' href ="http://www.google.com' class='alpha' > MY TEXT </a>
<caption>
<em> ABCD </em>
</caption>
I want to extract text between i.e
id='1234' href ="http://www.google.com' class='alpha'
How to do this using python and selenium.
Use
web_element.get_attribute(attribute_name)
method on the web_element object to get the value of any attribute present in a web_element in this case id, href, class.