2009-03-20 9 views
9

मेरे पास एक वेब.py सर्वर है जो विभिन्न उपयोगकर्ता अनुरोधों का उत्तर देता है। इन अनुरोधों में से एक में वेब पृष्ठों की श्रृंखला डाउनलोड और विश्लेषण करना शामिल है।पायथन: यूआरएल सामग्री का सरल एसिंक डाउनलोड?

क्या वेब.py में एसिंक/कॉलबैक आधारित यूआरएल डाउनलोड तंत्र स्थापित करने का कोई आसान तरीका है? कम संसाधन उपयोग विशेष रूप से महत्वपूर्ण है क्योंकि प्रत्येक उपयोगकर्ता द्वारा अनुरोधित अनुरोध के परिणामस्वरूप कई पृष्ठों का डाउनलोड हो सकता है।

प्रवाह दिखाई देगा:

उपयोगकर्ता अनुरोध -> web.py -> डाउनलोड समानांतर या असमकालिक में 10 पृष्ठ -> विश्लेषण सामग्री, वापसी परिणाम

मैं स्वीकार करते हैं कि मुड़ एक अच्छा तरीका होगा ऐसा करने के लिए, लेकिन मैं पहले से ही web.py में हूं इसलिए मैं विशेष रूप से उस चीज़ में रूचि रखता हूं जो web.py के भीतर फिट हो सकता है।

उत्तर

2

asynchat और asyncore का उपयोग करने वाले async http क्लाइंट का उपयोग करें। http://sourceforge.net/projects/asynchttp/files/asynchttp-production/asynchttp.py-1.0/asynchttp.py/download

+0

मेरे पास कुछ हैं asynchttpclient कोड के लिए बग फिक्स। मैंने लेखक को मेल करने की कोशिश की, लेकिन वह आसपास नहीं लग रहा है। यदि आप उन सुधारों को चाहते हैं, तो आप मुझे ईमेल कर सकते हैं। मैंने अतिरिक्त रूप से HTTP अनुरोध पाइपलाइनिंग भी सक्षम की है, जो कई छोटे अनुरोधों के लिए गति को अतिरिक्त बढ़ावा देना चाहिए। – dhruvbird

+0

आप यहां asynchttp क्लाइंट को बग-फ़िक्स और एक्सटेंशन पा सकते हैं: http://code.google.com/p/asynhttp/ – dhruvbird

0

मुझे यकीन नहीं है कि मैं आपका प्रश्न समझ रहा हूं, इसलिए मैं शुरू करने के लिए कई आंशिक उत्तर दूंगा।

  • आपकी चिंता web.py कहीं से डेटा डाउनलोड करने और जवाब देने से पहले परिणामों का विश्लेषण करने के लिए है, और आप डर अनुरोध टाइम आउट से पहले परिणाम के लिए तैयार हैं, तो आप काम को विभाजित करने के ajax इस्तेमाल कर सकते हैं कि है अप। क्लाइंट के पास तब तक परिणामों के लिए अलग-अलग मतदान करने के लिए एक कंटेनर पेज (परिणामों को पकड़ने के लिए) और कुछ जावास्क्रिप्ट के साथ तुरंत लौटें। इस प्रकार ग्राहक कभी भी सर्वर के लिए इंतजार नहीं करता है, हालांकि उपयोगकर्ता को अभी भी परिणामों की प्रतीक्षा करनी है।
  • यदि आपकी चिंता ग्राहक को परिणाम प्राप्त करने के लिए सर्वर की प्रतीक्षा कर रही है, तो मुझे संदेह है कि यह वास्तव में एक समस्या होगी। आपका नेटवर्किंग परतों या तो ajax या रीडायरेक्ट के चतुर उपयोग इंतजार-ऑन-राइट
  • को आप सर्वर इंतजार कर रहे हैं, जबकि ग्राहक कहीं और से स्थिर सामग्री डाउनलोड करता है के बारे में चिंता कर रहे हैं आप की आवश्यकता नहीं होनी चाहिए, आपकी समस्या का समाधान करना चाहिए
+0

AJAX समाधान के साथ समस्या क्रॉस-डोमेन प्रतिबंध है - मैं मूल सर्वर से आने वाले पृष्ठों से सामग्री नहीं ले सकता। बीटीडब्ल्यू, मैं इस मामले में लिखने के बारे में चिंतित नहीं हूं , लेकिन वास्तव में नेटवर्किंग परत द्वारा इसका कोई ख्याल नहीं रखा गया है। – Parand

+0

@ पैरांड - नहीं, लेकिन आप अपने डोमेन में एक सस्ते पासस्ट्रू प्रॉक्सी स्थापित कर सकते हैं और उन्हें उस से खींच सकते हैं। – MarkusQ

0

मुझे नहीं पता कि यह वास्तव में काम करेगा या नहीं, लेकिन ऐसा लगता है कि यह हो सकता है: EvServer: Python Asynchronous WSGI Server में web.py interface है और ब्राउज़र क्लाइंट को धूमकेतु शैली धक्का दे सकता है।

यदि यह सही नहीं है, तो आप पेजों के एसिंक डाउनलोड के लिए Concurrence HTTP client का उपयोग कर सकते हैं और यह पता लगा सकते हैं कि AJAX या धूमकेतु के माध्यम से ब्राउज़र में उनकी सेवा कैसे करें।

0

मार्कसक्यू के उत्तर की पंक्तियों के साथ, MochiKit एक अच्छी जावास्क्रिप्ट लाइब्रेरी है, जिसमें ट्विस्ट द्वारा प्रेरित मजबूत एसिंक विधियां हैं।

0

असल में आप web.py के साथ मुड़कर एकीकृत कर सकते हैं। मुझे सच में यकीन नहीं है कि मैंने इसे केवल django के साथ किया है (इसके साथ मुड़ता हुआ)।

4

एक विकल्प किसी प्रकार की एक कतार पर काम पोस्ट करने के लिए (आप pyactivemq साथ ActiveMQ या STOMP एक कनेक्टर के रूप में की तरह कुछ Enterprisey इस्तेमाल कर सकते हैं या आप कुछ हल्के तरह Kestrel जो स्काला में लिखा है इस्तेमाल कर सकते हैं हो सकता है और एक ही बोलती हैं memocache के रूप में protocl ताकि आप बस बात करने के लिए पाइथन memcache क्लाइंट का उपयोग कर सकते हैं)।

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

यदि आप बाहरी कार्यकर्ता प्रक्रियाओं को प्रबंधित नहीं करना चाहते हैं तो आप कार्यकर्ता थ्रेड को उसी पाइथन प्रक्रिया में बना सकते हैं जो वेबसर्वर चला रहा है, लेकिन फिर स्पष्ट रूप से आपके वेब पेज सेवारत प्रदर्शन को प्रभावित करने की अधिक संभावना होगी ।

2

मैं बस उस सेवा में एक सेवा का निर्माण करूंगा जो उस समवर्ती fetch और विश्लेषण और web.py से एक साधारण http अनुरोध के रूप में उपयोग करता है।

3

आप फ़ाइलें और Queue मॉड्यूल डाउनलोड करने के लिए कार्यकर्ता धागे की एक संख्या का प्रबंधन करने के urllib उपयोग करने में सक्षम हो सकता है। उदाहरण:

import urllib 
from threading import Thread 
from Queue import Queue 

NUM_WORKERS = 20 

class Dnld: 
    def __init__(self): 
     self.Q = Queue() 
     for i in xrange(NUM_WORKERS): 
      t = Thread(target=self.worker) 
      t.setDaemon(True) 
      t.start() 

    def worker(self): 
     while 1: 
      url, Q = self.Q.get() 
      try: 
       f = urllib.urlopen(url) 
       Q.put(('ok', url, f.read())) 
       f.close() 
      except Exception, e: 
       Q.put(('error', url, e)) 
       try: f.close() # clean up 
       except: pass 

    def download_urls(self, L): 
     Q = Queue() # Create a second queue so the worker 
        # threads can send the data back again 
     for url in L: 
      # Add the URLs in `L` to be downloaded asynchronously 
      self.Q.put((url, Q)) 

     rtn = [] 
     for i in xrange(len(L)): 
      # Get the data as it arrives, raising 
      # any exceptions if they occur 
      status, url, data = Q.get() 
      if status == 'ok': 
       rtn.append((url, data)) 
      else: 
       raise data 
     return rtn 

inst = Dnld() 
for url, data in inst.download_urls(['http://www.google.com']*2): 
    print url, data 
6

यहां कोड का एक दिलचस्प टुकड़ा है। मैं इसे अपने आप का उपयोग नहीं किया है, लेकिन यह अच्छा लग रहा है;)

https://github.com/facebook/tornado/blob/master/tornado/httpclient.py

कम स्तर AsyncHTTPClient:

"एक गैर अवरुद्ध HTTP pycurl उदाहरण उपयोग के साथ समर्थित ग्राहक:।"

import ioloop 

def handle_request(response): 
    if response.error: 
     print "Error:", response.error 
    else: 
     print response.body 
    ioloop.IOLoop.instance().stop() 

http_client = httpclient.AsyncHTTPClient() 
http_client.fetch("http://www.google.com/", handle_request) 
ioloop.IOLoop.instance().start() 

" लाने() एक स्ट्रिंग URL या एक HttpRequest उदाहरण है, जो क्रियान्वित पोस्ट/PUT/अनुरोध DELETE की तरह अधिक विकल्प प्रदान करता है, ले जा सकते हैं।

कीवर्ड तर्क max_clients AsyncHTTP क्लाइंट कन्स्ट्रक्टर को अधिकतम fetch() ऑपरेशंस की अधिकतम संख्या निर्धारित करता है जो प्रत्येक IOLoop पर समानांतर में निष्पादित कर सकते हैं। "

वहाँ भी प्रगति पर नए दिया गया है: https://github.com/facebook/tornado/blob/master/tornado/simple_httpclient.py " कोई बाहरी निर्भरता के साथ गैर अवरुद्ध HTTP ग्राहक। ... इस वर्ग के विकास में अब भी है और अभी तक उत्पादन प्रयोग के लिए सिफारिश नहीं "

2

आजकल उत्कृष्ट अजगर libs आप उपयोग कर सकते हैं कर रहे हैं -। urllib3 (धागा पूल का उपयोग करता है) और requests (urllib3 या गैर के माध्यम से धागा पूल का उपयोग करता है gevent के माध्यम से IO को अवरुद्ध करना)

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