I have a template htm file with a table in it, which has one column and looks like this:
<table>
<tr>
<td>ROWNAME1</td>
</tr>
<tr>
<td>ROWNAME2</td>
</tr>
</table>
I'm trying to create new td tags by iterating over the tr tags in the template and appending a new td inside every tr tag, so it will look like this, if I iterate over one of my input files:
<table>
<tr>
<td>ROWNAME1</td>
<td>ROWNAME1</td>
</tr>
<tr>
<td>ROWNAME2</td>
<td>ROWNAME2</td>
</tr>
</table>
So, I'm basically copying the first td tag in a tr and appending it to the original template html. This happens by iterating over the rows (tr tags) of my template html. At each row, I fill the contents of a newly created td with the contents from a separate input file, which has a corresponding td tag with new information in it. The idea is to take a column from an input file and append it to the table in the template html. Each file I iterate over adds a new column to the table in the template.
This works fine for the first file. I can append the first new column to my template html no problem. But when I try to add the next column, the script throws the following error:
File "C:\Users\Chris\Desktop\Nothing\Henke Skripte\HTML_Tables_transform\Run\temp\Parameter_Tables.py", line 124, in content_replacer
parent_tag.append(new_td)
File "C:\Python\Python38\lib\site-packages\bs4\element.py", line 351, in append
self.insert(len(self.contents), tag)
File "C:\Python\Python38\lib\site-packages\bs4\element.py", line 315, in insert
new_child.previous_element = previous_child._last_descendant(False)
File "C:\Python\Python38\lib\site-packages\bs4\element.py", line 268, in _last_descendant
last_child = last_child.contents[-1]
File "C:\Python\Python38\lib\site-packages\bs4\element.py", line 992, in __getitem__
return self.attrs[key]
KeyError: -1
Apparently, appending the new td works over 20 times, when I do it for the first column/input file. But directly when the next input file is used and I try to add the second column, a bs4 function tries to access the attrs dictionary of the newly appended td with the key "-1", which does not exist and I don't know why it would think that the key -1 should exist in the first place.
Here's my shortened code with an additional print of the td that causes the problem:
def content_replacer(parent_tag,content,parent_html):
'''Takes a td, replaces the content appropriately and returns it.'''
html_content = BeautifulSoup(content,features='html.parser')
# Go down the hierachy of children of td to create new td with the full formatting.
td_tag = parent_tag.select('td')
if len(td_tag) > 1:
print(td_tag[0].prettify())
print(td_tag[0].attrs)
new_td = parent_html.new_tag('td', attrs=td_tag[0].attrs)
parent_tag.append(new_td)
p_tag = parent_tag.select('p')
new_p = parent_html.new_tag('p', attrs=p_tag[0].attrs)
new_td.append(new_p)
span_tag = parent_tag.select('span')
new_span = parent_html.new_tag('span', attrs=span_tag[0].attrs)
new_p.append(new_span)
new_span.contents = html_content
# mainloop over input files and tr tags.
all_input_files = glob('*.html')
htm_file = html_parser('template.htm')
nrows = len(htm_file.table.find_all('tr'))
row_name_cleaner = lambda tag: re.sub('[ ]{2,}',' ',tag.text.strip().replace('\n',''))
for i in range(len(all_input_files)):
# html_parser just reads in htmls and turns them to soup.
input_file = html_parser(all_input_files[i])
# content_dictionary creates a dict of input data to be input into the new td tags
content_dict = content_dictionary(input_file)
for j in range(nrows):
# get current row (tr tag)
htm_row = htm_file.table.select('tr')[j]
# Get info on current row.
row_name = row_name_cleaner(htm_row)
# Translate row name into slicing string for content_dict
slice_string = slice_string_translator(row_name)
# Get new content from input file
new_content = content_dict[slice_string]
content_replacer(htm_row,new_content,htm_file)
The print of the faulty td that is supposed to be appended looks like this:
<td style="width:163.55pt;border-top:solid windowtext 1.0pt;
border-left:none;border-bottom:solid windowtext 1.0pt;border-right:none;
mso-border-top-alt:solid windowtext .5pt;mso-border-bottom-alt:solid windowtext .5pt;
padding:0cm 5.4pt 0cm 5.4pt;height:11.45pt" width="218">
<p align="center" class="MsoNormal" style="margin-bottom:0cm;margin-bottom:.0001pt;
text-align:center;line-height:normal">
<span style='font-size:10.0pt;
font-family:"CMU Serif"'>
Compound
<o:p>
</o:p>
</span>
</p>
</td>
{'width': '218', 'style': 'width:163.55pt;border-top:solid windowtext 1.0pt;\n border-left:none;border-bottom:solid windowtext 1.0pt;border-right:none;\n mso-border-top-alt:solid windowtext .5pt;mso-border-bottom-alt:solid windowtext .5pt;\n padding:0cm 5.4pt 0cm 5.4pt;height:11.45pt'}
Traceback (most recent call last):
File "C:\Users\Chris\Desktop\Nothing\Henke Skripte\HTML_Tables_transform\Run\temp\Parameter_Tables.py", line 165, in <module>
content_replacer(htm_row,new_content,htm_file)
File "C:\Users\Chris\Desktop\Nothing\Henke Skripte\HTML_Tables_transform\Run\temp\Parameter_Tables.py", line 124, in content_replacer
parent_tag.append(new_td)
File "C:\Python\Python38\lib\site-packages\bs4\element.py", line 351, in append
self.insert(len(self.contents), tag)
File "C:\Python\Python38\lib\site-packages\bs4\element.py", line 315, in insert
new_child.previous_element = previous_child._last_descendant(False)
File "C:\Python\Python38\lib\site-packages\bs4\element.py", line 268, in _last_descendant
last_child = last_child.contents[-1]
File "C:\Python\Python38\lib\site-packages\bs4\element.py", line 992, in __getitem__
return self.attrs[key]
KeyError: -1
Here's the full tr tag where the error occurs.
<tr style="mso-yfti-irow:0;mso-yfti-firstrow:yes;height:11.45pt">
<td style="width:163.55pt;border-top:solid windowtext 1.0pt;
border-left:none;border-bottom:solid windowtext 1.0pt;border-right:none;
mso-border-top-alt:solid windowtext .5pt;mso-border-bottom-alt:solid windowtext .5pt;
padding:0cm 5.4pt 0cm 5.4pt;height:11.45pt" width="218">
<p align="center" class="MsoNormal" style="margin-bottom:0cm;margin-bottom:.0001pt;
text-align:center;line-height:normal"><span style='font-size:10.0pt;
font-family:"CMU Serif"'>Compound<o:p></o:p></span></p>
</td>
<td style="width:163.55pt;border-top:solid windowtext 1.0pt;
border-left:none;border-bottom:solid windowtext 1.0pt;border-right:none;
mso-border-top-alt:solid windowtext .5pt;mso-border-bottom-alt:solid windowtext .5pt;
padding:0cm 5.4pt 0cm 5.4pt;height:11.45pt" width="218">
<p align="center" class="MsoNormal" style="margin-bottom:0cm;margin-bottom:.0001pt;
text-align:center;line-height:normal"><span style='font-size:10.0pt;
font-family:"CMU Serif"'>Compound<o:p></o:p></span></p>
<p align="center" class="MsoNormal" style="margin-bottom:0cm;margin-bottom:.0001pt;
text-align:center;line-height:normal"><span style='font-size:10.0pt;
font-family:"CMU Serif"'>PK59zni_co_100K_red</span></p></td></tr>