How do I iterate through elements in Selenium and Python? - python-3.x

I am trying to get to the texts inside the span tags by iterating through the li list of this HTML:
<ol class="KambiBC-event-result__score-list">
<li class="KambiBC-event-result__match">
<span class="KambiBC-event-result__points">1</span>
<span class="KambiBC-event-result__points">1</span>
</li>
</ol>
but i am getting the error
AttributeError: 'list' object has no attribute
'find_element_by_class_name'
on my code:
meci = driver.find_elements_by_class_name('KambiBC-event-result__match')
for items in meci:
scor = meci.find_element_by_class_name('KambiBC-event-result__points')
print (scor.text)

You are not using items inside the loop. You loop should be
meci = driver.find_elements_by_class_name('KambiBC-event-result__match')
for items in meci:
scor = items.find_element_by_class_name('KambiBC-event-result__points')
print (scor.text)
meci.find_element_by_class_name should be items.find_element_by_class_name

To answer your second comment, all you need to do is add ":nth-child(2)" to the end of the class name.
The class 'KambiBC-event-result__points' would read 'KambiBC-event-result__points:nth-child(2)' to only access the second child.

Related

Iteration of List Items using selenium in python

I have a dropdown menu with 7 values and these 7 values are stored in the form of list items under unordered list as:
<ul class="rcbList" style="list-style:none;margin:0;padding:0;zoom:1;">
<li class="rcbItem ">--Select--</li>
<li class="rcbHovered ">PIPL-C1-BH-RILJM</li>
<li class="rcbItem ">PIPL-C1-BH1-RILJM</li>
<li class="rcbItem ">PIPL-C1-BH2-RILJM</li>
<li class="rcbItem ">PIPL-C1-BH-RPLJM</li>
<li class="rcbItem ">PIPL-C1-DHJ-RPLJM</li>
<li class="rcbItem ">PIPL-C1-DHJ-RILJM</li>
</ul>
I want to click on each value of this dropdown menu using for loop with the help of selenium chromedriver in python.
Suppose I want to click on 2nd value PIPL-C1-BH-RILJM, I can do it as :
driver.find_element(By.XPATH,"//div[#id='ContentPlaceHolder1_rcmbCapacityTranch_DropDown']/div/ul/li[2]").click()
But to use it in the for loop, I have to do indexing on li tag. So, when I write as:
i=2
driver.find_element(By.XPATH,"//div[#id='ContentPlaceHolder1_rcmbCapacityTranch_DropDown']/div/ul/li['+str(i)+']").click()
It shows only --Select-- and does not select the 2nd value and same happens with other values of i.
I have also tried as:
i=2
driver.find_element(By.XPATH,"//div[#id='ContentPlaceHolder1_rcmbCapacityTranch_DropDown']/div/ul/li['"+str(i)+"']").click()
But --Select-- is selected again from the dropdown menu.
So, can anyone please help me to click on a particular value with indexing on li tag.
Any help would be appreciated.
Try like below once:
Collect all the li tag elements in a list and then iterate over them. Use find_elements for the same.
# This should highlight all the li tags - //div[#id='ContentPlaceHolder1_rcmbCapacityTranch_DropDown']/div/ul/li
options = driver.find_elements(By.XPATH,"//div[#id='ContentPlaceHolder1_rcmbCapacityTranch_DropDown']/div/ul/li")
# This should print 7
print(len(options))
# Start the loop from index 1 since the first option is "--Select--"
for i in range(1,len(options)):
options[i].click()

How to find all the span tag inside of an element in selenium python?

<div id="textelem" class="random">
<span class="a">
TEXT 1
</span>
<span>
<span>TEXT 2 </span>
</span>
<span>TEXT 3</span>
</div>
Python: TargetElem = self.wait.until(EC.presence_of_element_located((By.ID, "textelem")))
I want to get all the text inside of span tags of TargetElem element. How can I get all the span elements inside of TargetElem element and loop through them to get a single string of collected text. Thank you.
simply use .text
TargetElem = self.wait.until(EC.presence_of_element_located((By.ID, "textelem")))
print(TargetElem.text)
I do not think that you actually need a loop, since we are passing textelem id of div and all the span tags are inside the div, so .text should work.

Selenium Can't Find Element Returning None or []

im having trouble accessing element, here is my code:
driver.get(url)
desc = driver.find_elements_by_xpath('//p[#class="somethingcss xxx"]')
and im trying to use another method like this
desc = driver.find_elements_by_class_name('somethingcss xxx')
the element i try to find like this
<div data-testid="descContainer">
<div class="abc1123">
<h2 class="xxx">The Description<span data-tid="prodTitle">The Description</span></h2>
<p data-id="paragraphxx" class="somethingcss xxx">sometext here
<br>text
<br>
<br>text
<br> and several text with
<br> tag below
</p>
</div>
<!--and another div tag below-->
i want to extract tag p inside div class="abc1123", but it doesn't return any result, only return [] when i try to get_attribute or extract it to text.
When i try extract another element using this method with another class, it works perfectly.
Does anyone know why I can't access these elements?
Try the following css selector to locate p tag.
print(driver.find_element_by_css_selector("p[data-id^='paragraph'][class^='somethingcss']").text)
OR Use get_attribute("textContent")
print(driver.find_element_by_css_selector("p[data-id^='paragraph'][class^='somethingcss']").get_attribute("textContent"))

How can i click the third href link?

<ul id='pairSublinksLevel1' class='arial_14 bold newBigTabs'>...<ul>
<ul id='pairSublinksLevel2' class='arial_12 newBigTabs'>
<li>...</li>
<li>...</li>
<li>
<a href='/equities/...'> last data </a> #<-- HERE
</li>
<li>...</li>
Question is how can i get click third li tag ??
In my code
xpath = "//ul[#id='pairSublinksLevel2']"
element = driver.find_element_by_xpath(xpath)
actions = element.find_element_by_css_selector('a').click()
code works partially. but i want to click third li tag.
The code keeps clicking on the second tag.
Try
driver.find_element_by_xpath("//ul[#id='pairSublinksLevel2']/li[3]/a").click()
EDIT:
Thanks #DebanjanB for suggestion:
When you get the element with xpath //ul[#id='pairSublinksLevel2'] and search for a tag in its child elements, then it will return the first match(In your case, it could be inside second li tag). So you can use indexing as given above to get the specific numbered match. Please note that such indexing starts from 1 not 0.
As per the HTML you have shared you can use either of the following solutions:
Using link_text:
driver.find_element_by_link_text("last data").click()
Using partial_link_text:
driver.find_element_by_partial_link_text("last data").click()
Using css_selector:
driver.find_element_by_css_selector("ul.newBigTabs#pairSublinksLevel2 a[href*='equities']").click()
Using xpath:
driver.find_element_by_xpath("//ul[#class='arial_12 newBigTabs' and #id='pairSublinksLevel2']//a[contains(#href,'equities') and contains(.,'last data')]").click()
Reference: Official locator strategies for the webdriver

Jade template engine - Each Iteration Offset

Is there a way to offset the 'each' iteration when using the Jade template engine?
for example, when passing in the object named list:
ul
each item in list
li #{item}
Will output
<ul>
<li> Item 1 </li>
<li> item 2 </li>
<li> item 3.....
...
</ul>
But I want the first item to be displayed differently than the rest of the items, like so:
<ul>
<li> Item 1: First Item in list! </li>
<li> item 2 </li>
<li> item 3.....
...
</ul>
So does anyone know a way to offset the 'each' statement in Jade so that I can render the first item separately and then render each following item starting at the 2nd index?
each item, i in list
li= item
if i === 1
| : First item in list!
If #Johnathan's answer does not work for you:
In Jade 1.7 the following works:
for item, i in list
li= item
if i === 0
| : First item in list!
http://www.learnjade.com/tour/iteration/
Also note the 0 index vs 1 index.

Resources