2011-08-02 11 views
3

私はPythonを初めて使っていますので、私のコードは以下のようにクリーンではないかもしれません。プログラムの場合は、約500のWebページをダウンロードする必要があります。 URLは配列内に格納され、前の関数によって読み込まれます。ダウンロード部分は次のようになります。python - 〜500のWebページ(ループ)の速いダウンロード

各ファイルは約20KBですが、すべてをダウンロードするには少なくとも10分かかります。合計サイズのファイルを1つだけダウンロードするには、1〜2分かかります。私はこれをスピードアップできる方法はありますか?ありがとう

編集:http://code.google.com/p/workerpool/wiki/MassDownloaderに例を示し、50スレッドを使用すると、ダウンロード時間は元の10分プラスから約20秒に短縮されました。ダウンロード速度は、スレッドが約60スレッドまで増加するにつれて減少し続け、その後、ダウンロード時間は再び上昇し始める。

答えて

4

ただし、ここでは1つのファイルはダウンロードしていません。あなたは500の別々のページをダウンロードしています。それぞれの接続にはオーバーヘッド(初期接続用)とほかにサーバが何をしているのか(他の人にサービスしていますか?

どちらの方法でも、500 x 20kbをダウンロードすることは、そのサイズのファイルを1つダウンロードすることと同じではありません。

+0

もっと速い方法があれば同じ時間がかかるとは言いませんでした。 – Tim

3

スレッドを使用することで、実行速度を大幅に向上させることができます(サーバーに過負荷をかけないように注意してください)。

イントロ材料/コードサンプル:あなたがそうすることをgreenlet使用することができます

+2

500個のローカルスレッドを起動するのはやや高価です。 Webサーバで同時に500件のヒットを行うと、(あまりにも多くの)友好的なローカルシステム管理者からの訪問や、AUP違反による単純な禁止が発生する可能性があります。タスクをはるかに小さなスレッドプールに供給することを検討してください。 –

+0

完璧な、これを行くでしょう。上記の例では、一度に5つのスレッドを使用しています。ありがとう – Tim

+0

または、ツイストまたはマルチプロセッシングまたはその他の適切な並行処理方法。グリーンレットはスレッドではありません。 –

2

例えばeventlet libにして:

urls = [url1, url2, ...] 

import eventlet 
from eventlet.green import urllib2 

def fetch(url): 
    return urllib2.urlopen(url).read() 

pool = eventlet.GreenPool() 

for body in pool.imap(fetch, urls): 
    print "got body", len(body) 

プール内のすべての呼び出しは疑似simulatneousになります。

もちろん、前にpipまたはeasy_installでイベントレットをインストールする必要があります。

あなたはPythonでいくつかのgreenletsの実装をしています。あなたはgeventや他のものと同じことをすることができます。

+0

+1 –

0

何らかの並行性を使用することに加えて、要求を行うために使用している方法がHTTP 1.1接続の永続性を使用していることを確認してください。これにより、各スレッドは単一の接続のみを開き、各要求に対してTCP/IPのセットアップ/ティアダウンを行うのではなく、その上のすべてのページを要求できます。 urllib2がデフォルトでそれを行うかどうかはわかりません。あなた自身のロールを張らなければならないかもしれません。

関連する問題