【发布时间】:2012-04-07 22:12:24
【问题描述】:
我的行为很奇怪
>>> from bs4 import BeautifulSoup
>>> smallfile = 'small.xml' #approx 600bytes
>>> largerfile = 'larger.xml' #approx 2300 bytes
>>> len(BeautifulSoup(open(smallfile, 'r'), ['lxml', 'xml']))
1
>>> len(BeautifulSoup(open(largerfile, 'r'), ['lxml', 'xml']))
0
small.xml 的内容:
<?xml version="1.0" encoding="us-ascii"?>
<Catalog>
<CMoverMissile id="HunterSeekerMissile">
<MotionPhases index="1">
<Driver value="Guidance"/>
<Acceleration value="3200"/>
<MaxSpeed value="2.9531"/>
<Clearance value="0.5"/>
<ClearanceLookahead value="3"/>
<Outro value="-4.5,-4.25"/>
<YawPitchRoll value="MAX"/>
</MotionPhases>
<MotionPhases index="2">
<Driver value="Guidance"/>
<Acceleration value="4"/>
<MaxSpeed value="2.9531"/>
<Clearance value="0.5"/>
<ClearanceLookahead value="3"/>
<Outro value="-2.25,-2"/>
<YawPitchRoll value="MAX"/>
</MotionPhases>
</CMoverMissile>
</Catalog>
largerfile 只是较小的文件,但用空格和换行符填充(在最后两个标签之间,以防相关)。 IE xml 的结构和内容对于这两种情况应该是相同的。
在极少数情况下,处理较大的文件实际上会产生部分结果,其中只有一小部分 xml 已被解析。我似乎无法可靠地重现当时的情况。
由于 BeautifulSoup 使用 lxml,我测试了 lxml 是否可以独立处理文件。 lxml 似乎能够解析这两个文件。
>>> from lxml import etree
>>> tree = etree.parse(smallfile)
>>> len(etree.tostring(tree))
547
>>> tree = etree.parse(largerfile)
>>> len(etree.tostring(tree))
2294
我正在使用
- 1gb 内存上网本
- Windows 7
- lxml 2.3(安装时遇到了一些问题,我希望安装不当不会导致问题)
- 靓汤4.0.1
- python 3.2(我也安装了python 2.7x,但这段代码一直使用3.2)
是什么阻止了较大的文件被正确处理?我目前的怀疑是一些奇怪的内存问题,因为文件大小似乎有所不同,可能与 BeautifulSoup 4 如何与 lxml 交互的一些错误有关。
编辑: 为了更好地说明......
>>> smallsoup = BeautifulSoup(smallfile), ['lxml', 'xml'])
>>> smallsoup
<?xml version="1.0" encoding="utf-8"?>
<Catalog>
<CMoverMissile id="HunterSeekerMissile">
<MotionPhases index="1">
<Driver value="Guidance"/>
<Acceleration value="3200"/>
<MaxSpeed value="2.9531"/>
<Clearance value="0.5"/>
<ClearanceLookahead value="3"/>
<Outro value="-4.5,-4.25"/>
<YawPitchRoll value="MAX"/>
</MotionPhases>
<MotionPhases index="2">
<Driver value="Guidance"/>
<Acceleration value="4"/>
<MaxSpeed value="2.9531"/>
<Clearance value="0.5"/>
<ClearanceLookahead value="3"/>
<Outro value="-2.25,-2"/>
<YawPitchRoll value="MAX"/>
</MotionPhases>
</CMoverMissile>
</Catalog>
>>> largersoup = BeautifulSoup(largerfile, ['lxml', 'xml'])
>>> largersoup
<?xml version="1.0" encoding="utf-8"?>
>>>
>>> repr(open(largefile, 'r').read())
'\'<?xml version="1.0" encoding="us-ascii"?>\\n<Catalog>\\n<CMoverMissile id="HunterSeekerMissile">\\n<MotionPhases index="1">\\n<Driver value="Guidance"/>\\n<Acceleration value="3200"/>\\n<MaxSpeed value="2.9531"/>\\n<Clearance value="0.5"/>\\n<ClearanceLookahead value="3"/>\\n<Outro value="-4.5,-4.25"/>\\n<YawPitchRoll value="MAX"/>\\n</MotionPhases>\\n<MotionPhases index="2">\\n<Driver value="Guidance"/>\\n<Acceleration value="4"/>\\n<MaxSpeed value="2.9531"/>\\n<Clearance value="0.5"/>\\n<ClearanceLookahead value="3"/>\\n<Outro value="-2.25,-2"/>\\n<YawPitchRoll value="MAX"/>\\n</MotionPhases>\\n</CMoverMissile> </Catalog>\''
注意:和\''之间有很多空格(可能不会在浏览器中显示)
【问题讨论】:
-
1200 字节仍然很小,所以我怀疑这是问题所在。
-
你能把xml文件的内容贴出来吗?
-
我的怀疑(由于懒惰我没有检查)是在 beautifulsoup 对象上运行的 len 不返回字节,而是节点数或类似的东西。当然这不是内存问题'
-
我认为 BS4 所称的
'lxml'是 lxml HTML 解析器,因为 BeautifulSoup 主要用于 HTML。如果您只想解析 xml,请尝试使用'xml'。 crummy.com/software/BeautifulSoup/bs4/doc/#parsing-xml -
@alonisser 发布了 xml 的内容(在更改它们以使较大的文件与较小的文件相同,但带有空白填充之后)。
标签: python memory beautifulsoup lxml