解析HTML表格的最快、最简单、最佳方法是什么?

10 投票
5 回答
7616 浏览
提问于 2025-04-16 11:12

我想把这个表格 http://www.datamystic.com/timezone/time_zones.html 转换成数组格式,这样我就可以随意处理它。最好是用 PHP、Python 或 JavaScript。

这种问题经常会遇到,所以我不是想要解决这个具体的问题,而是想找一些方法来解决所有类似的问题。

我首先想到的是 BeautifulSoup。还有一种方法是把它复制粘贴到 TextMate,然后使用正则表达式处理。

你有什么建议吗?

这是我最终写的脚本,但正如我所说,我希望找到一个更通用的解决方案。

from BeautifulSoup import BeautifulSoup
import urllib2


url = 'http://www.datamystic.com/timezone/time_zones.html';
response = urllib2.urlopen(url)
html = response.read()
soup = BeautifulSoup(html)
tables = soup.findAll("table")
table = tables[1]
rows = table.findAll("tr")
for row in rows:
    tds = row.findAll('td')
    if(len(tds)==4):
        countrycode = tds[1].string
        timezone = tds[2].string
        if(type(countrycode) is not type(None) and type(timezone) is not type(None)):
            print "\'%s\' => \'%s\'," % (countrycode.strip(), timezone.strip())

欢迎对我的 Python 代码提出意见和改进建议;)

5 个回答

0

我建议使用像 DOMDocument::loadHTMLFile 这样的 XML 解析器来加载文档,这个解析器是 PHP 自带的。然后你可以用 XPath 来提取你需要的数据。

这样做可能不是最快的方式,但我觉得最终结果是最容易理解的。你也可以使用正则表达式,这样可能会快一点,但风格就不太好了(因为难以调试,难以阅读)。

补充一下:其实这很难,因为你提到的页面不是有效的 HTML(可以去 validator.w3.org 检查一下)。特别是那些没有开闭标签的标签,会让事情变得更加复杂。

不过,看起来 xmlstarlet(http://xmlstar.sourceforge.net/,这是个很棒的工具)能够修复这个问题(运行 xmlstarlet fo -R)。xmlstarlet 还可以使用 xpath 和 xslt 脚本,这样你就可以用简单的 shell 脚本提取数据了。

4

解析HTML的时候,最好不要用正则表达式,因为这并不合适。你应该使用像BeautifulSoup这样的DOM解析器。

还有一些其他的选择:

这些工具都能很好地处理格式不太规范的HTML。

6

针对你的一般问题,可以试试来自 lxml 包的 lxml.html。可以把它想象成是标准库中的 xml.etree 的升级版:它有相同的 xml 接口,但支持 html、xpath、xslt 等等。

这里有一个快速示例,适合你的具体情况:

from lxml import html

tree = html.parse('http://www.datamystic.com/timezone/time_zones.html')
table = tree.findall('//table')[1]
data = [
           [td.text_content().strip() for td in row.findall('td')] 
           for row in table.findall('tr')
       ]

这个代码会给你一个嵌套列表:每个子列表对应表格中的一行,里面包含了单元格中的数据。虽然偷偷插入的广告行还没有被过滤掉,但这应该能帮助你入门。(顺便说一下:lxml 的速度很快!)

但是:更具体地说,对于你的特定需求,有更好的方法来获取 时区数据库 信息,而不是去抓取那个特定的网页(顺便提一句,网页上其实提到你不允许复制它的内容)。实际上,还有一些现成的库已经使用了这些信息,比如 python-dateutil

撰写回答