2016-09-16 2 views
1

私は数日間このことに執着しており、それが私を狂ってしまいます。Scrapy:__init__内に設定されたルールはCrawlSpiderによって無視されます

私はこのように私のscrapyクモ呼び出す:

scrapy crawl example -a follow_links="True" 

私はWebサイト全体を掻き取りすべきかどうかを決定するために、「follow_links」フラグ、または私はクモで定義したばかりのインデックスページに渡します。

このフラグが設定されるべきルールを参照してクモのコンストラクタでチェックされます

def __init__(self, *args, **kwargs): 

    super(ExampleSpider, self).__init__(*args, **kwargs) 

    self.follow_links = kwargs.get('follow_links') 
    if self.follow_links == "True": 
     self.rules = (
      Rule(LinkExtractor(allow=()), callback="parse_pages", follow=True), 
     ) 
    else: 
     self.rules = (
      Rule(LinkExtractor(deny=(r'[a-zA-Z0-9]*')), callback="parse_pages", follow=False), 
     ) 

それが「本当」なら、すべてのリンクが許可されています。それが「偽」の場合、すべてのリンクは拒否されます。

これまでのところ、これらのルールは無視されています。私がルールを得ることができる唯一の方法は、コンストラクタの外側でそれらを定義することです。ことは、このような何かが正常に動作します:

class ExampleSpider(CrawlSpider): 

    rules = (
     Rule(LinkExtractor(deny=(r'[a-zA-Z0-9]*')), callback="parse_pages", follow=False), 
    ) 

    def __init__(self, *args, **kwargs): 
     ... 

だから、基本的には、__init__コンストラクタ内のルールを定義することは予想通り、コンストラクタは、作品の外のルールを定義するのに対し、ルールは無視されます。

私はこれを理解できません。私のコードは以下の通りです。

import re 
import scrapy 

from scrapy.linkextractors import LinkExtractor 
from scrapy.spiders import CrawlSpider, Rule 
from w3lib.html import remove_tags, remove_comments, replace_escape_chars, replace_entities, remove_tags_with_content 


class ExampleSpider(CrawlSpider): 

    name = "example" 
    allowed_domains = ['example.com'] 
    start_urls = ['http://www.example.com']  
    # if the rule below is uncommented, it works as expected (i.e. follow links and call parse_pages) 
    # rules = (
    #  Rule(LinkExtractor(allow=()), callback="parse_pages", follow=True), 
    #) 

    def __init__(self, *args, **kwargs): 

     super(ExampleSpider, self).__init__(*args, **kwargs) 

     # single page or follow links 
     self.follow_links = kwargs.get('follow_links') 
     if self.follow_links == "True": 
      # the rule below will always be ignored (why?!) 
      self.rules = (
       Rule(LinkExtractor(allow=()), callback="parse_pages", follow=True), 
      ) 
     else: 
      # the rule below will always be ignored (why?!) 
      self.rules = (
       Rule(LinkExtractor(deny=(r'[a-zA-Z0-9]*')), callback="parse_pages", follow=False), 
      ) 


    def parse_pages(self, response): 
     print("In parse_pages") 
     print(response.xpath('/html/body').extract()) 
     return None 


    def parse_start_url(self, response): 
     print("In parse_start_url") 
     print(response.xpath('/html/body').extract()) 
     return None 

この問題について私が手伝ってくれてどうもありがとう。

+2

あなたは 'スーパー(ExampleSpider、呼び出す前に、あなたのルールを設定してみてくださいすることができます...' – eLRuLL

+1

@eLRuLL、あなたは答えとしてこれを投稿する必要があります –

答えて

4

CrawlSpiderコンストラクター(__init__)もrulesパラメーターを処理しているため、これらのパラメーターを割り当てる必要がある場合は、既定のコンストラクターを呼び出す前に行う必要があります。言い換えれば

あなたがsuper(ExampleSpider, self).__init__(*args, **kwargs)を呼び出す前に必要なものがすべてです:?は

def __init__(self, *args, **kwargs): 
    # setting my own rules 
    super(ExampleSpider, self).__init__(*args, **kwargs) 
+0

これは正確です。super()を呼び出す前にルール、start_urls、allowed_domainsを設定する必要があります。 –

関連する問題