【问题标题】:Parsing fixed-format data embedded in HTML in python在python中解析嵌入在HTML中的固定格式数据
【发布时间】:2010-09-29 09:57:10
【问题描述】:

我正在使用谷歌的 appengine api

from google.appengine.api import urlfetch

获取网页。结果

result = urlfetch.fetch("http://www.example.com/index.html")

是 html 内容的字符串(在 result.content 中)。问题是我要解析的数据并不是真正的 HTML 格式,所以我不认为使用 python HTML 解析器对我有用。我需要解析 html 文档正文中的所有纯文本。唯一的问题是 urlfetch 返回整个 HTML 文档的单个字符串,删除所有换行符和多余的空格。

编辑: 好的,我尝试获取不同的 URL,显然 urlfetch 没有去除换行符,这是我试图解析的原始网页以这种方式提供 HTML 文件...... 结束编辑

如果文档是这样的:

<html><head></head><body>
AAA 123 888 2008-10-30 ABC
BBB 987 332 2009-01-02 JSE
...
A4A       288        AAA
</body></html>

result.content 将是这个,在 urlfetch 获取它之后:

'<html><head></head><body>AAA 123 888 2008-10-30 ABCBBB 987     2009-01-02 JSE...A4A     288            AAA</body></html>'

使用 HTML 解析器不会帮助我处理 body 标签之间的数据,所以我打算使用正则表达式来解析我的数据,但正如你所见,一行的最后一部分与第一部分结合在一起下一行,我不知道如何拆分它。我试过了

result.content.split('\n')

result.content.split('\r')

但结果列表只是 1 个元素。我在 google 的 urlfetch 函数中没有看到任何不删除换行符的选项。

有什么想法可以解析这些数据吗?也许我需要以不同的方式获取它?

提前致谢!

【问题讨论】:

    标签: python html google-app-engine parsing html-content-extraction


    【解决方案1】:

    将字符串 s 拆分为 26 个字符的块的更多建议:

    作为一个列表:

    >>> [s[x:x+26] for x in range(0, len(s), 26)]
    ['AAA 123 888 2008-10-30 ABC',
     'BBB 987     2009-01-02 JSE',
     'A4A     288            AAA']
    

    作为生成器:

    >>> for line in (s[x:x+26] for x in range(0, len(s), 26)): print line
    AAA 123 888 2008-10-30 ABC
    BBB 987     2009-01-02 JSE
    A4A     288            AAA
    

    如果 s 很长,则在 Python 2.x 中将 range() 替换为 xrange()

    【讨论】:

      【解决方案2】:

      编辑:阅读理解是一件可取的事情。我错过了关于线条一起运行而它们之间没有分隔符的一点,这有点是重点,不是吗?所以,别管我的回答,它实际上并不相关。


      如果您知道每行是 5 个以空格分隔的列,那么(一旦您删除了 html)您可以执行类似(未经测试)的操作:

      def generate_lines(datastring):
          while datastring:
              splitresult = datastring.split(' ', 5)
              if len(splitresult) >= 5:
                  datastring = splitresult[5]
              else:
                  datastring = None
              yield splitresult[:5]
      
      for line in generate_lines(data):
          process_data_line(line)
      

      当然,您可以根据需要更改拆分字符和列数(甚至可能将它们作为附加参数传递给生成器函数),并根据需要添加错误处理。

      【讨论】:

        【解决方案3】:

        将正文文本作为单个长字符串后,您可以将其分解如下。 这假定每条记录是 26 个字符。

        body= "AAA 123 888 2008-10-30 ABCBBB 987     2009-01-02 JSE...A4A     288            AAA"
        for i in range(0,len(body),26):
            line= body[i:i+26]
            # parse the line
        

        【讨论】:

          【解决方案4】:

          我了解文档的格式是您发布的格式。在这种情况下,我同意像 Beautiful Soup 这样的解析器可能不是一个好的解决方案。

          我假设您已经使用正则表达式(如

          )获得了有趣的数据(在 BODY 标签之间)
          import re
          data = re.findall('<body>([^\<]*)</body>', result)[0]
          

          那么,它应该很简单:

          start = 0
          end = 5
          while (end<len(data)):
             print data[start:end]
             start = end+1
             end = end+5
          print data[start:]
          

          (注意:我没有根据边界情况检查此代码,我确实希望它会失败。这里只是为了展示一般的想法)

          【讨论】:

            【解决方案5】:

            我能想到的唯一建议是将其解析为具有固定宽度的列。 HTML 不考虑换行符。

            如果您可以控制源数据,请将其放入文本文件而不是 HTML。

            【讨论】:

            • 我无法控制源数据...也许我可以尝试解析它,因为数据是固定宽度格式的。
            猜你喜欢
            • 2011-03-27
            • 2019-03-02
            • 1970-01-01
            • 1970-01-01
            • 2010-10-28
            • 2017-03-03
            • 1970-01-01
            • 1970-01-01
            • 2021-12-18
            相关资源
            最近更新 更多