2016-08-29 5 views
1

私は、ユーザー名を掻き取るこのコードを持っている:Pythonの長時間メモリ割り当てエラーのためのスクリプトを実行した後

def fetch_and_parse_names(url): 
    html = requests.get(url).text 
    soup = BeautifulSoup(html, "lxml") 
    return (a.string for a in soup.findAll(href=USERNAME_PATTERN)) 

def get_names(urls): 
    # Create a concurrent executor 
    with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor: 

     # Apply the fetch-and-parse function concurrently with executor.map, 
     # and join the results together 
     return itertools.chain.from_iterable(executor.map(fetch_and_parse_names, urls)) 

def get_url(region, page): 
    return 'http://lolprofile.net/leaderboards/%s/%d' % (region, page) 

それは後に、この

urls = [get_url(region, i) for i in range(start, end + 1)] 
names = (name.lower() for name in get_names(urls) if is_valid_name(name)) 

のようにリスト内のすべての名前を入れて起動します私はメモリ割り当てエラーが発生していることは明らかですが、なぜこれが起こるのか分かりますが、どうすれば修正できますか?私はちょうど単一のページからユーザー名を取得し、それらをすぐにファイルに出力することを考えていた、リストの内容を削除し、繰り返しますが、私はこれを実装する方法を知らなかった。

答えて

2

あなたが使用しているコードは、二つの理由のためにメモリ内のすべてのダウンロードの文書保持:

  • あなたがa.stringを返すだけstrしかしbs4.element.NavigableString、そのようにその親への参照を保持し、最終的にではありませんドキュメントツリー全体
  • ジェネレータ式を返します。ジェネレータ式は、使用されるまでローカルコンテキスト(この場合はsoup)を取得します。この問題を解決するために

一つの方法は、使用するために次のようになります。

return [str(a.string) for a in soup.findAll(href=USERNAME_PATTERN)] 

こうスープオブジェクトへの参照が保持されていない、と表現がすぐに実行され、str Sのリストが返されます。

+0

これはそれですか?ああ、私はそれを知らないために愚かな気がする、ありがとう! – edsheeran

+0

@edsheeran少なくとも、メモリの使用量は少なくて済むはずですが、実際にテストしていません。また、最終的にどのように結果を使用するかによっても異なる場合があります。 – mata

1

Python Resource Libraryを使用すると、プロセスのスレッドが親プロセスのメモリを使用するため、余分なメモリを割り当てることができないため、プロセス割り当てメモリを増やすことができます。

関連する問題