ग्रैब क्या है: स्पाइडर

मैं सिर्फ ग्रैब डॉक्यूमेंट लिखना समाप्त नहीं कर सकता: एसिंक्रोनस स्पाइडर लिखने के लिए स्पाइडर ग्रैब लाइब्रेरी का हिस्सा है। एक geek पत्रिका पर प्रलेखन के टुकड़े बाहर रखना सोचा मुझे लगता है कि कुछ प्रतिक्रिया के साथ, चीजें तेजी से आगे बढ़ेंगी। फिलहाल, प्रलेखन में केवल एक परिचय है जो बताता है कि इस तरह के जानवर किस ग्रैब: स्पाइडर है। मैंने इसे फैलाया।

स्पाइडर मॉड्यूल एक फ्रेमवर्क है जो आपको साइट पार्सर को हैंडलर फ़ंक्शन के एक सेट के रूप में वर्णित करने की अनुमति देता है, जहां प्रत्येक हैंडलर एक विशिष्ट प्रकार के अनुरोध के लिए जिम्मेदार है। उदाहरण के लिए, एक मंच को पार्स करते समय, आपके पास मुख्य पृष्ठ, सबफ़ोर्म पृष्ठ, विषय पृष्ठ, सदस्य प्रोफ़ाइल पृष्ठ के लिए हैंडलर होंगे। प्रारंभ में, इस तरह के एक पार्सर संरचना को अतुल्यकालिक मोड की सीमाओं के कारण विकसित किया गया था, लेकिन बाद में यह पता चला कि ऐसे संरचित रूप में पार्सर्स लिखना (एक अनुरोध - एक फ़ंक्शन) बहुत सुविधाजनक है।

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

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

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

एक साधारण पार्सर के उदाहरण पर विचार करें। मान लीजिए कि हम habrahabr.ru पर जाना चाहते हैं, नवीनतम समाचारों के लिए सुर्खियां पढ़ें, तो प्रत्येक शीर्षक के लिए images.yandex.ru का उपयोग करके एक चित्र ढूंढें और डेटा को फ़ाइल में सहेजें:

# coding: utf-8 import urllib import csv import logging from grab.spider import Spider, Task class ExampleSpider(Spider): #  ,   Spider   #         #    initial initial_urls = ['http://habrahabr.ru/'] def prepare(self): #      #  prepare      #   self.result_file = csv.writer(open('result.txt', 'w')) #       #  ,      . self.result_counter = 0 def task_initial(self, grab, task): print 'Habrahabr home page' #        initial # ..   ,     #    self.initial_urls #         #     Grab for elem in grab.xpath_list('//h1[@class="title"]/a[@class="post_title"]'): #   -    #   habrapost #  ,       #  yield -      # -    : # self.add_task(Task('habrapost', url=...)) yield Task('habrapost', url=elem.get('href')) def task_habrapost(self, grab, task): print 'Habrahabr topic: %s' % task.url #  ,     #    ,  #     ,   #    #          post = { 'url': task.url, 'title': grab.xpath_text('//h1/span[@class="post_title"]'), } #       ,  , #     Task   .   #        ,    #      .   ,   #    Task     #         query = urllib.quote_plus(post['title'].encode('utf-8')) search_url = 'http://images.yandex.ru/yandsearch?text=%s&rpt=image' % query yield Task('image_search', url=search_url, post=post) def task_image_search(self, grab, task): print 'Images search result for %s' % task.post['title'] #         ,  #     !     , #           # .      ,   #   ,     `task.post`. image_url = grab.xpath_text('//div[@class="b-image"]/a/img/@src') yield Task('image', url=image_url, post=task.post) def task_image(self, grab, task): print 'Image downloaded for %s' % task.post['title'] #      . #  ,   . path = 'images/%s.jpg' % self.result_counter grab.response.save(path) self.result_file.writerow([ task.post['url'].encode('utf-8'), task.post['title'].encode('utf-8'), path ]) #     ,  #       self.result_counter += 1 if __name__ == '__main__': logging.basicConfig(level=logging.DEBUG) #      -   #  ,     #        ,      bot = ExampleSpider(thread_number=2) bot.run() 


उदाहरण में, सबसे सरल पार्सर माना जाता है और बहुत सारी विशेषताएं जो स्पाइडर कर सकती हैं प्रभावित नहीं होती हैं। उनके बारे में विस्तृत दस्तावेज में पढ़ें। कृपया ध्यान दें कि हैंडलर के कुछ कार्य विफल हो जाएंगे, उदाहरण के लिए, क्योंकि यैंडेक्स को दिए गए अनुरोध से कुछ भी नहीं मिलेगा।

इसके अलावा, मैं टास्क ऑब्जेक्ट बनाने, नेटवर्क त्रुटियों को संसाधित करने और गलती से रोक दिए गए कार्यों को बार-बार निष्पादित करने के कार्य का वर्णन करने की योजना बना रहा हूं।

लिखित रूप में, ग्रैब के बारे में सवाल मेलिंग सूची में सबसे अच्छे से पूछे जाते हैं: group.google.com/group/python-grab

आप ग्रैब के संशोधन के साथ-साथ ग्रैब और ग्रैब :: स्पाइडर, यहां: Grablab.org पर आधारित एक पार्सर का आदेश दे सकते हैं

Source: https://habr.com/ru/post/In142288/


All Articles