代码之家  ›  专栏  ›  技术社区  ›  Christian Davén

在多个网站上使用一个刮擦蜘蛛

  •  12
  • Christian Davén  · 技术社区  · 16 年前

    我需要创建一个用户可配置的webspider/crawler,我正在考虑使用Scrapy。但是,我不能硬编码域和允许的URL regex:es——而是可以在GUI中配置。

    如何(尽可能简单)创建一个spider或一组spider,其中域和允许的URL regex:es是动态配置的?例如,我将配置写入一个文件,然后蜘蛛以某种方式读取它。

    4 回复  |  直到 16 年前
        1
  •  10
  •   dangra    14 年前

    警告:这个答案是针对ScrapyV0.7的,SpiderManagerAPI从那时起发生了很大的变化。

    重写默认的SpiderManager类,从数据库或其他地方加载自定义规则,并用自己的规则/正则表达式和域名实例化自定义spider

    在mybot/settings.py中:

    SPIDER_MANAGER_CLASS = 'mybot.spidermanager.MySpiderManager'
    

    在mybot/spidermanager.py中:

    from mybot.spider import MyParametrizedSpider
    
    class MySpiderManager(object):
        loaded = True
    
        def fromdomain(self, name):
            start_urls, extra_domain_names, regexes = self._get_spider_info(name)
            return MyParametrizedSpider(name, start_urls, extra_domain_names, regexes)
    
        def close_spider(self, spider):
            # Put here code you want to run before spiders is closed
            pass
    
        def _get_spider_info(self, name):
            # query your backend (maybe a sqldb) using `name` as primary key, 
            # and return start_urls, extra_domains and regexes
            ...
            return (start_urls, extra_domains, regexes)
    

    现在,在mybot/spider.py中定制spider类:

    from scrapy.spider import BaseSpider
    
    class MyParametrizedSpider(BaseSpider):
    
        def __init__(self, name, start_urls, extra_domain_names, regexes):
            self.domain_name = name
            self.start_urls = start_urls
            self.extra_domain_names = extra_domain_names
            self.regexes = regexes
    
         def parse(self, response):
             ...
    

    • 如果您想利用CrawlSpider的规则系统,也可以扩展CrawlSpider
    • 要运行爬行器,请使用: ./scrapy-ctl.py crawl <name> name 传递给SpiderManager.fromdomain,是从后端系统检索更多spider信息的密钥
    • TwistedPluginSpiderManager
        2
  •  4
  •   Alex Martelli    16 年前

    您需要的是动态创建spider类,将您最喜欢的泛型spider类子类化为 scrapy ( CrawlSpider 子类与你的 rules XmlFeedSpider ,或其他)并添加 domain_name , start_urls ,还有可能 extra_domain_names start_requests() 等),从GUI(或配置文件或其他任何文件)获取或推断它们。

    from scrapy import spider
    
    def makespider(domain_name, start_urls,
                   basecls=spider.BaseSpider):
      return type(domain_name + 'Spider',
                  (basecls,),
                  {'domain_name': domain_name,
                   'start_urls': start_urls})
    
    allspiders = []
    for domain, urls in listofdomainurlpairs:
      allspiders.append(makespider(domain, urls))
    

    这提供了一个非常简单的spider类的列表——您可能需要添加 parse 方法,然后再实例化它们。调味…;-)。

        3
  •  3
  •   alecxe    13 年前

    domo ! 您需要为您的项目实例化示例中给出的爬虫程序。

        4
  •  0
  •   eLRuLL    9 年前

    现在,为这些目的配置scrapy非常容易:

    1. 关于要访问的第一个url,您可以将其作为spider调用的属性传递给 -a start_requests 函数设置如何启动卡盘

    2. 您不需要设置 allowed_domains

    结果应该是:

    class MySpider(Spider):
    
        name = "myspider"
    
        def start_requests(self):
            yield Request(self.start_url, callback=self.parse)
    
    
        def parse(self, response):
            ...
    

    你应该称之为:

    scrapy crawl myspider -a start_url="http://example.com"