如何在Python中将HTML表格转换为数组
我有一个HTML文档,我想把里面的表格提取出来,并把它们返回为数组。我想象着有两个函数,一个是用来找到文档中的所有HTML表格,另一个是把HTML表格转换成二维数组。
大概是这样的:
htmltables = get_tables(htmldocument)
for table in htmltables:
array=make_array(table)
不过有两个问题需要注意:
- 表格的数量每天都不一样。
- 表格里面有各种奇怪的额外格式,比如加粗和闪烁标签,随意混在里面。
谢谢!
3 个回答
1
给提问的人加个赞,也给Python的大神加个赞。
我想用lxml和CSS选择器来试试这个例子。
是的,这个基本上和Alex的例子差不多:
import lxml.html
markup = lxml.html.fromstring('''<html><body>\
<table width="600">
<tr>
<td width="50%">0,0,0</td>
<td width="50%">0,0,1</td>
</tr>
<tr>
<td>0,1,0</td>
<td>0,1,1</td>
</tr>
</table>
<table>
<tr>
<td>1,0,0</td>
<td>1,<blink>0,</blink>1</td>
<td>1,0,2</td>
<td><bold>1</bold>,0,3</td>
</tr>
</table>
</body></html>''')
tbl = []
rows = markup.cssselect("tr")
for row in rows:
tbl.append(list())
for td in row.cssselect("td"):
tbl[-1].append(unicode(td.text_content()))
pprint(tbl)
#[[u'0,0,0', u'0,0,1'],
# [u'0,1,0', u'0,1,1'],
# [u'1,0,0', u'1,0,1', u'1,0,2', u'1,0,3']]
21
使用BeautifulSoup(我推荐使用3.0.8
版本)。找到所有的表格非常简单:
import BeautifulSoup
def get_tables(htmldoc):
soup = BeautifulSoup.BeautifulSoup(htmldoc)
return soup.findAll('table')
不过,在Python中,数组是单维的,而且只能包含一些基本类型的元素(比如整数、浮点数,简单得很)。所以,没办法把一个HTML表格放进Python的array
里。
你可能是想说Python的list
吧?这也是单维的,但里面的元素可以是任何东西,所以你可以有一个列表里面包含多个列表(我想每个子列表对应一个tr
标签,里面每个元素对应一个td
标签)。
这样就能得到:
def makelist(table):
result = []
allrows = table.findAll('tr')
for row in allrows:
result.append([])
allcols = row.findAll('td')
for col in allcols:
thestrings = [unicode(s) for s in col.findAll(text=True)]
thetext = ''.join(thestrings)
result[-1].append(thetext)
return result
这可能还不是你想要的(没有跳过HTML注释,子列表里的元素是unicode字符串而不是字节字符串等等),但应该很容易调整。
11
Pandas 是一个很方便的工具,它可以直接从你的网页中提取所有的表格,并把它们放到一个数据框的列表里,这样你就不用自己去解析网页了,省去了很多麻烦。一个数据框(DataFrame)是一种强大的二维数组类型。
我建议你继续使用Pandas来处理数据,因为它非常好用。不过,如果你喜欢的话,也可以把数据转换成其他格式,比如列表、字典、CSV文件等等。
示例
"""Extract all tables from an html file, printing and saving each to csv file."""
import pandas as pd
df_list = pd.read_html('my_file.html')
for i, df in enumerate(df_list):
print df
df.to_csv('table {}.csv'.format(i))
如果你想直接从网上获取HTML内容,而不是从文件中读取,只需要稍微修改一下代码:
import requests
html = requests.get('my_url').content
df_list = pd.read_html(html)