我正在尝试使用Python使用维基媒体转储文件(.xml.bz2)构建离线wiki。我从this文章开始作为指南。它涉及多种语言,我想将所有步骤组合为一个单独的python项目。我找到了该过程所需的几乎所有库。现在唯一的问题是将大型.xml.bz2文件有效地拆分成多个较小的文件,以便在搜索操作期间更快地解析。
我知道bz2库存在于python中,但它只提供压缩和解压缩操作。但是我需要一些可以从命令行执行类似bz2recover
的操作,它会将大文件拆分成许多较小的垃圾。
另一个重点是拆分不应拆分以<page>
开头的页面内容,并在已压缩的xml文档中结束</page>
。
以前是否有可以处理这种情况的库,或者必须从头开始编写代码?(任何大纲/伪代码都会非常有用)。
注意:我希望生成的包跨平台兼容,因此无法使用特定于操作系统的命令。
答案 0 :(得分:12)
最后我自己编写了一个Python脚本:
import os
import bz2
def split_xml(filename):
''' The function gets the filename of wiktionary.xml.bz2 file as input and creates
smallers chunks of it in a the diretory chunks
'''
# Check and create chunk diretory
if not os.path.exists("chunks"):
os.mkdir("chunks")
# Counters
pagecount = 0
filecount = 1
#open chunkfile in write mode
chunkname = lambda filecount: os.path.join("chunks","chunk-"+str(filecount)+".xml.bz2")
chunkfile = bz2.BZ2File(chunkname(filecount), 'w')
# Read line by line
bzfile = bz2.BZ2File(filename)
for line in bzfile:
chunkfile.write(line)
# the </page> determines new wiki page
if '</page>' in line:
pagecount += 1
if pagecount > 1999:
#print chunkname() # For Debugging
chunkfile.close()
pagecount = 0 # RESET pagecount
filecount += 1 # increment filename
chunkfile = bz2.BZ2File(chunkname(filecount), 'w')
try:
chunkfile.close()
except:
print 'Files already close'
if __name__ == '__main__':
# When the script is self run
split_xml('wiki-files/tawiktionary-20110518-pages-articles.xml.bz2')
答案 1 :(得分:1)
好吧,如果你有一个提供你所使用的功能的命令行工具,你总是可以使用subprocess模块将它包装在一个电话中
答案 2 :(得分:0)
您引用的方法非常糟糕:)
我写了一个离线的维基百科工具,只是萨克斯 - 完全解析了转储。如果您只是将未压缩的xml从正确的bzip2解压缩器传输到stdin,则吞吐量是可用的。特别是如果它只是维京人。
作为一种简单的测试方法,我只压缩每一页并将其写入一个大文件,并将偏移和长度保存在cdb(小键值存储)中。这对您来说可能是一个有效的解决方案。
请记住,mediawiki标记是我在很长一段时间内遇到的最可怕的部分。但是对于维基百科,我可以处理它。