I've been up on this for 2 days.

Trying to get all Text(s) from span(s), which appear in many div(s).

All the div(s) looks pretty much the same :

<div class="_3_7SH _3DFk6 message-in">
<div class="Tkt2p">
<div class="copyable-text" data-pre-plain-text="[10:26 AM, 5/28/2019] יוסף צדוק: ">
<div class="_3zb-j ZhF0n">
<span dir="rtl" class="XELVh selectable-text invisible-space copyable-text">TEXT TO COPY IS ME</span></div></div>
<div class="_2f-RV"><div class="_1DZAH">
<span class="_1ORuP">
</span><span class="_3EFt_">10:26 AM</span></div></div></div><span></span></div>

This is how tried to find ALL "message-in" elements :

in_mesg_arr = driver.find_elements_by_xpath("//div[contains(@class, 'message-in')]")

I got back the length of the array: 11

Then, tried to get all text from span(s):

for index in in_mesg_arr:
   last_msg = last_msg + str(index.find_element_by_xpath(
    "//span[contains(@class,'selectable-text invisible-space copyable-text')]").text)

HOWEVER, i get back the same text (same element over and over!).

print(last_msg) = bla bla bla bla bla bla bla bla bla bla bla

Will be glad to get some directions.

FULL HTML:

3 Answers

2
Kajal Kundu On Best Solutions
for index in last_msg:
   last_msg = last_msg + str(in_mesg_arr[index].find_element_by_xpath(
    "//span[contains(@class,'selectable-text invisible-space copyable-text')]").text)

This code will always returns the 1st element because it will search span element any where in the DOM.

The XPath expression in the loop has to start with a dot to be context-specific.Use any of the following code.

 in_mesg_arr = driver.find_elements_by_xpath("//div[contains(@class, 'message-in')]")
    for item in in_mesg_arr:
        spanele=item.find_element_by_xpath(".//span[contains(@class,'selectable-text invisible-space copyable-text')]")
        print(spanele.text)

OR

in_mesg_arr = driver.find_elements_by_xpath("//div[contains(@class, 'message-in')]")

for item in range(len(in_mesg_arr)):
    spanele=in_mesg_arr[item].find_element_by_xpath(".//span[contains(@class,'selectable-text invisible-space copyable-text')]")
    print(spanele.text)

Let me know how it goes.

0
qaiser On

These can be done using BeautifulSoup

from bs4 import BeautifulSoup
content = '''
    <div> class = "*something* message-in *something*" <div>
    <span> class = "selectable-text invisible-space copyable-text" <span>
    '''
soup = BeautifulSoup(content,"lxml")

span_text =  [x.get_text() for x in  soup.find_all('span')]



html_con = '''
<div class="_3_7SH _3DFk6 message-in">
<div class="Tkt2p">
<div class="copyable-text" data-pre-plain-text="[10:26 AM, 5/28/2019] יוסף צדוק: ">
<div class="_3zb-j ZhF0n">
<span dir="rtl" class="XELVh selectable-text invisible-space copyable-text">TEXT TO COPY IS ME</span></div></div>
<div class="_2f-RV"><div class="_1DZAH">
<span class="_1ORuP">
</span><span class="_3EFt_">10:26 AM</span></div></div></div><span></span></div>
<div class="_3_7SH _3DFk6123456 message-in">
<div class="Tkt2p">
<div class="copyable-text" data-pre-plain-text="[10:26 AM, 5/28/2019] יוסף צדוק: ">
<div class="_3zb-j ZhF0n">
<span dir="rtl" class="XELVh selectable-text invisible-space copyable-text">New text</span></div></div>
<div class="_2f-RV"><div class="_1DZAH">
<span class="_1ORuP">
</span><span class="_3EFt_">10:26 AM</span></div></div></div><span></span></div>
'''

soup = BeautifulSoup(html_con)

content_message_in= soup.find_all('div', {'class': 'message-in'})
span_content =[x.find_all('span') for x in content_message_in]
span_text  = [x[0].get_text() for x in span_content]


#o/p
['TEXT TO COPY IS ME', 'New text']
0
Community On

Could it be that when you are getting the spans, you are using

find_element_by_xpath 

instead of

find_elements_by_xpath

So its just returning the first element that matches, every time.

see the answer for this question: https://sqa.stackexchange.com/questions/37380/find-elements-by-xpath-issue?answertab=votes#tab-top