在python中解析嵌入在HTML中的固定格式数据
-
03-07-2019 - |
题
我正在使用google的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个元素。我没有在google的urlfetch函数中看到任何选项来删除换行符。
我是如何解析这些数据的?也许我需要以不同方式获取它?
提前致谢!
解决方案
我理解文档的格式是您发布的格式。在这种情况下,我同意像 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:]
(注意:我没有检查此代码是否违反边界情况,我确实希望它失败。只是在这里显示通用的想法)
其他提示
我能想到的唯一建议是将其解析为具有固定宽度列。 HTML不考虑换行符。
如果您可以控制源数据,请将其放入文本文件而不是HTML。
将正文文本作为单个长字符串后,您可以按如下方式对其进行分解。 这假设每条记录是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
编辑:阅读理解是一件令人满意的事情。我错过了关于线路一起运行而没有它们之间没有分隔符的情况,这有点像这一点,不是吗?所以,不要回答我的回答,这实际上并不相关。
如果您知道每行是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)
当然,您可以根据需要更改拆分字符和列数(甚至可以将它们作为附加参数传递给生成器函数),并根据需要添加错误处理。
将字符串 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中的 xrange()
替换 range()
。