我怎样才能从一张有美组的桌子上得到第一个和第三个td?

2024-06-07 14:40:15 发布

您现在位置:Python中文网/ 问答频道 /正文

我目前正在使用Python和BeautifulSoup来收集一些网站数据。 我正试图从一个格式如下的表中提取单元格:

<tr><td>1<td><td>20<td>5%</td></td></td></td></tr>

上面的HTML的问题是BeautifulSoup将其作为一个标记读取。我需要从第一个<td>和第三个<td>中提取值,分别是1和20。

不幸的是,我不知道该怎么办。如何让BeautifulSoup读取表中每行的第一个和第三个<td>标记?

更新:

我发现了问题。我使用的是html.parser而不是BeautifulSoup的默认值。一旦我切换到默认值,问题就消失了。我也用了答案中列出的方法。

我还发现,不同的解析器非常喜怒无常,代码都坏了。例如,默认解析器拒绝读取超过192行的内容,但是html5lib完成了任务。因此,如果在分析整个表时遇到问题,请尝试使用lxmlhtml,以及html5lib


Tags: 数据答案标记parser解析器网站html格式
1条回答
网友
1楼 · 发布于 2024-06-07 14:40:15

这是一段很讨厌的HTML。如果我们暂时忽略表行和表单元格的语义,并将其视为纯XML,则其结构如下:

<tr>
  <td>1
    <td>
      <td>20
        <td>5%</td>
      </td>
    </td>
  </td>
</tr>

但是,BeautifulSoup知道HTML表的语义,而是这样解析:

<tr>
  <td>1        <!-- an IMPLICITLY (no closing tag) closed td element -->
  <td>         <!-- as above -->
  <td>20       <!-- as above -->
  <td>5%</td>  <!-- an EXPLICITLY closed td element -->
  </td>        <!-- an error; ignore this -->
  </td>        <!-- as above -->
  </td>        <!-- as above -->
</tr>

。。。所以,正如您所说,1和20分别在第一和第三个td元素(not tags)中。

实际上,您可以获取这些td元素的内容,如下所示:

>>> from bs4 import BeautifulSoup
>>> soup = BeautifulSoup("<tr><td>1<td><td>20<td>5%</td></td></td></td></tr>")
>>> tr = soup.find("tr")
>>> tr
<tr><td>1</td><td></td><td>20</td><td>5%</td></tr>
>>> td_list = tr.find_all("td")
>>> td_list
[<td>1</td>, <td></td>, <td>20</td>, <td>5%</td>]
>>> td_list[0]  # Python starts counting list items from 0, not 1
<td>1</td>
>>> td_list[0].text
'1'
>>> td_list[2].text
'20'
>>> td_list[3].text
'5%'

相关问题 更多 >

    热门问题