0

我正在使用谷歌的 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>

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

'<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 个元素。我在谷歌的 urlfetch 函数中看不到任何不删除换行符的选项。

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

提前致谢!

4

5 回答 5

2

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

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

于 2009-01-03T20:36:30.413 回答
2

我了解文档的格式是您发布的格式。在这种情况下,我同意像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:]

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

于 2009-01-03T21:13:07.360 回答
1

将正文文本作为单个长字符串后,您可以将其分解如下。这假定每条记录是 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
于 2009-01-04T00:18:04.413 回答
0

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


如果您知道每行是 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)

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

于 2009-01-04T01:08:14.500 回答
0

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

如果很长range()xrange()请在 Python 2.x 中替换为。s

于 2009-01-27T21:52:46.303 回答