【问题标题】:Fastest, easiest, and best way to parse an HTML table?解析 HTML 表格的最快、最简单和最好的方法?
【发布时间】:2011-06-21 01:37:08
【问题描述】:

我正在尝试将此表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 代码提出改进意见和建议;)

【问题讨论】:

  • BeautifulSoup(或其他解析器)。除了桌子中间那些烦人的广告之外,这几乎是微不足道的。
  • 强制链接,因为“html-parsing”和“regex”标签都存在:stackoverflow.com/questions/1732348/…

标签: python regex html-parsing beautifulsoup


【解决方案1】:

避免使用正则表达式来解析 HTML,它们根本不适合它,你肯定需要像 BeautifulSoup 这样的 DOM 解析器......

其他一些选择

所有这些都可以合理地容忍格式不正确的 HTML。

【讨论】:

    【解决方案2】:

    我建议使用与 PHP 捆绑的 XML 解析器(如 DOMDocument::loadHTMLFile)加载文档,然后使用 XPath grep 您需要的数据。

    这不是最快的方式,但最终是最易读的(在我看来)。您可以使用正则表达式,它可能会快一点,但样式不好(难以调试,难以阅读)。

    编辑:实际上这很难,因为您提到的页面不是有效的 HTML(请参阅 validator.w3.org)。尤其是没有开始/结束标签的标签会很麻烦。

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

    【讨论】:

    • XML 解析器的问题在于 HTML 不是 XML 的子集,除非它按照 XML 规则的格式正确(或 XML 解析器损坏),否则它将无法正常工作。例如:HTML 中的<P> 甚至不需要任何类型的结束标记。此外,像   这样简单的东西不是有效的 XML。如果解析器(DOMDocument?)真的是一个 HTML 解析器,那么它应该被这样调用,而不是与 XML 解析器混淆:-)
    • @pst:没错,这就是为什么它有两种不同的方法“loadFile()”和“loadHTMLFile()”。 php 的 DOM 解析器能够应付正常的异常。但是在这种情况下,正如现在提到的那样,它不会这样做,因为提到的页面甚至不是有效的html)
    • 我没有在这个特定的页面上尝试过,但是 BeautifulSoup 是专门为处理无效的 HTML 而编写的,只是因为你不可避免地经常遇到它。
    • 然后“我建议使用 HTML 解析器加载文档...”:)
    【解决方案3】:

    正则表达式的效率优于 DOM 解析器。

    看看这个比较:

    http://www.rockto.com/launcher/28852/mochien.com/Blog/Read/A300111001736/Regex-VS-DOM-untuk-Rockto-Team

    你可以在网上找到更多。

    【讨论】:

    • 仅供参考,您提供的链接现已失效。
    【解决方案4】:

    对于您的一般问题:尝试 lxml 包中的 lxml.html(将其视为类固醇上的 stdlibs xml.etree:相同的 xml api,但支持 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 很快!)

    但是:更具体地说,对于您的特定用例:有比抓取该特定网页更好的方法来获取 timezone database 信息(除此之外:请注意该网页实际上提到您不允许复制其内容)。甚至已有的库已经使用了这些信息,例如python-dateutil

    【讨论】:

      【解决方案5】:

      在构建 SerpAPI 时,我们测试了许多平台/解析器。

      这是 Python 的基准测试结果。

      更多信息,这里有一篇关于 Medium 的完整文章: https://medium.com/@vikoky/fastest-html-parser-available-now-f677a68b81dd

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-01-23
        • 1970-01-01
        • 2016-10-27
        • 2018-10-15
        • 2011-03-03
        • 2016-04-10
        • 2015-07-11
        • 1970-01-01
        相关资源
        最近更新 更多