2016-10-21 2 views
1

私はインターネットから写真をダウンロードしています。その結果、多くの写真をダウンロードする必要があります。私は実際に私が写真をダウンロードし、ダウンロードをするつもりリンクをループ(以下のコードのバージョンを使用しています:スピードアップurlib.urlretrieve

import urllib 
urllib.urlretrieve(link, filename) 

私はひどく遅い番号に基づいておよそ1000年の画像を15分ごとに、ダウンロードしています。、ダウンロードを並列化するコンピュータクラスタ上でジョブを実行するだけでなく

import socket 
socket.setdefaulttimeout(5) 

です:私はダウンロードする必要が

効率化のために絵を、私はタイムアウトを5秒ごとに(まだ多くのダウンロードがずっと長持ち)を設定しましたそこに画像をより速く/より効率的にダウンロードするにはどうしたらいいですか?

+0

これはあなたにインスピレーションを与えることができると思います:http://stackoverflow.com/questions/1628766/python-package-for-multi-threaded-spider-w-proxy-support – snahor

+0

傷病や捻挫などのパッケージを調べます。治療はねじれに基づいていますが、少し使いやすくなっています。どちらもノンブロッキングAPIを提供します。この方法で、複数のファイルを1つとしてダウンロードできます。 **ちょうどいいと同じサーバーからの並列ダウンロードの数を制限する** –

+0

こんにちはTammo、ありがとう。 Btw、私はurllib2とscrappyを比較する優秀な記事を見つけました:http://www.scrapinginsider.com/2016/01/scrapy-urllib2-requests-beautifulsoup-lxml.html - また、私はマルチスレッドが大幅にパフォーマンスを向上させることができると信じています上のコードの。一度私はそれを行う方法を正確に把握すると私は答えを投稿します –

答えて

1

上記の私のコードは、私がマルチスレッドを利用しなかったので、とても素朴でした。明らかにURLリクエストに応答する必要がありますが、プロキシサーバーが応答している間にコンピュータがそれ以上のリクエストを行うことができない理由はありません。

次の調整を行うことで、効率を10倍向上させることができます。また、治療などのパッケージを使用して効率を改善する方法もあります。

1)関数で取得したURLカプセル化:

import import urllib.request 

def geturl(link,i): 
try: 
    urllib.request.urlretrieve(link, str(i)+".jpg") 
except: 
    pass 

2)すべてでコレクションを作成し、マルチスレッドを追加するマルチプロセッシングパッケージを使用して、以下のような何かを

URLだけでなく、あなたがダウンロードした映像のためにしたい名:

urls = [url1,url2,url3,urln] 
names = [i for i in range(0,len(urls))] 

3)は、マルチプロセッシングパッケージからプールのクラスをインポートして、このようなCLAを使用してオブジェクトを作成しますSS(明らかにあなたは、実際のプログラムであなたのコードの最初の行にあるすべての輸入品が含まれます):

from multiprocessing.dummy import Pool as ThreadPool 
pool = ThreadPool(100) 

その後、pool.starmap()メソッドを使用し、機能や関数の引数を渡します。

results = pool.starmap(geturl, zip(links, d)) 

注:pool.starmapは()

0

プログラムは、I/O待ちに入るのPython 3でのみ動作カーネルは、関連付けられた低レベルの操作を実行できるように、実行が一時停止されていますI/O要求(これはcontext switch)と呼ばれ、I/O操作が完了するまで再開されません)

コンテキスト切り替えは非常に重い操作です。プログラムの状態を保存する必要があります私たちはCPUレベルでキャッシュしていました)、CPUの使用をやめてしまいました。後で再び実行できるようになると、再初期化に時間を費やす必要があります私たちのプログラムをマザーボード上で実現し、再開する準備をしています(もちろん、これはすべて舞台裏で起こります)。

一方、concurrency,では、プログラム内で何が実行されるのかを管理する「イベントループ」と呼ばれるものがあります。本質的に、イベントループは単に実行する必要がある関数のリストです。リストの先頭にある関数が実行され、次に関数が実行されます。上記の使用可能なもののように思える場合

from Queue import Queue 
from functools import partial 

eventloop = None 

class EventLoop(Queue): 
    def start(self): 
     while True: 
      function = self.get() 
      function() 

def do_hello(): 
    global eventloop 
    print "Hello" 
    eventloop.put(do_world) 

def do_world(): 
    global eventloop 
    print "world" 
    eventloop.put(do_hello) 

if __name__ == "__main__": 
    eventloop = EventLoop() 
    eventloop.put(do_hello) 
    eventloop.start() 

、そしてあなたもgevent,tornado,AsyncIO,はあなたの問題を助けることができる方法を見てみたい:

以下はイベントループの簡単な例を示していますその後、あなたの(大学)図書館に行き、High Performance Python by Micha Gorelick and Ian Ozsvaldをチェックし、pp.181-202を読んでください。

注:上記のコードおよびテキストは、上記のbookからのものです。