2017-01-23 33 views
0

我是新來的python。目前,我試圖實現一個程序來從遠程服務器(http/https)下載大量文件。沒有。的文件很大(> 1000)。爲了處理這個問題,我需要以某種方式實現代碼,以便能夠以高效和最優的方式利用操作系統資源。爲了處理這個問題,我採取的方式是多處理。在Python中的多線程優化下載文件

這裏,是我實現:

import urllib,urlparse 
import urllib2 
import os 
import multiprocessing 
from multiprocessing.dummy import Pool as ThreadPool 
from itertools import repeat 

def download_file((url, d_dir)) : 
    #logger.debug('Download URL -> ' + url) 

    try : 
     with open(d_dir + os.sep + urlparse.urlparse(url).path, 'wb') as tfile : 
      tfile.write(urllib2.urlopen(url).read()) 

    except : 
     logger.error('There was a some problem while downloading file, ' + url) 


def create_pool(d_links, d_dir) : 
    pool = multiprocessing.Pool(processes=10) 
    pool.map(download_file, zip(d_links, repeat(d_dir))) 

def extract_urls() : 
    # some logic to extract urls from files 
    links = {‘url1’, ‘url2’, ‘url3’, ‘url4’, ‘url5’, …} 

    #created process pool 
    create_pool(links, l_dir) 

如果我運行這段代碼,它給了我正常輸出。但我想我沒有正確實現多處理。你可以給一些輸入來優化這段代碼嗎?

在此先感謝。

問候, 阿希什

回答

1

你可以做到這一點

import multiprocessing as mp 
with mp.Pool(4) as pool: 
    pool.map_async(download_file, zip(d_links, repeat(d_dir))) 

參考:https://docs.python.org/3/library/multiprocessing.html#module-multiprocessing.pool

注意map_async不平行的工作,但地圖塊的過程,直到被叫函數返回

+0

「回溯(最近通話最後一個): 文件 「FileScanner.py」,線路192,在create_pool create_threadpool(d_links,d_dir) 文件 「FileScanner.py」 ,第195行,在create_threadpool 與multiprocessing.Pool(4)作爲池: AttributeError:__exit__' 以上錯誤我得到如果我按照您的建議實施 –

+0

@AshishMisra抱歉,但我沒有得到錯誤。我編輯了我的答案兩次,也許再試一次 –

+0

@MatthiasGlich:謝謝。其實你是對的,但我的服務器上的python版本是2.7,你的建議是從python 3。 –

0

我在python 2.7中遇到了同樣的問題。問題是multiprocessing庫在pool.map(func,arg)中不支持多個參數。作爲我使用pathos的多處理庫的解決方案。 所以你的功能可能是如下

from pathos.multiprocessing import ProcessingPool as Pool 
from itertools import izip 

p = Pool(self.nbr_processes) 
     try: 
      p.map(download_file, izip(d_links, repeat(d_dir))) 
      p.close() 
      p.join() 

     except Exception as f: 
      logging.error(f)