HTML表到熊猫表:html标签内的信息

Posted

技术标签:

【中文标题】HTML表到熊猫表:html标签内的信息【英文标题】:HTML table to pandas table: Info inside html tags 【发布时间】:2015-10-24 15:14:25 【问题描述】:

我有一个来自网络的大表,通过请求访问并使用 BeautifulSoup 进行解析。它的一部分看起来像这样:

<table>
<tbody>
<tr>
<td>265</td>
<td> <a href="/j/jones03.shtml">Jones</a>Blue</td>
<td>29</td>
</tr>
<tr >
<td>266</td>
<td> <a href="/s/smith01.shtml">Smith</a></td>
<td>34</td>
</tr>
</tbody>
</table>

当我使用 pd.read_html(tbl) 将其转换为 pandas 时,输出是这样的:

    0    1          2
 0  265  JonesBlue  29
 1  266  Smith      34

我需要将信息保留在&lt;A HREF ... &gt; 标记中,因为唯一标识符存储在链接中。也就是说,表格应该是这样的:

    0    1        2
 0  265  jones03  29
 1  266  smith01  34

我对其他各种输出都很好(例如,jones03 Jones 会更有帮助),但唯一 ID 很关键。

其他单元格中也有 html 标签,通常我不希望保存这些标签,但如果这是获取 uid 的唯一方法,我可以保留这些标签并稍后清理它们,如果我必须。

有没有一种简单的方法可以访问这些信息?

【问题讨论】:

【参考方案1】:

由于这个解析工作需要同时提取文本和属性 值,它不能完全通过诸如 pd.read_html。其中一些必须手工完成。

使用lxml,您可以使用XPath 提取属性值:

import lxml.html as LH
import pandas as pd

content = '''
<table>
<tbody>
<tr>
<td>265</td>
<td> <a href="/j/jones03.shtml">Jones</a>Blue</td>
<td >29</td>
</tr>
<tr >
<td>266</td>
<td> <a href="/s/smith01.shtml">Smith</a></td>
<td>34</td>
</tr>
</tbody>
</table>'''

table = LH.fromstring(content)
for df in pd.read_html(content):
    df['refname'] = table.xpath('//tr/td/a/@href')
    df['refname'] = df['refname'].str.extract(r'([^./]+)[.]')
    print(df)

产量

     0          1   2  refname
0  265  JonesBlue  29  jones03
1  266      Smith  34  smith01

以上内容可能很有用,因为它只需要几个 额外的代码行来添加refname 列。

LH.fromstringpd.read_html 都会解析 HTML。 所以它的效率可以通过删除pd.read_html 和 用LH.fromstring解析一次表格:

table = LH.fromstring(content)
# extract the text from `<td>` tags
data = [[elt.text_content() for elt in tr.xpath('td')] 
        for tr in table.xpath('//tr')]
df = pd.DataFrame(data, columns=['id', 'name', 'val'])
for col in ('id', 'val'):
    df[col] = df[col].astype(int)
# extract the href attribute values
df['refname'] = table.xpath('//tr/td/a/@href')
df['refname'] = df['refname'].str.extract(r'([^./]+)[.]')
print(df)

产量

    id        name  val  refname
0  265   JonesBlue   29  jones03
1  266       Smith   34  smith01

【讨论】:

谢谢。这种确切的方法在我的情况下不起作用,因为其他单元格也有被 xpath 拾取的 href 标记;但鉴于无论如何我都必须执行额外的步骤,我使用正则表达式提取 UID,然后用它填充新列。 很高兴您解决了这个问题!不过要小心parsing HTML with regex;它可能在许多情况下都有效,但很难变得健壮。 明白。在这种情况下,我并没有真正解析 html,只是在指示 uid 的完整 URL 中查找文本。它比我喜欢的更脆弱,但这些表应该具有一致的结构,使其相对安全。【参考方案2】:

您可以像这样简单地手动解析表格:

import BeautifulSoup
import pandas as pd

TABLE = """<table>
<tbody>
<tr>
<td>265</td>
<td <a href="/j/jones03.shtml">Jones</a>Blue</td>
<td >29</td>
</tr>
<tr >
<td>266</td>
<td <a href="/s/smith01.shtml">Smith</a></td>
<td>34</td>
</tr>
</tbody>
</table>"""

table = BeautifulSoup.BeautifulSoup(TABLE)
records = []
for tr in table.findAll("tr"):
    trs = tr.findAll("td")
    record = []
    record.append(trs[0].text)
    record.append(trs[1].a["href"])
    record.append(trs[2].text)
    records.append(record)

df = pd.DataFrame(data=records)
df

给你

     0                 1   2
0  265  /j/jones03.shtml  29
1  266  /s/smith01.shtml  34

【讨论】:

感谢您的建议。表格相当大,每行有很多单元格,所以我宁愿尽可能避免手动提升(这很难概括),但如果没有更简单的解决方案,我会退回到这个。【参考方案3】:

您可以先使用正则表达式修改文本并删除html标签:

import re, pandas as pd
tbl = """<table>
<tbody>
<tr>
<td>265</td>
<td> <a href="/j/jones03.shtml">Jones</a>Blue</td>
<td>29</td>
</tr>
<tr >
<td>266</td>
<td> <a href="/s/smith01.shtml">Smith</a></td>
<td>34</td>
</tr>
</tbody>
</table>"""
tbl = re.sub('<a.*?href="(.*?)">(.*?)</a>', '\\1 \\2', tbl)
pd.read_html(tbl)

给你

[     0                           1   2
 0  265  /j/jones03.shtml JonesBlue  29
 1  266      /s/smith01.shtml Smith  34]

【讨论】:

以上是关于HTML表到熊猫表:html标签内的信息的主要内容,如果未能解决你的问题,请参考以下文章

CSS学习笔记:HTML元素和CSS盒子

5月25日 python学习总结 HTML标签

.NET ORM工具Pax实战Pax插入表到数据库

需要表结构来存储html标签并存储和返回它的值

如何在循环的帮助下动态地从 xml 文件中获取表到 ajax?

如何使用熊猫从文件中提取 html 表?