解析HTML表到Python列表?
我想获取一个HTML表并对其进行解析以获得字典列表。 每个列表元素将是一个与表中的一行相对应的字典。
例如,如果我有一个包含三列(用标题标签标记),“事件”,“开始日期”和“结束日期”的HTML表,并且该表有5个条目,我想将该表解析为 返回长度为5的列表,其中每个元素都是带有键“事件”,“开始日期”和“结束日期”的字典。
谢谢您的帮助!
Andrew asked 2020-07-26T08:10:22Z
4个解决方案
66 votes
您应该使用一些HTML解析库,例如lxml:
from lxml import etree
s = """
Event | Start Date | End Date |
---|---|---|
a | b | c |
d | e | f |
g | h | i |
"""
table = etree.HTML(s).find("body/table")
rows = iter(table)
headers = [col.text for col in next(rows)]
for row in rows:
values = [col.text for col in row]
print dict(zip(headers, values))
版画
{'End Date': 'c', 'Start Date': 'b', 'Event': 'a'}
{'End Date': 'f', 'Start Date': 'e', 'Event': 'd'}
{'End Date': 'i', 'Start Date': 'h', 'Event': 'g'}
Sven Marnach answered 2020-07-26T08:11:06Z
31 votes
轻松解析HTML表的最简单方法是使用pandas.read_html()-它接受URL和HTML。
import pandas as pd
url = r'https://en.wikipedia.org/wiki/List_of_S%26P_500_companies'
tables = pd.read_html(url) # Returns list of all tables on page
sp500_table = tables[0] # Select table of interest
唯一的缺点是read_html()不保留超链接。
zelusp answered 2020-07-26T08:11:31Z
29 votes
Sven Marnach出色的解决方案可以直接翻译成ElementTree,这是最近的Python发行版的一部分:
from xml.etree import ElementTree as ET
s = """
Event | Start Date | End Date |
---|---|---|
a | b | c |
d | e | f |
g | h | i |
"""
table = ET.XML(s)
rows = iter(table)
headers = [col.text for col in next(rows)]
for row in rows:
values = [col.text for col in row]
print dict(zip(headers, values))
与Sven Marnach的答案相同的输出...
Community answered 2020-07-26T08:11:55Z
18 votes
如果HTML不是XML,则无法使用etree。 但是即使那样,您也不必使用外部库来解析HTML表。 在python 3中,您可以使用html.parser中的HTMLTableParser达到目标。我在github存储库中拥有简单派生的HTMLParser类的代码。
您可以通过以下方式使用该类(此处为HTMLTableParser):
import urllib.request
from html_table_parser import HTMLTableParser
target = 'http://www.twitter.com'
# get website content
req = urllib.request.Request(url=target)
f = urllib.request.urlopen(req)
xhtml = f.read().decode('utf-8')
# instantiate the parser and feed it
p = HTMLTableParser()
p.feed(xhtml)
print(p.tables)
它的输出是代表表的2D列表的列表。 看起来可能像这样:
[[[' ', ' Anmelden ']],
[['Land', 'Code', 'Für Kunden von'],
['Vereinigte Staaten', '40404', '(beliebig)'],
['Kanada', '21212', '(beliebig)'],
...
['3424486444', 'Vodafone'],
[' Zeige SMS-Kurzwahlen für andere Länder ']]]
schmijos answered 2020-07-26T08:12:24Z