2015-11-20 64 views
2

因此,我建立了一個scrapy蜘蛛爬過網站內的所有內部鏈接。但是,當我運行蜘蛛時,有一些網站的大部分網站與網站內容無關。例如,一個網站運行詹金斯,而我的蜘蛛花費大量時間瀏覽與網站無關的這些網頁。防止scrapy蜘蛛爬行網站的一部分太長

一種方法是創建一個黑名單並添加一些路徑,如詹金斯,但我想知道是否有更好的方式來處理這個問題。

class MappingItem(dict, BaseItem): 
    pass 

class WebsiteSpider(scrapy.Spider): 
    name = "Website" 

    def __init__(self): 
     item = MappingItem() 
     self.loader = ItemLoader(item) 
     self.filter_urls = list() 

    def start_requests(self): 
     filename = "filename.csv" 
     try: 
      with open(filename, 'r') as csv_file: 
       reader = csv.reader(csv_file) 
       header = next(reader) 
       for row in reader: 
        seed_url = row[1].strip() 
        base_url = urlparse(seed_url).netloc 
        self.filter_urls.append(base_url) 
        request = Request(seed_url, callback=self.parse_seed) 
        request.meta['base_url'] = base_url 

        yield request 
     except IOError: 
      raise CloseSpider("A list of websites are needed") 

    def parse_seed(self, response): 
     base_url = response.meta['base_url'] 
     # handle external redirect while still allowing internal redirect 
     if urlparse(response.url).netloc != base_url: 
      return 
     external_le = LinkExtractor(deny_domains=base_url) 
     external_links = external_le.extract_links(response) 
     for external_link in external_links: 
      if urlparse(external_link.url).netloc in self.filter_urls: 
       self.loader.add_value(base_url, external_link.url) 

     internal_le = LinkExtractor(allow_domains=base_url) 
     internal_links = internal_le.extract_links(response) 

     for internal_link in internal_links: 
      request = Request(internal_link.url, callback=self.parse_seed) 
      request.meta['base_url'] = base_url 
      request.meta['dont_redirect'] = True 
      yield request 
+0

您是否正在使用鏈接提取?顯示您的蜘蛛代碼的相關部分可能有助於在這裏幫助。謝謝! – alecxe

回答

0

這聽起來像鏈接提取的deny_domains說法是東西給你使用的域的「黑名單」,不遵循:

deny_domains(STR或列表) - 單個值或字符串列表 包含將不被考慮用於提取鏈接的域

+0

這似乎是一個解決方案,但問題是,即使在我面對蜘蛛大部分時間花費的這個「窪地」時,我也不得不手動添加所有形式的sink孔。 –

+0

我想過規避這種情況的一種方法是通過限制您可以在特定路徑上進行的訪問次數,但問題在於,如果內容穩定,可能會有太多的誤報漏洞。例如,如果蜘蛛在www.website.com/jenkins/上花費了數千次請求,那麼它應該終止,但是如果「www.website.com/articles/」和成千上萬篇文章,蜘蛛應該發送因爲它們是相關材料。我想我需要做的是找到某種模式,可以區分有用和無用的網頁。 –

+0

@THISUSERNEEDSHELP明白了。你應該圍繞它創建一些自定義邏輯 - 例如,有一個域優先級映射可以定義一個域的相關性和一個計數器字典('defaultdict(int)'我想),你會用它來計算按域訪問。然後,您可以使用某種相關性來請求計數規則,以確定是否需要停止抓取特定域。這聽起來像是你需要一個定製的中間件......只是一種感覺。 – alecxe