2011-06-12 108 views
28

我想要一個HTML表格並通過它進行解析以獲取字典列表。每個列表元素將是與表中的一行相對應的字典。例如,如果我有一個包含三列(標題標記標記),「事件」,「開始日期」和「結束日期」的HTML表格,並且該表格有5個條目,我想解析通過該表獲取長度爲5的列表,其中每個元素是具有鍵「事件」,「開始日期」和「結束日期」的字典。將HTML表解析爲Python列表?

感謝您的幫助!

回答

52

您應該使用像lxml一些HTML解析庫:

from lxml import etree 
s = """<table> 
    <tr><th>Event</th><th>Start Date</th><th>End Date</th></tr> 
    <tr><td>a</td><td>b</td><td>c</td></tr> 
    <tr><td>d</td><td>e</td><td>f</td></tr> 
    <tr><td>g</td><td>h</td><td>i</td></tr> 
</table> 
""" 
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'} 
+0

我的表格有不同數量的行。如果情況如此,我如何才能使它工作?謝謝你的迴應,順便說一句。 – Andrew 2011-06-12 23:09:39

+0

@Andrew:只要每行有相同數量的列,上面的代碼適用於任意數量的行和任意數量的列。 – 2011-06-12 23:44:44

+0

我建議'HTMLParser' /'html.parser',但這種解決方案在這種情況下要好得多。 – Robin 2011-06-13 09:25:06

22

斯文Marnach excellent solution是直接翻譯成ElementTree這是最近的Python發行的一部分:

from xml.etree import ElementTree as ET 

s = """<table> 
    <tr><th>Event</th><th>Start Date</th><th>End Date</th></tr> 
    <tr><td>a</td><td>b</td><td>c</td></tr> 
    <tr><td>d</td><td>e</td><td>f</td></tr> 
    <tr><td>g</td><td>h</td><td>i</td></tr> 
</table> 
""" 

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)) 

相同的輸出爲斯文Marnach的答案...

+1

+1因爲它允許使用cElementTree而不是ElementTree,如果涉及大量表格,它比lxml快得多 – Cerno 2016-04-06 16:00:38

+0

我有一個從wikipedia保存的網頁。我怎樣才能指定哪個表來解析和獲取數據?可以通過表名或表ID來實現嗎? – Massimo 2017-05-01 14:31:03

14

如果HTML XML你不能etree做到這一點。但即使如此,您也不必使用外部庫來分析HTML表格。在python 3中,您可以使用html.parserHTMLParser來達到目標​​。我有簡單派生的HTMLParser類here in a github repo的代碼。

您可以使用類(這裏命名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 ']]] 
+0

真棒解析器! – Naive 2017-11-28 07:57:21

8

相傳的最簡單的方法來解析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()不保留超鏈接。

+0

太棒了!謝謝。 – Raf 2017-08-29 13:45:11

+1

謝謝!這非常快速和簡單。 – 2018-01-03 05:54:48