0

XML ファイルをフェッチして解析してデータベースにしようとしています。XML は GZIP で圧縮されています。GZIP ファイルは最大 8 MB です。コードをローカルで実行すると、pythonw.exe のメモリがシステム全体 (Windows 7) が応答を停止するレベルまで蓄積され、オンラインで実行すると Google App Engine のメモリ制限を超えます。ファイルが大きすぎるのか、何か間違っているのかわかりません。どんな助けでも大歓迎です!

from google.appengine.ext import webapp
from google.appengine.api.urlfetch import fetch
from xml.dom.minidom import parseString
import gzip
import base64
import StringIO

class ParseCatalog(webapp.RequestHandler):
user = xxx
password = yyy
catalog = fetch('url',
                    headers={"Authorization": 
                             "Basic %s" % base64.b64encode(user + ':' + password)}, deadline=600)
xmlstring = StringIO.StringIO(catalog.content)
gz = gzip.GzipFile(fileobj=xmlstring)
gzcontent = gz.read()
contentxml = parseString(gzcontent)
items = contentxml.getElementsByTagName("Product")

for item in items:
    item = DatabaseEntry()
    item.name = str(coupon.getElementsByTagName("Manufacturer")[0].firstChild.data)
    item.put()

アップデート

そこで、BasicWolf の提案に従って LXML に切り替えようとしましたが、インポートに問題がありました。LXML 2.3 ライブラリをダウンロードして、アプリのフォルダに入れました (これが理想的ではないことはわかっていますが、これがサード パーティのライブラリを含める方法を知っている唯一の方法です)。また、app.yaml に以下を追加しました。

libraries:
- name: lxml
  version: "2.3"

次に、解析するかどうかをテストするために次のコードを書きました。

import lxml

class ParseCatalog(webapp.RequestHandler):
    user = xxx
    password = yyy
    catalog = fetch('url',
                    headers={"Authorization": 
                             "Basic %s" % base64.b64encode(user + ':' + password)}, deadline=600)
    items = etree.iterparse(catalog.content)

    def get(self): 
       for elem in items:
           self.response.out.write(str(elem.tag))

ただし、これにより次のエラーが発生します。

ImportError: cannot import name etree

このエラーに関する他の質問を確認しましたが、Windows 7 で実行していることが影響しているようです。また、 http: //www.lfd.uci.edu/~gohlke/pythonlibs/#lxml からコンパイル済みのバイナリ パッケージをインストールしようとしましたが、何も変わりませんでした。

4

1 に答える 1

3

あなたは何を期待していますか?まず、文字列をメモリに読み込み、メモリに解凍し、メモリ内に DOM ツリーを構築します。

ここにいくつかの改善があります:

  1. del必要がなくなった瞬間にすべてのバッファ変数。
  2. DOM XML パーサーを取り除き、イベント駆動型 LXML を使用してメモリを節約します。
于 2013-01-27T17:23:32.770 に答える