2016-04-11 30 views
0

Python'u kullanarak birkaç bin görüntü indirmeye çalışıyorum ve çoklu işlemeyi ve lib'leri talep ediyorum. İşler yoluna giriyor ama yaklaşık 100 resim içeriyor, her şey kilitleniyor ve süreçleri öldürmem gerekiyor. Python 2.7.6 kullanıyorum.Python İstekleri ve Çok İşlemesiyle Pek Çok Resmin İndirilmesi

import requests 
import shutil 
from multiprocessing import Pool 
from urlparse import urlparse 

def get_domain_name(s): 
    domain_name = urlparse(s).netloc 
    new_s = re.sub('\:', '_', domain_name) #replace colons 
    return new_s 

def grab_image(url): 
    response = requests.get(url, stream=True, timeout=2) 
    if response.status_code == 200: 
     img_name = get_domain_name(url) 
     with open(IMG_DST + img_name + ".jpg", 'wb') as outf: 
      shutil.copyfileobj(response.raw, outf) 
     del response 

def main():           
    with open(list_of_image_urls, 'r') as f:     
     urls = f.read().splitlines()                
    urls.sort()          
    pool = Pool(processes=4, maxtasksperchild=2) 
    pool.map(grab_image, urls)      
    pool.close()         
    pool.join() 

if __name__ == "__main__": 
    main() 

Düzenleme: İşte kod çoklu işlem ithalat değiştirdikten sonra konuları yerine süreçleri hala aynı sorunu yaşıyorum kullanmak multiprocessing.dummy için. Görünüşe göre, bazen tek bir görüntü yerine bir hareket jpeg akışına isabet ediyorum, bu da ilgili sorunlara neden oluyor. Bu sorunu çözmek için bir içerik yöneticisi kullanıyorum ve bir FileTooBigException oluşturdum. herhangi bir iyileştirme hoşgeldin önerdi

class FileTooBigException(requests.exceptions.RequestException): 
    """File over LIMIT_SIZE""" 


def grab_image(url): 
    try: 
     img = '' 
     with closing(requests.get(url, stream=True, timeout=4)) as response: 
      if response.status_code == 200: 
       content_length = 0 
       img_name = get_domain_name(url) 
       img = IMG_DST + img_name + ".jpg" 
       with open(img, 'wb') as outf: 
        for chunk in response.iter_content(chunk_size=CHUNK_SIZE): 
         outf.write(chunk) 
         content_length = content_length + CHUNK_SIZE 
         if(content_length > LIMIT_SIZE): 
          raise FileTooBigException(response) 
    except requests.exceptions.Timeout: 
     pass 
    except requests.exceptions.ConnectionError: 
     pass 
    except socket.timeout: 
     pass 
    except FileTooBigException: 
     os.remove(img) 
     pass 

Ve: Ben aslında bir resim dosyası ve diğer bazı ev temizliği indirdiğiniz emin olmak için uygulamıyor kontrol ederken, aşağıda kod birisi için yararlı olabileceğini düşündük!

+1

Kilitlendiğinde hata/uyarı alıyor musunuz? Nereye kilitlendiğini anlayabiliyor musun diye bir hata ayıklama yaptın mı? Aynı görüntülerde sürekli kilitleniyor mu? – Andy

+1

İşlem hala çalışırken herhangi bir CPU kullanıyor mu? Ne kadar bellek ayrıldı? 32-bit mi, 64-bit mi çalışıyorsun? Kilitlenene kadar dosyaları mı oluşturuyor? 0 bayt dosyaları gibi sıra dışı bir çöp bırakıyor mu? Kilitlendiğinde ne kadar disk alanı kaldınız? –

cevap

1

G/Ç eşzamanlılığı için multiprocessing kullanımında hiçbir nokta yoktur. Ağ G/Ç'de, işlenen iplik sadece çoğu zaman hiçbir şey yapmadan bekler. Ve Python konuları hiçbir şey yapmamak için mükemmeldir. Yani, bir processpool yerine iş parçacığı kullanın. Her süreç çok fazla kaynak tüketir ve I/O ile ilişkili faaliyetler için gereksizdir. Thread'ler işlem durumunu paylaşırken ve tam olarak aradığınız şeydir.