我的XML解析函数的简化版本在这里:
import xml.etree.cElementTree as ET
def analyze(xml):
it = ET.iterparse(file(xml))
count = 0
for (ev, el) in it:
count += 1
print('count: {0}'.format(count))
Run Code Online (Sandbox Code Playgroud)
这会导致Python耗尽内存,这并没有多大意义.我实际存储的唯一东西是count,一个整数.为什么这样做:

看到内存和CPU使用率突然下降?这是Python的惊人崩溃.至少它给了我一个MemoryError(取决于我在循环中做了什么,它给了我更多随机错误,比如一个IndexError)和堆栈跟踪而不是段错误.但为什么会崩溃?
这最终消耗了我所有可用的内存,然后该进程被终止.我已经尝试将标签更改schedule为"较小"标签,但这并没有什么区别.
我做错了什么/如何处理这个大文件iterparse()?
import lxml.etree
for schedule in lxml.etree.iterparse('really-big-file.xml', tag='schedule'):
print "why does this consume all my memory?"
Run Code Online (Sandbox Code Playgroud)
我可以轻松地将其切割并以较小的块处理它,但这比我想要的更糟糕.
我有这样的xml:
<a>
<b>hello</b>
<b>world</b>
</a>
<x>
<y></y>
</x>
<a>
<b>first</b>
<b>second</b>
<b>third</b>
</a>
Run Code Online (Sandbox Code Playgroud)
我需要迭代所有<a>和<b>标签,但我不知道它们中有多少是在文档中.所以我xpath用来处理:
from lxml import etree
doc = etree.fromstring(xml)
atags = doc.xpath('//a')
for a in atags:
btags = a.xpath('b')
for b in btags:
print b
Run Code Online (Sandbox Code Playgroud)
它工作,但我有相当大的文件,并cProfile告诉我xpath使用非常昂贵.
我想知道,也许有更有效的方法来迭代无限数量的xml元素?
有没有人建议在下面的网站上打开xml数据的最佳方法是将它放在python中的数据框(我更喜欢使用pandas)?该文件位于此站点上的"Data - XML(sdmx/zip)"链接中:
http://www.federalreserve.gov/pubs/feds/2006/200628/200628abs.html
我试过从http://timhomelab.blogspot.com/2014/01/how-to-read-xml-file-into-dataframe.html复制使用以下内容,似乎我越来越近了:
from lxml import objectify
import pandas as pd
path = 'feds200628.xml'
xml = objectify.parse(open(path))
root = xml.getroot()
root.getchildren()[0].getchildren()
df = pd.DataFrame(columns=('id', 'name'))
for i in range(0,4):
obj = root.getchildren()[i].getchildren()
row = dict(zip(['id', 'name'], [obj[0].text, obj[1].text]))
row_s = pd.Series(row)
row_s.name = i
df = df.append(row_s)
Run Code Online (Sandbox Code Playgroud)
尽管如此,我还不太了解xml让我完成剩下的工作.
任何帮助都很棒 - 我甚至不需要它在数据框中,我只需要弄清楚如何以某种方式在python中解析这个内容.
我有一个非常大的XML文件(300mb),格式如下:
<data>
<point>
<id><![CDATA[1371308]]></id>
<time><![CDATA[15:36]]></time>
</point>
<point>
<id><![CDATA[1371308]]></id>
<time><![CDATA[15:36]]></time>
</point>
<point>
<id><![CDATA[1371308]]></id>
<time><![CDATA[15:36]]></time>
</point>
</data>
Run Code Online (Sandbox Code Playgroud)
现在我需要读取它并遍历point节点为每个节点做一些事情.目前我正在和Nokogiri这样做:
require 'nokogiri'
xmlfeed = Nokogiri::XML(open("large_file.xml"))
xmlfeed.xpath("./data/point").each do |item|
save_id(item.xpath("./id").text)
end
Run Code Online (Sandbox Code Playgroud)
然而,这并不是非常有效,因为它解析了整个拥抱的一切,因此创造了巨大的内存占用(几GB).
有没有办法在块中执行此操作?如果我没弄错的话可能会被称为流式传输?
编辑
使用nokogiris sax解析器的建议答案可能没问题,但是当每个节点中有多个节点point需要从中提取内容并以不同方式处理时,它会变得非常混乱.我宁愿选择point一次访问一个,处理它,然后继续下一个"忘记"前一个,而不是返回大量的条目供以后处理.
我正在改进一个解析XML并对其子树进行分类和索引的程序.实际程序太大而无法显示在这里,所以我把它归结为一个最小的测试用例,显示我遇到的问题.
这个想法是:
alpino_ds并行处理文件中的所有节点请注意,在实际代码中还有一些注意事项:
dicts of four levels deep consisting of dicts, sets, ints, and strings, as well as dict-to-filehandle, and Counter() objects;ThreadPoolExecutor) and even though there was some gain (I calculated around 5% improvement in speed), this …python parallel-processing shared-memory python-3.x python-multiprocessing
我有一个非常大的 XML 文件,其中包含 40,000 个标签元素。当我使用元素树来解析这个文件时,它由于内存而出错。那么python中是否有任何模块可以读取数据块中的xml文件而无需将整个xml加载到内存中?我如何实现该模块?
我一直在尝试解析LXML不会理解的一些巨大的XML文件,所以我不得不用它来解析它们xml.sax.
class SpamExtractor(sax.ContentHandler):
def startElement(self, name, attrs):
if name == "spam":
print("We found a spam!")
# now what?
Run Code Online (Sandbox Code Playgroud)
问题是我不明白如何实际return或更好地yield处理这个处理程序找到调用者的事情,而不等待整个文件被解析.到目前为止,我一直在瞎搞与threading.Thread和Queue.Queue,但是这会导致各种问题与线程真的分散我的注意力从实际的问题,我试图解决的问题.
我知道我可以在一个单独的进程中运行SAX解析器,但我觉得必须有一种更简单的方法来获取数据.在那儿?
我有一个巨大的XML文件,我对如何处理它有点不知所措.它是60 GB,我需要阅读它.
我在想是否有办法使用多处理模块来读取python文件?
有没有人有这样做的样本,他们可以指点我?
谢谢
我有一个非常大的 XML 日志文件,它会以固定大小 (~200MB) 自动分割。可以有很多部分(通常少于 10 个)。当它拆分时,它不会在记录末尾甚至当前行末尾整齐地进行拆分。一旦达到目标尺寸,它就会分裂。
time基本上我需要解析这些文件中的“记录”元素,然后从每个文件中取出子文件
由于这些日志文件在随机位置分割并且不一定有根目录,因此我将 Python3 和 lxmletree.iterparse与html=True. 这是处理由于分割文件而导致缺少根节点的情况。但是,我不确定如何处理最终在一个文件的末尾和另一个文件的开头之间分割的记录。
以下是分割文件的一个小示例。
文件:测试.001.txt
<records>
<record>
<data>5</data>
<time>1</time>
</record>
<record>
<data>5</data>
<time>2</time>
</record>
<record>
<data>5</data>
<ti
Run Code Online (Sandbox Code Playgroud)
文件:测试.002.txt
me>3</time>
</record>
<record>
<data>6</data>
<time>4</time>
</record>
<record>
<data>6</data>
<time>5</time>
</record>
</records>
Run Code Online (Sandbox Code Playgroud)
这是我尝试过的方法,但我知道它不能正常工作:
from lxml import etree
xmlFiles = []
xmlFiles.append('test.001.txt')
xmlFiles.append('test.002.txt')
timeStamps = []
for xmlF in xmlFiles:
for event, elem in etree.iterparse(xmlF, events=("end",), tag='record',html=True):
tElem = elem.find('time')
if tElem is not None:
timeStamps.append(int(tElem.text))
Run Code Online (Sandbox Code Playgroud)
输出:
In[20] : …Run Code Online (Sandbox Code Playgroud) 我需要更新一些超过2GB文件的最后一行,这些文件由无法读取的文本行组成readlines().目前,它通过逐行循环工作正常.但是,我想知道是否有任何编译库可以更有效地实现这一点?谢谢!
myfile = open("large.XML")
for line in myfile:
do_something()
Run Code Online (Sandbox Code Playgroud) python ×10
lxml ×4
xml ×4
elementtree ×1
io ×1
iterparse ×1
memory ×1
memory-leaks ×1
pandas ×1
python-3.x ×1
ruby ×1
sax ×1
xml-parsing ×1