2013-02-17 14 views
8

Mam bardzo duży plik XML (dokładnie 20 GB i tak, potrzebuję tego wszystkiego). Przy próbie załadowania pliku, otrzymuję ten błąd:Ładowanie dużych plików XML i radzenie sobie z 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 

ten jest obecny kod mam do odczytu pliku XML:

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

Teraz, jak pójdę o wyeliminowaniu ten błąd i móc kontynuować pracę nad skryptem. Spróbowałbym podzielić plik na osobne pliki, ale ponieważ nie wiem, jak wpłynęłoby to na BeautifulSoup, a także dane XML, wolałbym tego nie robić.

(dane XML jest zrzutu bazy danych z wiki ja na ochotnika na, wykorzystując go do importowania danych z różnych czasowych okresów, za pomocą bezpośredniej informacji z wielu stron)

+2

Czy masz 20 GB pamięci RAM? Jeśli nie, nawet jeśli uda ci się to osiągnąć, będzie to nieznośnie powolne, gdy się zamieni. Być może istnieje sposób, abyś działał tylko na porcjach z czymś takim jak lxml. – Dougal

Odpowiedz

11

Czy nie użytkowania BeautifulSoup spróbować i taki duży plik XML analizy. Zamiast tego użyj ElementTree API. W szczególności, należy użyć iterparse() function przeanalizować plik jako strumień, przetwarzania informacji, jak jesteś informowany o elementach, a następnie usuwać elementy ponownie:

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() 

Stosując podejście zdarzeniami, nie trzeba trzymać cały dokument XML w pamięci, wyciągasz tylko to, czego potrzebujesz i odrzucasz resztę.

Zobacz iterparse() tutorial and documentation.

Alternatywnie można również użyć lxml library; oferuje ten sam interfejs API w szybszym i bardziej funkcjonalnym pakiecie.

Powiązane problemy