2015-06-02 6 views
5

में मौजूद है या नहीं, मैं अपने अनुरोध करने के लिए python-requests लाइब्रेरी का उपयोग कर रहा हूं।यह देखने के लिए तेज़ तरीका है कि रिमोट यूआरएल पर छवि पाइथन

वेबसाइट के होम पेज पर, मुझे छवियों का एक गुच्छा मिलता है और उन्हें उपयोगकर्ता को दिखाता है। कभी-कभी उन छवियों को हटा दिया जाता है और मुझे एक टूटी हुई छवि यूआरएल मिलती है।

तो मैं यह जांचना चाहता हूं कि छवियां मौजूद हैं या नहीं।

यहाँ मैं क्या किया है:

items = Item.objects.filter(shop__is_hidden=False, is_hidden=False).order_by("?")[:16] 

existing_items = [] 

for item in items: 
    response = requests.head(item.item_low_url) 
    if response.status_code == 200: 
     existing_items.append(item) 

लेकिन यह एक समय लग रहा है की तुलना में मैं चाहता हूँ।

क्या कोई तेज तरीका है?

उत्तर

4

आपके अनुरोध अवरुद्ध और तुल्यकालिक हैं, इसलिए यह थोडा समय ले रहा है। सरल शब्दों में, इसका मतलब है कि दूसरा अनुरोध शुरू नहीं होता है, जब तक कि पहला पूरा नहीं होता है।

इसे एक कन्वेयर बेल्ट की तरह बक्से के गुच्छा के साथ सोचें और आपके पास प्रत्येक बॉक्स को संसाधित करने के लिए एक कार्यकर्ता है।

कर्मचारी एक समय में केवल एक बॉक्स को संसाधित कर सकता है; और उसे प्रसंस्करण के लिए एक और बॉक्स प्रसंस्करण शुरू करने से पहले इंतजार करना पड़ता है (दूसरे शब्दों में, वह बेल्ट से एक बॉक्स नहीं ले सकता है, इसे कहीं संसाधित करने के लिए छोड़ देता है, वापस आकर दूसरे को चुन सकता है)।

समय यह प्रक्रियाओं बक्से पर ले जाता है कम करने के लिए, आप:

  1. समय यह प्रत्येक बॉक्स के संसाधन में लगने को कम करें।
  2. इसे बनाओ ताकि एक ही समय में एकाधिक बॉक्स संसाधित किए जा सकें (दूसरे शब्दों में, कार्यकर्ता को प्रतीक्षा करने की आवश्यकता नहीं है)।
  3. बेल्ट और श्रमिकों की संख्या बढ़ाएं और फिर बेल्ट के बीच के बक्से को विभाजित करें।

हम वास्तव में # 1 नहीं कर सकते क्योंकि यह देरी नेटवर्क से है (आप टाइमआउट अवधि को कम कर सकते हैं, लेकिन इसकी अनुशंसा नहीं की जाती है)।

इसके बजाय हम क्या करना चाहते हैं # 2 - चूंकि एक बॉक्स की प्रसंस्करण स्वतंत्र है, हमें अगले बॉक्स को संसाधित करने के लिए समाप्त होने के लिए एक बॉक्स की प्रतीक्षा करने की आवश्यकता नहीं है।

  1. जल्दी ही समय पर यूआरएल के लिए एक सर्वर के लिए एक से अधिक अनुरोध भेजें:

    तो हम निम्न कार्य करना चाहते हैं।

  2. उनमें से प्रत्येक को समाप्त करने के लिए प्रतीक्षा करें (एक दूसरे से स्वतंत्र)।
  3. परिणाम एकत्रित करें।

documentation for requests में सूचीबद्ध करने के लिए कई तरीके हैं; यहां grequests का उपयोग करके एक उदाहरण दिया गया है:

import grequests 

# Create a map between url and the item 
url_to_item = {item.item_low_url: item for item in items} 

# Create a request queue, but don't send them 
rq = (grequests.head(url) for url in url_to_item.keys()) 

# Send requests simultaneously, and collect the results, 
# and filter those that are valid 

# Each item returned in the Response object, which has a request 
# property that is the original request to which this is a response; 
# we use that to filter out the item objects 

results = [url_to_item[i.request.url] 
      for i in filter(lambda x: x.status_code == 200, 
          grequests.map(rq)))] 
+0

आपके व्यापक उत्तर के लिए धन्यवाद। यह निश्चित रूप से तेज़ हो गया, लेकिन 'परिणाम' 'प्रतिक्रिया 'वस्तुओं की एक सूची बन गया, आइटम नहीं, जो आश्चर्यजनक है। इसे ठीक करने के लिए कोई विचार? –

+0

इसका कारण प्रतिक्रिया वस्तुओं का एक गुच्छा है क्योंकि यह 'grequests.map (rq)' से वापसी है।मूल 'आइटम' पर वापस मैप करने के तरीके के लिए अपडेट देखें। –

+0

बहुत बहुत धन्यवाद :) –

संबंधित मुद्दे

 संबंधित मुद्दे