2013-02-17 27 views
8

私は非常に大きなXMLファイルを持っています(正確には20GB、はい、それはすべて必要です)。私は、ファイルをロードしようとすると、私はこのエラーが表示されます。これは私がXMLファイル読み取りに、持っている現在のコードである巨大なXMLファイルを読み込んで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 

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

を、どのように私は排除しに行きますかこのエラーが発生し、スクリプトの作業を続けることができます。私はファイルを別々のファイルに分割しようとしますが、それがBeautifulSoupとXMLデータにどのように影響するかわからないので、私はむしろこれをやりません。

(XMLデータが多くのページから直接情報を使用して、異なる時間帯からデータをインポートするためにそれを使用して、私はボランティアのwikiからのデータベース・ダンプである)

+2

20GBのRAMがありますか?もしそうでなければ、たとえあなたがこれを動かすことができても、それは内外にスワップするほど堪えがたく遅くなるでしょう。あなたはlxmlのようなもので一度にチャンクだけを操作する方法があるかもしれません。 – Dougal

答えて

11

ないしようとするBeautifulSoupを使用していますそのような大規模な解析XMLファイルです。代わりにElementTree APIを使用してください。具体的には、再び要素を削除しますが、要素が通知されると、その後、情報を処理、ストリームとしてファイルを解析するiterparse() functionを使用します。

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

をイベント駆動型のアプローチを使用することで、保持する必要はありません全体 XML文書をメモリに格納するだけで、必要なものを抽出し、残りの部分を破棄するだけです。

iterparse() tutorial and documentationを参照してください。

また、lxml libraryを使用することもできます。同じAPIをより速く、より機能豊富なパッケージに提供します。

関連する問題