【问题标题】:Parsing an html table with pd.read_html where cells contain full-tables themselves使用 pd.read_html 解析 html 表格,其中单元格本身包含完整表格
【发布时间】:2019-10-08 04:42:37
【问题描述】:

我需要从 html 中解析一个表,该表具有嵌套在较大表中的其他表。正如下面用pd.read_html 调用的那样,这些嵌套表中的每一个都被解析,然后“插入”/“连接”为行。

我希望将这些嵌套表分别解析为它们自己的pd.DataFrames,并作为对象插入作为相应列的值。

如果这是不可能,那么将嵌套表的原始html作为字符串放在相应位置就可以了。

经过测试的代码:

import pandas as pd
df_up = pd.read_html("up_pf00344.test.html", attrs = {'id': 'results'})

输出截图:

以 html 呈现的表格的屏幕截图:

文件链接:https://gist.github.com/smsaladi/6adb30efbe70f9fed0306b226e8ad0d8#file-up_pf00344-test-html-L62

【问题讨论】:

    标签: python html pandas beautifulsoup lxml


    【解决方案1】:

    您不能使用read_html 读取嵌套表格,但您可以滚动您自己的html 阅读器并将read_html 用于表格单元格:

    import pandas as pd
    import bs4
    
    with open('up_pf00344.test.html') as f:
        html = f.read()
    soup = bs4.BeautifulSoup(html, 'lxml')
    results = soup.find(attrs = {'id': 'results'})
    
    # get first visible header row as dataframe headers
    for row in results.thead.find_all('tr'):
        if 'display:none' not in row.get('style',''):
            df = pd.DataFrame(columns=[col.get_text() for col in row.find_all('th')])
        break
    
    # append all table rows to dataframe
    for row in results.tbody.find_all('tr', recursive=False):
        if 'display:none' in row.get('style',''):
            continue
        df_row = []
        for col in row.find_all('td', recursive=False):
            table = col.find_all('table')
            df_row.append(pd.read_html(str(col))[0] if table else col.get_text())
        df.loc[len(df)] = df_row
    

    df.iloc[0].map(type) 的结果:

                                                                <class 'str'>
    Entry                                                       <class 'str'>
    Organism                                                    <class 'str'>
    Protein names                                               <class 'str'>
    Gene names                                                  <class 'str'>
    Length                                                      <class 'str'>
    Cross-reference (Pfam)                                      <class 'str'>
    Cross-reference (InterPro)                                  <class 'str'>
    Taxonomic lineage IDs                                       <class 'str'>
    Subcellular location [CC]                                   <class 'str'>
    Signal peptide                                              <class 'str'>
    Transit peptide                                             <class 'str'>
    Topological domain                  <class 'pandas.core.frame.DataFrame'>
    Transmembrane                       <class 'pandas.core.frame.DataFrame'>
    Intramembrane                       <class 'pandas.core.frame.DataFrame'>
    Sequence caution                                            <class 'str'>
    Caution                                                     <class 'str'>
    Taxonomic lineage (SUPERKINGDOM)                            <class 'str'>
    Taxonomic lineage (KINGDOM)                                 <class 'str'>
    Taxonomic lineage (PHYLUM)                                  <class 'str'>
    Cross-reference (RefSeq)                                    <class 'str'>
    Cross-reference (EMBL)                                      <class 'str'>
    e                                                           <class 'str'>
    

    奖励:由于您的表格行有一个id,您可以将它用作数据框的索引df.loc[row.get('id')] = df_row 而不是df.loc[len(df)] = df_row

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-30
      • 1970-01-01
      • 1970-01-01
      • 2011-06-02
      • 2020-02-07
      • 1970-01-01
      • 2017-11-13
      • 2016-12-01
      相关资源
      最近更新 更多