2015-05-15 122 views
0

我正在嘗試讀取一堆xml文件並向他們做些什麼。我想要做的第一件事是根據文件中的數字對它們進行重命名。用BeautifulSoup讀取1000個XML文檔

你可以看到一個數據樣本here警告這將啓動下載一個108MB的zip文件!。這是一個巨大的xml文件,其中包含數千個較小的xml文件。我已經將這些分解成單個文件。我想根據裏面的數字重新命名文件(預處理的一部分)。我有以下代碼:

from __future__ import print_function 
from bs4 import BeautifulSoup # To get everything 
import os 

def rename_xml_files(directory): 
    xml_files = [xml_file for xml_file in os.listdir(directory) ] 

    for filename in xml_files: 
     filename = filename.strip() 
     full_filename = directory + "/" +filename 
     print (full_filename) 
     f = open(full_filename, "r") 
     xml = f.read() 
     soup = BeautifulSoup(xml) 
     del xml 
     del soup 
     f.close() 

如果我註釋掉「湯=」和「刪除」行,它完美的作品。如果我添加「soup = ...」這一行,它會運行一段時間,然後它最終會崩潰 - 它只會崩潰python內核。我正在使用Enthought Canopy,但是我已經試過它從命令行運行,它也在那裏瘋狂。

我想,也許,它並沒有釋放變量「湯」的空間,所以我嘗試添加「del」命令。同樣的問題。

有關如何規避這個問題的想法?我沒有被困在BS上。如果有更好的方法做到這一點,我會喜歡它,但我需要一些示例代碼。

+0

你能展示一個正在解析的XML文件嗎? –

+1

如果您有權訪問多個核心,您可以從https://mikecvet.wordpress.com/2010/07/02/parallel-mapreduce-in-python/ – boardrider

回答

2

嘗試使用Python的標準xml庫中的cElementTree.parse()而不是BeautifulSoup。 「湯對解析正常的網頁非常有用,但cElementTree正在快速發展。

像這樣:

import xml.etree.cElementTree as cET 

# ... 

def rename_xml_files(directory): 
    xml_files = [xml_file for xml_file in os.listdir(directory) ] 

    for filename in xml_files: 
     filename = filename.strip() 
     full_filename = directory + "/" +filename 
     print(full_filename) 
     parsed = cET.parse(full_filename) 
     del parsed 

如果你的XML格式正確無誤這應該分析它。如果您的機器仍然無法處理內存中的所有數據,則應該查看streaming XML。

+0

獲得一些見解我嘗試使用該核心,然後去回到學士學位,因爲我無法弄清楚確切的電話是否能讓我得到我想要的。 – elbillaf

+1

'parsed.getroot()。getchildren()'應該讓你開始。你可以閱讀文檔https://docs.python.org/2/library/xml.etree.elementtree.html –

+0

這是非常有用的建議。你提供的樣本完美地工作,進一步的建議閱讀幫助我擴展了我正在做的事情。 – elbillaf

0

我不會將該文件分成許多小文件,然後再處理它們,我會一次處理它們。

我只是使用一個streaming api XML解析器並解析主文件,獲取名稱並用正確的名稱寫出一次子文件。

BeautifulSoup不需要主要用於處理HTML並使用文檔模型而不是流式解析器。

不需要爲了一次獲得單個元素而構建整個DOM。