使用 pd.read_html 解析 html table,其中单元格本身包含完整的 table
Parsing an html table with pd.read_html where cells contain full-tables themselves
我需要从 html 中解析一个 table,它有其他 table 嵌套在较大的 table 中。正如下面使用 pd.read_html
调用的那样,这些嵌套的 table 中的每一个都被解析,然后 "inserted"/"concatenated" 作为行。
我希望将这些嵌套的 table 分别解析为它们自己的 pd.DataFrames
并作为对象作为相应列的值插入。
如果这不可能,那么将嵌套table的原始html作为相应位置的字符串就可以了。
测试代码:
import pandas as pd
df_up = pd.read_html("up_pf00344.test.html", attrs = {'id': 'results'})
输出截图:
在 html 中呈现的 table 的屏幕截图:
Link 到文件:https://gist.github.com/smsaladi/6adb30efbe70f9fed0306b226e8ad0d8#file-up_pf00344-test-html-L62
您不能使用 read_html
来读取嵌套的 table,但您可以滚动自己的 html reader 并使用 read_html
作为 table 单元格:
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'>
奖励:由于您的 table 行有一个 id
,您可以将其用作数据帧的索引 df.loc[row.get('id')] = df_row
而不是 df.loc[len(df)] = df_row
。
我需要从 html 中解析一个 table,它有其他 table 嵌套在较大的 table 中。正如下面使用 pd.read_html
调用的那样,这些嵌套的 table 中的每一个都被解析,然后 "inserted"/"concatenated" 作为行。
我希望将这些嵌套的 table 分别解析为它们自己的 pd.DataFrames
并作为对象作为相应列的值插入。
如果这不可能,那么将嵌套table的原始html作为相应位置的字符串就可以了。
测试代码:
import pandas as pd
df_up = pd.read_html("up_pf00344.test.html", attrs = {'id': 'results'})
输出截图:
在 html 中呈现的 table 的屏幕截图:
Link 到文件:https://gist.github.com/smsaladi/6adb30efbe70f9fed0306b226e8ad0d8#file-up_pf00344-test-html-L62
您不能使用 read_html
来读取嵌套的 table,但您可以滚动自己的 html reader 并使用 read_html
作为 table 单元格:
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'>
奖励:由于您的 table 行有一个 id
,您可以将其用作数据帧的索引 df.loc[row.get('id')] = df_row
而不是 df.loc[len(df)] = df_row
。