2016-12-04 4 views
0

私はURLから画像をダウンロードするスクリプトを用意していますが、それ以外の場合は並列化したいと思います。このコードでは:列挙型ループでのマルチ処理

import requests 
from math import floor, log10 
import urllib 
import time 
import multiprocessing 

with open('images.csv', 'r') as f: 
    images = f.readlines() 

num_position = floor(log10(len(images)) + 1) 

a = time.time() 

for i, image in enumerate(images[1:10]): 
    if (i+1) % 1000 == 0: 
     print('Downloading {} image'.format(i+1)) 
# a = time.time() 
    with open(str(i).zfill(num_position)+'a.jpg', 'wb') as file: 
     try: 
      writing = file.write(requests.get(image.split(',')[2]).content) 
      p = multiprocessing.Process(target=writing, args=(image,)) 
      p.start() 
      p.join()  
     except: 
      print('Skipping an image!') 
      pass 
b = time.time() 
print('multiple process -- {}'.format(b-a)) 

私はエラーを取得する:

Process Process-9: 
Traceback (most recent call last): 
    File "/usr/lib/python3.4/multiprocessing/process.py", line 254, in _bootstrap 
    self.run() 
    File "/usr/lib/python3.4/multiprocessing/process.py", line 93, in run 
    self._target(*self._args, **self._kwargs) 
TypeError: 'int' object is not callable 
  1. は、なぜ私はエラーを取得していますが、タスクがまだ完了し、コードが壊れていないのですか? (と私は試しにその作品を意味する):
  2. ここにいくつかの種類の並列を含める最も簡単な方法は?

答えて

1

私の知る限り、このライン

writing = file.write(requests.get(image.split(',')[2]).content) 

は、整数型の出力を持っているので、あなたは、エラーが発生します。 writeは、イメージの文字列表現の長さに等しい書かれた文字数を返します。今度はそれを変数writingに割り当てます - >writingは数字になります。

p = multiprocessing.Process(target=writing, args=(image,)) 

は、あなたが関数が、整数型writing(呼び出し可能ではない)を呼び出していないので、エラーを発生させ、目標関数としてwriting呼び出します。このコードは、作業者が何もしないですぐに閉じることができ、ファイルが既に書かれているため機能します。

機能を有効にするには、画像を引数とし、ファイル名を指定する関数を定義する必要があります。この機能は後であなたの労働者の設定を呼び出します。そのような何か:

def write_file(image, filename): 
    filestream = open(filename, mode="w") 
    filestream.write(requests.get(image.split(',')[2]).content) 
    filestream.close() 

そして、あなたのアプリケーション

p = multiprocessing.Process(target=write_file, args=(image, filename,)) 

にはしかし、それはちょうど書込部です。別々のタスクでダウンロードをしたい場合は、そのコードを別の関数に入れなければなりません。

def download_write(urls): 
    for url in iter(urls.get, 'STOP'): 
     #download code here# 
     filestream = open(filename, mode="w") 
     filestream.write(requests.get(image.split(',')[2]).content) 
     filestream.close() 

そして、あなたの主なアプリケーション:詳細な回答のため

list_urls = [] # your list of urls to download 
urls = Queue() 
for element in list_urls: 
    urls.put(element) 
p = multiprocessing.Process(target=download_write, args=(urls,)) 
urls.put("STOP") #signals end of tasks for your workers 
p.start() #start worker 
p.join() #wait for worker to finish 
+0

多くの感謝! – jojo