【问题标题】:How can I get the first and third td from a table with BeautifulSoup?如何使用 BeautifulSoup 从表中获取第一个和第三个 td?
【发布时间】:2013-08-16 03:19:34
【问题描述】:

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

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

上述 HTML 的问题在于 BeautifulSoup 将其作为一个标签来读取。我需要从第一个 &lt;td&gt; 和第三个 &lt;td&gt; 中提取值,它们分别是 1 和 20。

不幸的是,我不知道该怎么做。如何让 BeautifulSoup 读取表格每一行的第一个和第三个 &lt;td&gt; 标签?

更新:

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

我还发现,不同的解析器对损坏的代码非常敏感。例如,默认解析器拒绝读取第 192 行,但 html5lib 完成了这项工作。因此,如果您在解析整个表时遇到问题,请尝试使用 lxmlhtmlhtml5lib

【问题讨论】:

    标签: python html html-table beautifulsoup html-parsing


    【解决方案1】:

    那是一段令人讨厌的 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%'
    

    【讨论】:

    • 我试过了,结果是[&lt;td&gt;1&lt;td&gt;&lt;td&gt;20&lt;td&gt;5%&lt;/td&gt;&lt;/td&gt;&lt;/td&gt;&lt;/td&gt;,&lt;td&gt;&lt;td&gt;20&lt;td&gt;5%&lt;/td&gt;&lt;/td&gt;&lt;/td&gt;,&lt;td&gt;20&lt;td&gt;5%&lt;/td&gt;&lt;/td&gt;,&lt;td&gt;5%&lt;/td&gt;]
    • 没问题 :-) 正如你可能知道的那样,使用 'html.parser' 将 HTML 解释为格式正确的 XHTML(如上所述),而不是格式错误的 HTML,因此在您的第一个结果中嵌套 td 元素。
    猜你喜欢
    • 1970-01-01
    • 2019-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-03
    • 1970-01-01
    • 1970-01-01
    • 2015-10-11
    相关资源
    最近更新 更多