【问题标题】:Extracting data between tags from huge text (XML) files从巨大的文本 (XML) 文件中提取标签之间的数据
【发布时间】:2015-05-13 13:12:30
【问题描述】:

注意:我使用的是 Windows 7 64 位系统 - 刚刚安装了 cygwin。

我需要从大量不同的大型(100 MB)XML 文件中提取大量数据。 xml 文件包含一堆行序列,如下所示:

<taggie>
lotsolines which include some string that I'm searching for.
</taggie>

我想提取从开始标签到包含搜索字符串的结束标签的所有内容。 (是在 python 中执行此操作还是在 cygwin 中执行此操作是一个折腾。)

我的计划是编写一个脚本,从这些 xml 文件中预处理出开始和结束标记表,并为开始-结束创建一个行号参考表。 类似的东西

filename, start line (begin tag), end line (end tag)
bogusname.xml, 50025, 100003

然后我再次搜索以创建我的字符串出现位置的列表。 它可能看起来像这样。

filename, searchstring, line number
bogusname.xml, "foo", 76543

然后我根据第一个列表处理第二个列表,以提取信息(可能到第二个大文件或一组文件中。我现在不在乎。

不管怎样,当我这样做时,我突然想到,几乎可以肯定有人做了这件事或与之非常相似的事情。

那么,任何人都可以指导我使用已经这样做的代码吗?首选 Python,但 cygwin 的 unix 样式脚本会很方便。我更喜欢源代码而不是任何我看不到源代码在做什么的可执行文件。

与此同时,我正在独自进行。提前致谢。

对于确切的数据,我正在下载这个文件(例如): http://storage.googleapis.com/patents/grant_full_text/2015/ipg150106.zip 我解压缩它,我想提取那些包含大量搜索字符串的 XML 文档。这是一个包含数千个连接的 XML 文档的单个文件。我想提取任何包含搜索字符串之一的 XML。

我目前正在尝试使用 BeautifulSoup:

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

xml_handle = open("t.xml", "r")
soup = BeautifulSoup(xml_handle)

i = 0
for grant in soup('us-patent-grant'):
    i = i + 1
    print (i)
    print (grant)

print (i)

当我这样做时,它给出的 i 的最终值为 9。 如果它获得了所有的“us-patent-grant”标签,我希望 i 超过 6000 - 这表明它可能没有解析整个文件。

【问题讨论】:

    标签: xml tags extraction


    【解决方案1】:

    我目前正在处理 Python 中的类似问题。我知道这已经晚了几年,但我会分享我解析类似大文件的经验。

    我发现 Python 的内置函数 xml.etree.ElementTree 可以很好地解决这个问题(它的 C 实现,称为 cElementTree 具有相同的 API,也是内置的)。我尝试了文档中的所有方法,iterparse() with clear() 是迄今为止库中最快的(比我在 Python 中制作的任何其他实现快 5 倍)。这种方法允许您以增量方式在内存中加载和清除 xml,将其作为流处理(使用生成器)。这比将整个文件加载到内存中要好得多,这可能会使您的计算机慢下来。

    参考资料:

    The accepted answer here explains basically the best approach that I could find.

    This IBM site talks about lxml which is similar to the xml library but has better XPath support.

    lxml websitecElementTree website 比较 xml 和 lxml 包的执行速度。

    【讨论】:

      【解决方案2】:

      (过去的答案)

      使用python包beautifulsoup怎么样?加上正则表达式。 BeautifulSoup 是最著名的处理 .html、.xml 文件的工具。 重新进口 从 bs4 导入 BeautifulSoup

      f = open("filename.xml")
      xml = f.read()
      soup = BeautifulSoup(xml)
      find_search = re.compile("[search]+")
      #remain code here....
      

      查看此网站http://www.crummy.com/software/BeautifulSoup/bs4/doc/ 了解美丽汤, 和https://docs.python.org/2/library/re.html 用于正则表达式语法。

      但访问此网页后,您可以轻松地做自己想做的事。

      ================================================ ========================

      文件太大,所以你需要一些代码来将文件拆分成单独的文件。从链接Split diary file into multiple files using Python,您可以将代码编写为

      <!-- language: python -->
      def files():
          n = 0
          while True:
              n += 1
              yield open('xml_%d.xml' % n, 'w')
      pat = '<?xml'
      fs = files()
      outfile = next(fs) 
      with open("ipg150106.xml") as infile:
          for line in infile:
              if pat not in line:
                  outfile.write(line)
              else:
                  items = line.split(pat)
                  outfile.write(items[0])
                  for item in items[1:]:
                      outfile = next(fs)
                      outfile.write(pat + item)
      

      这段代码给了我 xml_6527.xml。

      def files():
          n = 0
          while True:
              n += 1
              yield open('xml_%d.xml' % n, 'w')
      
      if __name__ == '__main__':
          #make file seperate
          # pat = '<?xml'
          # fs = files()
          # outfile = next(fs) 
      
          # with open("ipg150106.xml") as infile:
          #     for line in infile:
          #         if pat not in line:
          #             outfile.write(line)
          #         else:
          #             items = line.split(pat)
          #             outfile.write(items[0])
          #             for item in items[1:]:
          #                 outfile = next(fs)
          #                 outfile.write(pat + item)
      
          #analyzing each file
          import os
          pwd = os.path.dirname(os.path.realpath(__file__))
          xml_files = [xml_file for xml_file in os.listdir(pwd) if os.path.isfile(os.path.join(pwd, xml_file))]
      
          for f in xml_files:
              xml = f.read()
              soup = BeautifulSoup(xml)
              #Remain code here..
      

      (对不起,奇怪的代码块:()

      【讨论】:

      • 我现在正在看。我遇到的问题是这些大文件中的每一个都包含数千个连接的 XML 文档 - 我不确定,但我认为 BS 只读取第一个。现在浏览文档。
      • @elbillaf 我曾经废弃了一个 Facebook 群组页面,其中包含近 50000 个帖子,包括 cmets,但 beautifulsoup 废弃了它并在 10 秒内在我的 4GB ram macbook 上解析了它。另外,我建议如何分离串联的 XML 文档?
      • 我不知道你的建议。
      • @elbillaf 如何使用此代码 stackoverflow.com/questions/12717294/… ?先拆分很多xml文件,然后对每个文件使用beautifulsoup,然后写入一个输出文件。
      • 分解它是有效的。那挺好的。我可以处理这个。谢谢,
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-10
      • 1970-01-01
      相关资源
      最近更新 更多