9

Python(2.6)でできればリクエストモジュールを介して複数のファイルを非同期にダウンロードする方法を見つけようとしています。Gevent と Twisted も、近いうちに学習するので、受け入れられるでしょう。

私のアプリケーションでは、40 以上のファイルを短時間でダウンロードする必要があります。一度に 4 つのすべてのファイルを継続的にダウンロードしたいと考えています。そして、1 つのファイルのダウンロードが完了するたびに、別のファイルのダウンロードが開始されるため、4 のままになります。これは可能ですか?

4

1 に答える 1

13

このような単純なタスクに外部ライブラリやフレームワークを使用する必要はありません。URL のリストをキューに入れ、4 つのスレッドを開始すると、各スレッドはキューからアイテムを取得してダウンロードする必要があります。

このようなもの:

import sys
import os
import urllib
import threading
from Queue import Queue

class DownloadThread(threading.Thread):
    def __init__(self, queue, destfolder):
        super(DownloadThread, self).__init__()
        self.queue = queue
        self.destfolder = destfolder
        self.daemon = True

    def run(self):
        while True:
            url = self.queue.get()
            try:
                self.download_url(url)
            except Exception,e:
                print "   Error: %s"%e
            self.queue.task_done()

    def download_url(self, url):
        # change it to a different way if you require
        name = url.split('/')[-1]
        dest = os.path.join(self.destfolder, name)
        print "[%s] Downloading %s -> %s"%(self.ident, url, dest)
        urllib.urlretrieve(url, dest)

def download(urls, destfolder, numthreads=4):
    queue = Queue()
    for url in urls:
        queue.put(url)

    for i in range(numthreads):
        t = DownloadThread(queue, destfolder)
        t.start()

    queue.join()

if __name__ == "__main__":
    download(sys.argv[1:], "/tmp")

利用方法:

$ python download.py http://en.wikipedia.org/wiki/1 http://en.wikipedia.org/wiki/2 http://en.wikipedia.org/wiki/3 http://en.wikipedia.org/wiki/4
[4456497152] Downloading http://en.wikipedia.org/wiki/1 -> /tmp/1
[4457033728] Downloading http://en.wikipedia.org/wiki/2 -> /tmp/2
[4457701376] Downloading http://en.wikipedia.org/wiki/3 -> /tmp/3
[4458258432] Downloading http://en.wikipedia.org/wiki/4 -> /tmp/4
于 2013-09-18T23:26:35.333 に答える