2015-10-03 9 views
5

मैं एक स्क्रैप वेब स्क्रैपर पर काम कर रहा हूं जो एक प्रारंभिक यूआरएल से सभी आंतरिक लिंक के माध्यम से क्रॉल करता है और केवल scrapy के साथ बाहरी लिंक एकत्र करता है। हालांकि, मेरी मुख्य समस्या बाहरी लिंक और आंतरिक लिंक वर्गीकृत कर रही है। उदाहरण के लिए, जब मैं link.startswith("http") or link.startswith("ftp") or link.startswith("www") के साथ बाहरी लिंक को फ़िल्टर करने का प्रयास करता हूं, तो वेबसाइट /about के बजाय एक पूर्ण पथ (www.my-domain.com/about) के साथ अपनी वेबसाइट को लिंक करती है, तो यह बाहरी लिंक के रूप में इसे वर्गीकृत करेगी, भले ही यह न हो। निम्नलिखित मेरा कोड है:स्केपर: सभी बाहरी लिंक स्टोर करें और सभी इंटरल लिंक को क्रॉल करें

import scrapy 
from lab_relationship.items import Links 

class WebSpider(scrapy.Spider): 
    name = "web" 
    allowed_domains = ["my-domain.com"] 
    start_urls = (
     'www.my-domain.com', 
    ) 

    def parse(self, response): 
     """ finds all external links""" 
     items = [] 
     for link in set(response.xpath('//a/@href').extract()): 
      item = Links() 
      if len(link) > 1: 
       if link.startswith("/") or link.startswith("."): 
        # internal link 
        url = response.urljoin(link) 
        item['internal'] = url 
        #yield scrapy.Request(url, self.parse) 
       elif link.startswith("http") or link.startswith("ftp") or link.startswith("www"): 
        # external link 
        item['external'] = link 
       else: 
        # misc. links: mailto, id (#) 
        item['misc'] = link 
       items.append(item) 
     return items 

कोई सुझाव?

उत्तर

7

link extractor का उपयोग करें।

तत्काल होने पर आपको अनुमति डोमेन पास करना होगा। आपको आवश्यक टैग निर्दिष्ट करने के बारे में चिंता करने की आवश्यकता नहीं है, क्योंकि (दस्तावेज़ों के अनुसार) पैरामीटर tags डिफ़ॉल्ट रूप से ('a', 'area') लेता है।

जंग लैंग वेबसाइट के उदाहरण पर, कोड सभी आंतरिक लिंक मुद्रित करने के लिए अपने डोमेन से दिखाई देगा:

import scrapy 
from scrapy.linkextractors import LinkExtractor 


class RustSpider(scrapy.Spider): 
    name = "rust" 
    allowed_domains = ["www.rust-lang.org"] 
    start_urls = (
     'http://www.rust-lang.org/', 
    ) 

    def parse(self, response): 
     extractor = LinkExtractor(allow_domains='rust-lang.org') 
     links = extractor.extract_links(response) 
     for link in links: 
      print link.url 

और उत्पादन में इस तरह के लिंक की एक सूची होगा: https://doc.rust-lang.org/nightly/reference.html (मैं कर सकते हैं ' टी अधिक पोस्ट करें), जबकि स्टैक ओवरफ्लो जैसे सभी लिंक को छोड़कर।

कृपया प्रलेखन पृष्ठ को देखना सुनिश्चित करें, क्योंकि लिंक निकालने वाले के पास कई पैरामीटर हैं जिनकी आपको आवश्यकता हो सकती है।

+0

एचएम .. क्या आप LinkExtractor के साथ आंतरिक लिंक का एक सेट बनाने का सुझाव दे रहे हैं, और सभी लिंक के लिए, जांचें कि क्या वे आंतरिक लिंक से मेल खाते हैं, और यदि नहीं, तो वे बाहरी लिंक हैं? –

+0

बिल्कुल नहीं, 'deny_domains = 'डोमेन' सेट करके आप उन लिंक को निकाल सकते हैं जो किसी दिए गए डोमेन (बाहरी) में नहीं हैं। –

+0

ओह मैन। यह बिल्कुल सही है. बहुत बहुत धन्यवाद। –

-2

यदि एकाधिक या कथन ले सकते हैं, तो केवल दो नहीं।

+0

लेकिन मेरी सरणी में आंतरिक लिंक भी शामिल होंगे। मैं केवल बाहरी लिंक –

+0

हां चाहता हूं, बस ध्यान दें। अपना कोड देखकर, "अगर link.startswith ("/") या link.startswith ("। "):" लाइन में एकाधिक "या" कथन हो सकते हैं, अन्यथा शायद [स्विच] (https: // pypi) का उपयोग करें। python.org/pypi/switch) कथन – kcrk

+0

मैं पहले से ही अपने कोड में एकाधिक 'या' का उपयोग कर रहा हूं, और मुझे नहीं लगता कि यह रिश्तेदार लिंक –

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