在大文件中查找字符串,并将每个字符串写入Python中的第二个文件

时间:2013-09-29 21:13:57

标签: python

我是Python的新手(通常是编程)。为了使工作项目更容易,我试图编写一些代码,在XML文件中搜索某些标记并将内容复制到第二个文件。我需要读取的文件大约是165MB,并且将有数万个条目需要读取。

我已经成功地使它适用于小文件(使用此类论坛上的示例代码),但它超出了一定的大小(它开始复制大部分XML,而不仅仅是所需的字符串) 。我想这是因为我已经定义了我的变量。

有人可以给我一个指针或示例代码来解决这个问题吗?我很惊讶它的确有效!

这是我现在的代码:

text = open("UPC_Small.xml", "r")

lines = text.read()

fo = open("output.log", "wt")

crid1 = 0

while True:

    crid1 = lines.find('<ProgramInformation programId="crid://bds.tv/',crid1)
    crid2 = lines.find('">',crid1)
    crid_string = (lines[crid1+45:crid2])

    if crid1 == -1:
        fo.write("End of File")
        fo.close()
        break

    title1 = lines.find('<Title xml:lang="EN" type="main">',crid2)
    title2 = lines.find('</Title>',title1)
    title_string = (lines[title1+33:title2])

    genre1 = lines.find('<Name xml:lang="EN">',title2)
    genre2 = lines.find('</Name>',genre1)
    genre_string = (lines[genre1+20:genre2])

    fo.write(crid_string + "|" + title_string + "|" + genre_string + "\n")

2 个答案:

答案 0 :(得分:1)

尝试xml.etree.ElementTree迭代XML。

def parse_file(filename):
    import xml.etree.ElementTree as ET
    tree = ET.parse(filename)
    root = tree.getroot()
    for program_information in root.findall('ProgramInformation'):
        attr = program_information.attrib
        title = program_information.find('Title').text
        genre = program_information.get('Name').text
        yield attr, title, genre

for attr, title, genre in parse_file("UPC_Small.xml"):
    print attr, title, genre

P.S。这段代码未经测试,我从未使用过该库。

答案 1 :(得分:0)

这里有一些代码可以让你在rails上尝试SAX解析器。对于简单的解析和 大文件它比ElementTree更好,因为它消耗更少的内存。

import xml.sax
from xml.sax.handler import ContentHandler

class MySaxHandler(ContentHandler):
  def __init__(self):
    ContentHandler.__init__(self)

    self.results = []

  def startElement(self, name, attrs):
    if name == 'ProgramInformation':
      program_id = attrs["programId"]
      self.results.append([program_id, "", ""])

  def characters(self, content):
    self.last_contents = str(content)

  def endElement(self, name):
    if name == 'Title':
      self.results[-1][1] = self.last_contents
    elif name == 'Name':
      self.results[-1][2] = self.last_contents

def parse(filename):
  handler = MySaxHandler()
  xml.sax.parse(filename, handler)
  return handler.results

if __name__ == '__main__':
  fo = open("output.log", "wt")
  fo.write("\n".join("|".join(parse("UPC_Small.xml")))