2013-02-17 13 views
8

Ich habe eine sehr große XML-Datei (20 GB um genau zu sein, und ja, ich brauche alles). Wenn ich versuche, die Datei zu laden, ich diese Fehlermeldung:Laden von riesigen XML-Dateien und Umgang mit MemoryError

Python(23358) malloc: *** mmap(size=140736680968192) failed (error code=12) 
*** error: can't allocate region 
*** set a breakpoint in malloc_error_break to debug 
Traceback (most recent call last): 
    File "file.py", line 5, in <module> 
    code = xml.read() 
MemoryError 

Dies ist der aktuelle Code, den ich habe, die XML-Datei zu lesen:

from bs4 import BeautifulSoup 
xml = open('pages_full.xml', 'r') 
code = xml.read() 
xml.close() 
soup = BeautifulSoup(code) 

Nun, wie würde ich mich über die Beseitigung diesen Fehler und in der Lage sein, weiter an dem Skript zu arbeiten. Ich würde versuchen, die Datei in separate Dateien aufzuteilen, aber da ich nicht weiß, wie sich das auf BeautifulSoup und die XML-Daten auswirken würde, würde ich das lieber nicht tun.

(Die XML-Daten sind ein Datenbank-Dump aus einem Wiki ich freiwillig, es unter Verwendung von Daten aus verschiedenen Zeitperioden zu importieren, die direkten Informationen aus vielen Seiten mit)

+2

Haben Sie 20 GB RAM? Wenn nicht, auch wenn du es zur Arbeit bringen kannst, wird es unerträglich langsam sein, wenn es ein- und austauscht. Es könnte einen Weg für Sie geben, nur Stücke auf einmal mit etwas wie lxml zu bearbeiten. – Dougal

Antwort

11

nicht Verwendung BeautifulSoup tun, um zu versuchen, und so eine große Parse-XML-Datei. Verwenden Sie stattdessen die ElementTree API. Insbesondere verwenden die iterparse() function Ihre Datei als Stream zu analysieren, verarbeiten Informationen, wie Sie von Elementen benachrichtigt werden, dann löschen die Elemente wieder:

from xml.etree import ElementTree as ET 

parser = ET.iterparse(filename) 

for event, element in parser: 
    # element is a whole element 
    if element.tag == 'yourelement' 
     # do something with this element 
     # then clean up 
     element.clear() 

Durch eine ereignisgesteuerten Ansatz, die Sie nie brauchen zu halten das ganze XML-Dokument im Speicher, extrahieren Sie nur, was Sie brauchen und den Rest verwerfen.

Siehe die iterparse() tutorial and documentation.

Alternativ können Sie auch die lxml library; Es bietet die gleiche API in einem schnelleren und umfassenderen Paket.