【问题标题】:Parsing html tables with Beautifulsoup in Python在 Python 中使用 Beautifulsoup 解析 html 表
【发布时间】:2018-02-01 05:43:55
【问题描述】:

我正在尝试从大量 html 页面中解析表格。每个 tagret 表都有下一个结构:

<table width="100%%" border="2" bordercolor="navy">
  <tr bordercolor="#0000FF">
    <td width="20%%" height="22" bgcolor="navy"><font color="#FFFFFF"><b>Field1</b></font></td>
    <td width="20%%" height="22" bgcolor="navy"><font color="#FFFFFF"><b>Field2</b></font></td>
     <td width="60%%" height="22" bgcolor="navy"><font color="#FFFFFF"><b>Field3</b></font></td>
  </tr>
    <tr>
    <td width="12%">A1</td>
    <td width="32%"><a href="../">A2</a></td>
    <td width="56%">A3</td>
  </tr>
  <tr>
    <td width="12%">B1</td>
    <td width="32%"><a href="../">B2</a></td>
    <td width="56%">B3
</td>
  </tr>
  <tr>
    <td width="12%">C1</td>
    <td width="32%"><a href="../">C2</a></td>
    <td width="56%">C3</td>
  </tr>
  <tr>
    <td width="12%">D1</td>
    <td width="32%"><a href="../">D2</a></td>
    <td width="56%">D3</td>
  </tr>

</table>

行数因页面而异,因此解析器应该能够处理任意数量的行。我想从每个 html 页面收集信息,例如

A1 A2 A3
B1 B2 B3
C1 C2 C3
D1 D2 D3

我该怎么做?

【问题讨论】:

    标签: python-3.x beautifulsoup


    【解决方案1】:

    您可以使用find_all()get_text() 来收集表格数据。 find_all() 方法返回一个包含标签所有后代的列表; get_text() 返回一个包含标签文本内容的字符串。首先选择所有选项卡,为每个表选择所有行,为每行选择所有列,最后提取文本。这将按照 HTML 文档中出现的相同顺序和结构收集所有表格数据。

    from bs4 import BeautifulSoup
    
    html = 'my html document'
    soup = BeautifulSoup(html, 'html.parser')
    tables = [
        [
            [td.get_text(strip=True) for td in tr.find_all('td')] 
            for tr in table.find_all('tr')
        ] 
        for table in soup.find_all('table')
    ]
    

    tables变量包含文档中的所有表格,它是一个嵌套列表,结构如下,

    tables -> rows -> columns
    

    如果结构不重要,并且您只想从一个大列表中的所有表中收集文本,请使用:

    table_data = [i.text for i in soup.find_all('td')]
    

    或者如果你更喜欢CSS selectors:

    table_data = [i.text for i in soup.select('td')]
    

    如果目标是收集表格数据而不考虑 HTML 属性或其他参数,那么最好使用pandaspandas.read_html() 方法从 URL、文件或字符串中读取 HTML,对其进行解析并返回包含表数据的数据帧列表。

    import pandas as pd
    
    html = 'my html document'
    tables = pd.read_html(html)
    

    请注意,pandas.read_html() 比 BeautifulSoup 更脆弱,如果它无法解析 HTML 或文档没有任何表格,它将引发值错误。

    【讨论】:

    • 我在表格中遇到了一些空单元格的问题。使用 td.text for td in tr.find_all('td') 而不是 td.string.strip() 帮助我解决了这个问题
    • 我使用了strip(),因为它会删除尾随空格、制表符等,并生成干净的文本。我也没有从第一行([1:])收集列,因为它似乎是一个标题。当然,我的代码是基于您帖子中的 html 的通用示例;你可以修改它以满足你的需要。
    • 我认为td.texttd.get_text()是检索表格中文本内容的更好方法。 .text.string的区别请参考stackoverflow.com/questions/25327693/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-15
    • 2020-02-06
    相关资源
    最近更新 更多