Home > database >  BeautifulSoup get text between tags for one line
BeautifulSoup get text between tags for one line

Time:12-04

I have a bunch of HTML documents of GCOV branch and line coverage tools, the files look like this:

<tr>
<td align="right" class="lineno"><pre>224</pre></td>
<td align="right" class="linebranch"><span class="takenBranch" title="Branch 1 taken 329 times">&check;</span><span class="notTakenBranch" title="Branch 2 not taken">&cross;</span><span class="notTakenBranch" title="Branch 4 not taken">&cross;</span><span class="takenBranch" title="Branch 5 taken 329 times">&check;</span><br/><span class="notTakenBranch" title="Branch 6 not taken">&cross;</span><span class="takenBranch" title="Branch 7 taken 329 times">&check;</span></td>
<td align="right" class="linecount coveredLine"><pre>329</pre></td>
<td align="left" class="src coveredLine"><pre>        line of C   code</pre></td>
</tr>

<tr>
<td align="right" class="lineno"><pre>225</pre></td>
<td align="right" class="linebranch"></td>
<td align="right" class="linecount uncoveredLine"><pre></pre></td>
<td align="left" class="src uncoveredLine"><pre>   another line of  C   code;</pre></td>
</tr>

I would like to extract the text "(another) line of C " code and ideally also the line number so the output would look like this:

224 line of C   code
225 another line of C   code

I tried to use BeautifulSoup but it does not provide the requested output, my code looks like this:

from itertools import islice
import codecs
import glob
from ntpath import join
import os
from bs4 import BeautifulSoup

lineNo = "<td align=\"right\" class=\"lineNo\"><pre>"
linetextCovered = "<td align=\"left\" class=\"src coveredLine\"><pre>"
linetextNotCovered = "<td align=\"left\" class=\"src uncoveredLine\"><pre>"
open('Output.txt', 'w').close() #Erase any content of Output.txt file

for filepath in glob.iglob('path/To/Reports/*.html'):
    with codecs.open(os.path.join(filepath), "r") as inputFile, open('Output.txt',"a") as outputFile:
        for num, line in enumerate(inputFile, 1):
            if lineNo in line:
                inputSoup = BeautifulSoup(line)
                text = inputSoup.getText()
                outputFile.write("".join(islice(text, 1)   "\t"))
            if linetextCovered or linetextNotCovered in line:
                inputSoup = BeautifulSoup(line)
                text = inputSoup.getText()
                outputFile.write("".join(islice(text, 4)))
            outputFile.write("\n")
print("Done")

But the output looks like this

/* L
a:li
{

colo
text
}

What am I doing wrong? Thank you very much for any help.

CodePudding user response:

You can do like this:

from bs4 import BeautifulSoup

html = '''
<tr>
<td align="right" ><pre>224</pre></td>
<td align="right" ><span  title="Branch 1 taken 329 times">&check;</span><span  title="Branch 2 not taken">&cross;</span><span  title="Branch 4 not taken">&cross;</span><span  title="Branch 5 taken 329 times">&check;</span><br/><span  title="Branch 6 not taken">&cross;</span><span  title="Branch 7 taken 329 times">&check;</span></td>
<td align="right" ><pre>329</pre></td>
<td align="left" ><pre>        line of C   code</pre></td>
</tr>

<tr>
<td align="right" ><pre>225</pre></td>
<td align="right" ></td>
<td align="right" ><pre></pre></td>
<td align="left" ><pre>   another line of  C   code;</pre></td>
</tr>
'''


for tr in BeautifulSoup(html.encode(), 'html.parser').find_all('tr'):
    lineno  = tr.find('td',{'class':'src'}).text.strip()
    src     = tr.find('td', {'class':'lineno'}).text.strip()
    print(lineno, src)
  • Related