MongoNYC 2013 カンファレンスで、講演者はウィキペディアのコピーを使用して全文検索をテストしたと述べました。私はこれを自分で複製しようとしましたが、ファイルのサイズと形式が原因で自明ではないことがわかりました.
これが私がやっていることです:
$ wget http://download.wikimedia.org/enwiki/latest/enwiki-latest-pages-articles.xml.bz2
$ bunzip2 enwiki-latest-pages-articles.xml.bz2
$ python
>>> import xml.etree.ElementTree as ET
>>> tree = ET.parse('enwiki-latest-pages-articles.xml')
Killed
標準の XML パーサーで XML ファイルを解析しようとすると、XML ファイルのサイズで Python エラーが発生します。9GBのXMLファイルをmongoDBにロードできるJSON-yに変換する方法について、他に提案はありますか?
更新 1
以下のショーンの提案に従って、反復要素ツリーも試しました。
>>> import xml.etree.ElementTree as ET
>>> context = ET.iterparse('enwiki-latest-pages-articles.xml', events=("start", "end"))
>>> context = iter(context)
>>> event, root = context.next()
>>> for i in context[0:10]:
... print(i)
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: '_IterParseIterator' object has no attribute '__getitem__'
>>> for event, elem in context[0:10]:
... if event == "end" and elem.tag == "record":
... print(elem)
... root.clear()
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: '_IterParseIterator' object has no attribute '__getitem__'
同様に、運もありません。
更新 2
以下の Asya Kamsky の提案をフォローアップします。
ここで試していxml2json
ます:
$ git clone https://github.com/hay/xml2json.git
$ ./xml2json/xml2json.py -t xml2json -o enwiki-latest-pages-articles.json enwiki-latest-pages-articles.xml
Traceback (most recent call last):
File "./xml2json/xml2json.py", line 199, in <module>
main()
File "./xml2json/xml2json.py", line 181, in main
input = open(arguments[0]).read()
MemoryError
ここにありxmlutils
ます:
$ pip install xmlutils
$ xml2json --input "enwiki-latest-pages-articles.xml" --output "enwiki-latest-pages-articles.json"
xml2sql by Kailash Nadh (http://nadh.in)
--help for help
Wrote to enwiki-latest-pages-articles.json
しかし、中身はただの1枚。それは繰り返されませんでした。
xmltodict
、繰り返し Expat を使用し、ウィキペディアに適していることを宣伝しているため、有望に見えました。しかし、これも 20 分ほどでメモリ不足になりました。
>>> import xmltodict
>>> f = open('enwiki-latest-pages-articles.xml')
>>> doc = xmltodict.parse(f)
Killed
更新 3
これは、以下のロスの回答への回答であり、彼が言及したリンクから私のパーサーをモデル化しています。
from lxml import etree
file = 'enwiki-latest-pages-articles.xml'
def page_handler(page):
try:
print page.get('title','').encode('utf-8')
except:
print page
print "error"
class page_handler(object):
def __init__(self):
self.text = []
def start(self, tag, attrib):
self.is_title = True if tag == 'title' else False
def end(self, tag):
pass
def data(self, data):
if self.is_title:
self.text.append(data.encode('utf-8'))
def close(self):
return self.text
def fast_iter(context, func):
for event, elem in context:
print(elem)
elem.clear()
while elem.getprevious() is not None:
del elem.getparent()[0]
del context
process_element = etree.XMLParser(target = page_handler())
context = etree.iterparse( file, tag='item' )
fast_iter(context,process_element)
エラーは次のとおりです。
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in fast_iter
File "iterparse.pxi", line 484, in lxml.etree.iterparse.__next__ (src/lxml/lxml.etree.c:112653)
File "iterparse.pxi", line 537, in lxml.etree.iterparse._read_more_events (src/lxml/lxml.etree.c:113223)
File "parser.pxi", line 596, in lxml.etree._raiseParseError (src/lxml/lxml.etree.c:83186)
lxml.etree.XMLSyntaxError: Extra content at the end of the document, line 22, column 1