2012-10-24 15 views
5

मैंने स्केपर का उपयोग करके एक मकड़ी लिखी, जो साइट्स को अलग करने के लिए HtmlXPathSelector अनुरोधों का पूरा समूह बनाता है। प्रत्येक अनुरोध (असीमित रूप से) संतुष्ट होने के बाद यह एक .csv फ़ाइल में डेटा की एक पंक्ति बनाता है। यह देखना असंभव है कि कौन सा अनुरोध आखिरी बार संतुष्ट है, क्योंकि अगर कोई डेटा निकाला नहीं गया है तो अनुरोध दोहराया जाता है (कभी-कभी यह डेटा को कुछ बार याद करता है)। भले ही मैं एक साफ सूची के साथ शुरू करता हूं, आउटपुट झुका हुआ है क्योंकि डेटा निकालने के तुरंत बाद पंक्तियां लिखी जाती हैं।स्पाइडर_क्लोज़ सिग्नल भेजे जाने से ठीक पहले पाइथन स्कैपर फ़ंक्शन को कॉल किया जाना चाहिए?

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

def start_requests(self) 
    ... dispatcher.connect(self.spider_closed, signal=signals.engine_stopped) .... 


def spider_closed(spider): 
    print 'this gets printed alright' # <-only if the next line is omitted... 
    out = self.AnotherFunction(in)  # <-This doesn't seem to run 
+0

मुझे लगता है कि आप सिग्नल में 1 से अधिक फ़ंक्शन संलग्न कर सकते हैं। क्या यह आपकी समस्या का समाधान करेगा? –

+0

आप वास्तव में सिग्नल को एक फ़ंक्शन से जोड़ सकते हैं ... मेरा मानना ​​है कि मेरी वास्तविक समस्या 'स्केपर' की संरचना के साथ थी - इसे पहले मकड़ी के माध्यम से चलाने के लिए एक .py फ़ाइल बनाकर हल किया गया था, और उसके बाद सॉर्ट करें आउटपुट फ़ाइल बाद में। इससे बहुत मदद मिली: http://snipplr.com/view/67012/selfcontained-script-to-crawl-a-site-updated-scrapy-130dev/ – corg

+1

प्रेषक नहीं होना चाहिए। कनेक्ट (...) __init __ में होना चाहिए () start_requests() के बजाय? – imwilsonxu

उत्तर

0

मैंने आपके लिए इस समस्या को हल करने के लिए एक पाइपलाइन को एक साथ हैक किया।

फ़ाइल: Project.middleware_module.SortedCSVPipeline

import csv 
from scrapy import signals 


class SortedCSVPipeline(object): 

    def __init__(self): 
     self.items = [] 
     self.file_name = r'YOUR_FILE_PATH_HERE' 
     self.key = 'YOUR_KEY_HERE' 

    @classmethod 
    def from_crawler(cls, crawler): 
     pipeline = cls() 
     crawler.signals.connect(pipeline.spider_closed, signals.spider_closed) 
     return pipeline 

    def spider_closed(self, spider): 
     for item in sorted(self.items, key=lambda k: k[self.key]): 
      self.write_to_csv(item) 

    def process_item(self, item, spider): 
     self.items.append(item) 
     return item 

    def write_to_csv(self, item): 
     writer = csv.writer(open(self.file_name, 'a'), lineterminator='\n') 
     writer.writerow([item[key] for key in item.keys()]) 

फ़ाइल: settings.py

ITEM_PIPELINES = {"Project.middleware_module.SortedCSVPipeline.SortedCSVPipeline" : 1000} 

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

चीयर्स

+0

खैर मैंने यह नहीं देखा कि यह 2012 से था ... उम्मीद है कि यह किसी को मदद करता है – rocktheartsm4l

+0

इस एक हां को पुनर्जीवित करने के लिए धन्यवाद - इस परियोजना के पास और भी नहीं है, लेकिन मुझे विश्वास होगा कि यह काम करेगा – corg

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

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