2015-09-23 5 views
10

मेरे पास स्पाइडर है जो डेटा को स्क्रैप करता है जिसे एक आइटम क्लास में सहेजा नहीं जा सकता है।स्केपर, पायथन: एक पाइपलाइन में एकाधिक आइटम कक्षाएं?

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

  1. हालांकि, मैं नहीं जानता कि कैसे एक parse_item समारोह के साथ एक पाइप लाइन के दो अलग-अलग आइटम कक्षाएं संभाल कर सकते हैं?

  2. या क्या विभिन्न parse_item फ़ंक्शंस का उपयोग करना संभव है?

  3. या मुझे कई पाइपलाइनों का उपयोग करना है?

  4. या क्या एक स्केपर आइटम फ़ील्ड में इटरेटर लिखना संभव है?


comments_list=[] 
comments=response.xpath(somexpath) 
for x in comments.extract(): 
     comments_list.append(x) 
    ScrapyItem['comments'] =comments_list 

उत्तर

1

सरल तरीके पार्सर दो उप पारसर्स, प्रत्येक डेटा प्रकार के लिए एक शामिल है। मुख्य पार्सर इनपुट से प्रकार निर्धारित करता है और स्ट्रिंग को उपयुक्त सबराउटिन में पास करता है।

एक दूसरा दृष्टिकोण अनुक्रम में पार्सर्स को शामिल करना है: एक पार्स प्रोफाइल और अन्य सभी को अनदेखा करता है; दूसरा पार्स टिप्पणियां और अन्य सभी को अनदेखा करता है (ऊपर जैसा सिद्धांत)।

क्या यह आपको आगे बढ़ता है?

9

डिफ़ॉल्ट रूप से प्रत्येक आइटम प्रत्येक पाइपलाइन के माध्यम से जाता है।

उदाहरण के लिए, यदि आप ProfileItem और CommentItem उत्पन्न करते हैं, तो वे दोनों पाइपलाइनों से गुजरेंगे। आप पटरियों आइटम प्रकार के लिए एक पाइप लाइन सेटअप है, तो अपने process_item विधि दिखाई दे सकता है जैसे:

def process_item(self, item, spider): 
    self.stats.inc_value('typecount/%s' % type(item).__name__) 
    return item 

एक ProfileItem बात आती है, के माध्यम से 'typecount/ProfileItem' वृद्धि की जाती है। जब CommentItem आता है, 'typecount/CommentItem' बढ़ता है।

आप, आइटम अनुरोध में से एक पाइपलाइन संभाल केवल एक ही प्रकार हो सकता है, हालांकि अगर वह आइटम प्रकार से निपटने अद्वितीय है, आगे बढ़ने से पहले आइटम प्रकार देख सकते हैं:

def process_item(self, item, spider): 
    if not isinstance(item, ProfileItem): 
     return item 
    # Handle your Profile Item here. 

आप उपरोक्त दो process_item तरीकों था विभिन्न पाइपलाइनों में सेटअप, आइटम उन दोनों के माध्यम से जाएगा, ट्रैक किया जा रहा है और संसाधित किया जा रहा है (या दूसरे पर नजरअंदाज कर दिया गया है)।

साथ ही आप सभी 'से संबंधित' आइटम को संभालने के लिए एक पाइपलाइन सेटअप हो सकता है:

def process_item(self, item, spider): 
    if isinstance(item, ProfileItem): 
     return self.handleProfile(item, spider) 
    if isinstance(item, CommentItem): 
     return self.handleComment(item, spider) 

def handleComment(item, spider): 
    # Handle Comment here, return item 

def handleProfile(item, spider): 
    # Handle profile here, return item 

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

5

एकाधिक आइटमों को परिभाषित करना यह एक मुश्किल बात है जब आप अपने डेटा को निर्यात कर रहे हैं (उदाहरण के लिए प्रोफाइल 1 - एन टिप्पणियां) और आपको उन्हें एक साथ निर्यात करना होगा क्योंकि प्रत्येक आइटम पाइपलाइनों द्वारा अलग-अलग समय पर संसाधित होता है । ,

class CommentItem(scrapy.Item): 
    profile = ProfileField() 

class ProfileField(scrapy.item.Field): 
    # your business here 

लेकिन परिदृश्य आप 2 आइटम नहीं हैं चाहिए जहां दिए गए यह अत्यधिक के इस प्रकार से हर एक के लिए एक अलग पाइप लाइन का उपयोग करने का सुझाव दिया है: इस स्थिति के लिए एक वैकल्पिक दृष्टिकोण उदाहरण के लिए एक कस्टम Scrapy फील्ड परिभाषित करने के लिए है वस्तुओं और भी अलग निर्यातक उदाहरणों ताकि आप (यदि आप फ़ाइलों का उपयोग कर रहे हैं) अलग अलग फ़ाइलों में यह जानकारी प्राप्त:

settings.py

ITEM_PIPELINES = { 
    'pipelines.CommentsPipeline': 1, 
    'pipelines.ProfilePipeline': 1, 
} 

pipelines.py

class CommentsPipeline(object): 
    def process_item(self, item, spider): 
     if isinstance(item, CommentItem): 
      # Your business here 

class ProfilePipeline(object): 
    def process_item(self, item, spider): 
     if isinstance(item, ProfileItem): 
      # Your business here 
संबंधित मुद्दे