gpt4 book ai didi

python - 将(所有)维基百科数据加载到 mongodb 中?

转载 作者:可可西里 更新时间:2023-11-01 09:45:28 25 4
gpt4 key购买 nike

在 MongoNYC 2013 session 上,一位演讲者提到他们使用维基百科的副本来测试他们的全文搜索。我试图自己复制它,但由于文件大小和格式的原因,我发现它很重要。

这是我正在做的:

$ 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 文件时,Python 出现错误。对于如何将 9GB 的 XML 文件转换为我可以加载到 mongoDB 中的 JSON-y 文件,有没有人有任何其他建议?

更新 1

按照下面 Sean 的建议,我也尝试了迭代元素树:

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

但内容只有一条记录。它没有迭代。

xmltodict,也看起来很有前途,因为它宣传使用迭代 Expat 并且对维基百科有好处。但它也在 20 分钟左右后耗尽了内存:

>>> import xmltodict
>>> f = open('enwiki-latest-pages-articles.xml')
>>> doc = xmltodict.parse(f)
Killed

更新 3

这是对 Ross 在下面的回答的回应,根据 link he mentions 对我的解析器进行建模:

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

最佳答案

您需要使用 iterparse 进行迭代而不是将整个文件加载到内存中。至于如何转换为 json 甚至转换为 python 对象以存储在数据库中 - 请参阅:https://github.com/knadh/xmlutils.py/blob/master/xmlutils/xml2json.py

更新

使用 iterparse 并保持低内存占用的示例:

试试 Liza Daly's fast_iter 的变体.在处理完一个元素 elem 后,它会调用 elem.clear() 来移除后代并移除之前的 sibling 。

from lxml import etree

def fast_iter(context, func):
# http://www.ibm.com/developerworks/xml/library/x-hiperfparse/
# Author: Liza Daly
for event, elem in context:
print(elem)
elem.clear()
while elem.getprevious() is not None:
del elem.getparent()[0]
del context

context = etree.iterparse( MYFILE, tag='item' )
fast_iter(context,process_element)

Daly 的文章非常值得一读,尤其是当您正在处理大型 XML 文件时。

关于python - 将(所有)维基百科数据加载到 mongodb 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17286183/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com