9

Python 2.7.3 で BeautifulSoup4 を使用していくつかの Web ページを処理しようとしていましたが、解析するたびにメモリ使用量がどんどん増えていきます。

この単純化されたコードは、同じ動作を生成します。

from bs4 import BeautifulSoup

def parse():
    f = open("index.html", "r")
    page = BeautifulSoup(f.read(), "lxml")
    f.close()

while True:
    parse()
    raw_input()

parse() を 5 回呼び出した後、Python プロセスは既に 30 MB のメモリを使用し (使用された HTML ファイルは約 100 kB)、呼び出しごとに 4 MB 増加します。そのメモリを解放する方法または何らかの回避策はありますか?

更新: この動作は頭痛の種です。BeautifulSoup 変数を長い間削除する必要があるにもかかわらず、このコードは簡単に大量のメモリを使い果たします。

from bs4 import BeautifulSoup
import threading, httplib, gc

class pageThread(threading.Thread):
    def run(self):
        con = httplib.HTTPConnection("stackoverflow.com")
        con.request("GET", "/")
        res = con.getresponse()
        if res.status == 200:
            page = BeautifulSoup(res.read(), "lxml")
        con.close()

def load():
    t = list()
    for i in range(5):
        t.append(pageThread())
        t[i].start()
    for thread in t:
        thread.join()

while not raw_input("load? "):
    gc.collect()
    load()

それはおそらくある種のバグでしょうか?

4

4 に答える 4

10

各ファイルでの作業が完了したら、ツリーを破棄するBeautiful Soup の分解機能を試してください。

from bs4 import BeautifulSoup

def parse():
    f = open("index.html", "r")
    page = BeautifulSoup(f.read(), "lxml")
    # page extraction goes here
    page.decompose()
    f.close()

while True:
    parse()
    raw_input()
于 2013-01-16T02:34:47.683 に答える
2

ガベージ コレクションを試す:

from bs4 import BeautifulSoup
import gc

def parse():
    f = open("index.html", "r")
    page = BeautifulSoup(f.read(), "lxml")
    page = None
    gc.collect()
    f.close()

while True:
    parse()
    raw_input()

以下も参照してください。

Python ガベージ コレクション

于 2012-07-01T20:05:27.533 に答える
0

ガベージコレクションはおそらく実行可能ですが、コンテキストマネージャは、余分なメモリ使用量なしでそれをかなりうまく処理しているようです。

from bs4 import BeautifulSoup as soup
def parse():
  with open('testque.xml') as fh:
    page = soup(fh.read())

また、完全に必要というわけではありませんが、raw_inputテスト中にループさせるために使用している場合、このイディオムは実際に非常に便利です。

while not raw_input():
  parse()

Enterキーを押すたびにループを続けますが、空でない文字列を入力するとすぐに停止します。

于 2012-07-01T20:18:00.210 に答える