在Scrapy中结合蜘蛛

时间:2014-10-16 15:00:51

标签: scrapy

是否可以创建一个继承/使用两个基础蜘蛛功能的蜘蛛?

我正在尝试抓取各种网站,我注意到在很多情况下该网站提供了一个站点地图,但这只是指向类别/列表类型页面,而不是“真实”内容。因此,我不得不使用CrawlSpider(指向网站根目录),但这是非常低效的,因为它遍历包括大量垃圾在内的所有页面。

我想做的是这样的事情:

  1. 启动我的Spider,它是SitemapSpider的子类,并将每个响应传递给parse_items方法。
  2. 在parse_items中测试页面是否包含“真实”内容
  3. 如果确实如此,则处理它,如果没有将响应传递给 CrawlSpider(实际上是我的CrawlSpider的子类)来处理
  4. CrawlSpider然后在页面中查找链接,比如2级深度和 处理它们
  5. 这可能吗?我意识到我可以将CrawlSpider中的代码复制并粘贴到我的蜘蛛中,但这似乎是一个糟糕的设计

3 个答案:

答案 0 :(得分:1)

最后,我决定只扩展sitemap spider并从爬网蜘蛛中提取一些代码,因为它更简单,试图处理多个继承问题,所以基本上:

class MySpider(SitemapSpider):
   def __init__(self, **kw):
      super(MySpider, self).__init__(**kw)
      self.link_extractor = LxmlLinkExtractor()

   def parse(self, response):
      # perform item extraction etc
      ...
      links = self.link_extractor.extract_links(response)
      for link in links:
        yield Request(link.url, callback=self.parse) 

答案 1 :(得分:1)

from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import SitemapSpider, CrawlSpider, Rule

class MySpider(SitemapSpider, CrawlSpider):
    name = "myspider"
    rules = ( Rule(LinkExtractor(allow=('', )), callback='parse_item', follow=True), )
    sitemap_rules = [ ('/', 'parse_item'), ]
    sitemap_urls = ['http://www.example.com/sitemap.xml']
    start_urls = ['http://www.example.com']
    allowed_domains = ['example.com']

    def parse_item(self, response):
        # Do your stuff here
        ...
        # Return to CrawlSpider that will crawl them
        yield from self.parse(response)

这样,Scrapy将从站点地图中的网址开始,然后按照每个网址中的所有链接进行操作。

来源:Multiple inheritance in scrapy spiders

答案 2 :(得分:0)

您可以像往常一样继承,唯一需要注意的是基础蜘蛛通常会覆盖基本方法start_requestsparse。另一点需要指出的是,CrawlSpider会在每个通过_parse_response的响应中获得链接。