我正在接收一个html格式的表格,需要遍历它以找到一个设置为rowspan的标签.一旦找到包含rowspan=<a number>的单元格,我需要插入一段代码:

<tr>
<th rowspan="14" >Words</th>
<td style="height: 30px;"></td>
<td style="text-align: center; height: 30px;"></td>
<td style="height: 30px;"></td>
<td style="text-align: right; padding: 7px; min-width: 75px"></td>
<td style="height: 30px;"></td>
<td style="height: 30px;"></td>
<td style="height: 30px;"></td>
</tr>\n

作为当前行上方的行.然后,我需要从当前行中删除这<th>.

例如,这是我要搜索的代码:

<table border="1" class="dataframe" style="border: 1px solid grey">
<tbody>
    <tr>
      <th>Records</th>
      <th>Worth</th>
      <td>30</td>
      <td>is</td>
      <td>50</td>
      <td>0</td>
      <td>good</td>
      <td></td>
    </tr>
    <tr>
      <!-- this is the code im looking for -->
      <th rowspan="13" valign="top">Reports</th>
      <!--  -->
      <th>Worth</th>
      <td>30</td>
      <td>=</td>
      <td>40</td>
      <td>0</td>
      <td>bad</td>
      <td></td>
    </tr>
    <tr>
      <th>Worth</th>
      <td>is</td>
      <td>44</td>
      <td>400.0</td>
      <td></td>
      <td>bad</td>
      <td></td>
    </tr>
</tbody>
</table>

因此,一旦找到具有rowspan<th>,我需要将块作为其上方的行插入,然后从当前行中删除<th>.我现在是这样做的:

for child in soup.tbody.descendants:
        if child.name == 'th':
            if 'rowspan' in child.attrs:
                new_row = <<that block from above>>
                crazy_tag = bs4.BeautifulSoup(new_row, 'html.parser')
                x = child.find_previous('tr')
                x.insert_before(crazy_tag)
                child.extract()

我正在寻找的输出是:

<table border="1" class="dataframe" style="border: 1px solid grey">
<tbody>
    <tr>
      <th>Records</th>
      <th>Worth</th>
      <td>30</td>
      <td>is</td>
      <td>50</td>
      <td>0</td>
      <td>good</td>
      <td></td>
    </tr>
    <tr>
      <th rowspan="14" >Words</th>
      <td style="height: 30px;"></td>
      <td style="text-align: center; height: 30px;"></td>
      <td style="height: 30px;"></td>
      <td style="text-align: right; padding: 7px; min-width: 75px"></td>
      <td style="height: 30px;"></td>
      <td style="height: 30px;"></td>
      <td style="height: 30px;"></td>
    </tr>
    <tr>
      <th>Worth</th>
      <td>30</td>
      <td>=</td>
      <td>40</td>
      <td>0</td>
      <td>bad</td>
      <td></td>
    </tr>
    <tr>
      <th>Worth</th>
      <td>is</td>
      <td>44</td>
      <td>400.0</td>
      <td></td>
      <td>bad</td>
      <td></td>
    </tr>
</tbody>
</table>

好消息是,我的代码做了我想做的事情,并且我得到了想要的输出.坏消息是,在我完成之前,我还必须对这个html做其他事情.在我执行此操作后,它继续循环遍历后代,下一次迭代不会给我任何结果.我以为Extract()保持了树的 struct 不变,但似乎是我要插入的块或我要删除的行没有保留树 struct .有什么主意吗?

我的问题基本上可以归结为:如何在漂亮的Soup对象中插入一些html,并在不 destruct 文档中sibling 关系的情况下提取一行?

推荐答案

.insert_before()/.extract()可以用简单的.replace_with()来代替:

from bs4 import BeautifulSoup

html_text = """\
<table border="1" class="dataframe" style="border: 1px solid grey">
<tbody>
    <tr>
      <th>Records</th>
      <th>Worth</th>
      <td>30</td>
      <td>is</td>
      <td>50</td>
      <td>0</td>
      <td>good</td>
      <td></td>
    </tr>
    <tr>
      <!-- this is the code im looking for -->
      <th rowspan="13" valign="top">Reports</th>
      <!--  -->
      <th>Worth</th>
      <td>30</td>
      <td>=</td>
      <td>40</td>
      <td>0</td>
      <td>bad</td>
      <td></td>
    </tr>
    <tr>
      <th>Worth</th>
      <td>is</td>
      <td>44</td>
      <td>400.0</td>
      <td></td>
      <td>bad</td>
      <td></td>
    </tr>
</tbody>
</table>"""

snippet = """\
<tr>
<th rowspan="14" >Words</th>
<td style="height: 30px;"></td>
<td style="text-align: center; height: 30px;"></td>
<td style="height: 30px;"></td>
<td style="text-align: right; padding: 7px; min-width: 75px"></td>
<td style="height: 30px;"></td>
<td style="height: 30px;"></td>
<td style="height: 30px;"></td>
</tr>"""

soup = BeautifulSoup(html_text, "html.parser")

for th in soup.select("th[rowspan]"):
    th.replace_with(BeautifulSoup(snippet, "html.parser"))

print(soup)

打印:

<table border="1" class="dataframe" style="border: 1px solid grey">
<tbody>
<tr>
<th>Records</th>
<th>Worth</th>
<td>30</td>
<td>is</td>
<td>50</td>
<td>0</td>
<td>good</td>
<td></td>
</tr>
<tr>
<!-- this is the code im looking for -->
<tr>
<th rowspan="14">Words</th>
<td style="height: 30px;"></td>
<td style="text-align: center; height: 30px;"></td>
<td style="height: 30px;"></td>
<td style="text-align: right; padding: 7px; min-width: 75px"></td>
<td style="height: 30px;"></td>
<td style="height: 30px;"></td>
<td style="height: 30px;"></td>
</tr>
<!-- -->
<th>Worth</th>
<td>30</td>
<td>=</td>
<td>40</td>
<td>0</td>
<td>bad</td>
<td></td>
</tr>
<tr>
<th>Worth</th>
<td>is</td>
<td>44</td>
<td>400.0</td>
<td></td>
<td>bad</td>
<td></td>
</tr>
</tbody>
</table>

Python相关问答推荐

点到面的Y距离

Pystata:从Python并行运行stata实例

如何标记Spacy中不包含特定符号的单词?

运行Python脚本时,用作命令行参数的SON文本

将两只Pandas rame乘以指数

Excel图表-使用openpyxl更改水平轴与Y轴相交的位置(Python)

如何在solve()之后获得症状上的等式的值

如何根据一列的值有条件地 Select 前N组?

我的字符串搜索算法的平均时间复杂度和最坏时间复杂度是多少?

如何使regex代码只适用于空的目标单元格

合并与拼接并举

如何获取Python synsets列表的第一个内容?

如何合并具有相同元素的 torch 矩阵的行?

计算机找不到已安装的库'

用fft计算指数复和代替求和来模拟衍射?

如何在Python中从html页面中提取html链接?

如何在Python中解析特定的文本,这些文本包含了同一行中的所有内容,

有没有一种方法可以在朗肯代理中集成向量嵌入

具有不匹配列的2D到3D广播

是否将列表分割为2?