craw母模板爬虫

在我们前面的几个章节中介绍了爬取单页数据、数据的存储、分页抓取数据,如果对于一个网址的数据可以是全部可以爬取到的,本章节介绍另外一种方式爬取整站的数据,本章项目依然以伯乐在线文章抓取为案例

一、关于CrawlSpider的介绍

前面我们介绍的Spider是我们需要先分析一个url然后发送请求,请求回来我们在对数据的提起。有时候我们想要这样做,只要满足某个条件的url,都给我进行爬取。那么这时候我们就可以通过CrawlSpider来帮我们完成了。CrawlSpider继承自Spider,只不过是在之前的基础之上增加了新的功能,可以定义爬取的url的规则,以后scrapy碰到满足条件的url都进行爬取,而不用手动的yield Request

可以简单理解CrawlSpider是高级的Spider爬虫

二、创建一个CrawlSpider模板的爬虫

  • 1、创建一个项目

    scrapy statrproject blog_page1
    
  • 2、创建CrawlSpider模板的爬虫

    scrapy genspider -t crawl blog 'blog.jobbole.com/all-posts'
    # 之前创建普通爬虫的命令
    # scrapy genspider 爬虫名称 域名
    
  • 3、创建出来的Spider模板初始化

    import scrapy
    from scrapy.linkextractors import LinkExtractor
    from scrapy.spiders import CrawlSpider, Rule
    
    class BlogSpider(CrawlSpider):
        name = 'blog'
        allowed_domains = ['blog.jobbole.com/all-posts']
        start_urls = ['http://blog.jobbole.com/all-posts/']
    
        rules = (
            Rule(LinkExtractor(allow=r'Items/'), callback='parse_item', follow=True),
        )
    
        def parse_item(self, response):
            i = {}
            #i['domain_id'] = response.xpath('//input[@id="sid"]/@value').extract()
            #i['name'] = response.xpath('//div[@id="name"]').extract()
            #i['description'] = response.xpath('//div[@id="description"]').extract()
            return i
    

三、LinkExtractor链接提取器

使用LinkExtractor可以不用程序员自己提取想要的url,然后发送请求。这些工作都可以交给LinkExtractor,他会在所有爬的页面中找到满足规则的url,实现自动的爬取。以下对LinkExtractor类做一个简单的介绍:

  • 1、关于LinkExtractor的源码

    class LxmlLinkExtractor(FilteringLinkExtractor):
    
        def __init__(self, allow=(), deny=(), allow_domains=(), deny_domains=(), restrict_xpaths=(),
                     tags=('a', 'area'), attrs=('href',), canonicalize=False,
                     unique=True, process_value=None, deny_extensions=None, restrict_css=(),
                     strip=True):
    
  • 2、主要参数的介绍

    • allow: 允许的url。所有满足这个正则表达式的url都会被提取。
    • deny: 禁止的url。所有满足这个正则表达式的url都不会被提取。
    • allow_domains: 允许的域名。只有在这个里面指定的域名的url才会被提取。
    • deny_domains: 禁止的域名。所有在这个里面指定的域名的url都不会被提取。
    • restrict_xpaths: 严格的xpath。和allow共同过滤链接。

四、Rule的介绍

  • 1、源码文件

    class Rule(object):
    
        def __init__(self, link_extractor, callback=None, cb_kwargs=None, follow=None, process_links=None, process_request=identity):
            pass
    
  • 2、主要参数介绍

    • link_extractor: 一个LinkExtractor对象,用于定义爬取规则。
    • callback: 满足这个规则的url,应该要执行哪个回调函数。因为CrawlSpider使用了parse作为回调函数,因此不要覆盖parse作为回调函数自己的回调函数。
    • follow: 指定根据该规则从response中提取的链接是否需要跟进。
    • process_links: 从link_extractor中获取到链接后会传递给这个函数,用来过滤不需要爬取的链接。

五、使用CrawlSpider爬取伯乐在线标题

  • 1、Spider代码

    import scrapy
    from scrapy.linkextractors import LinkExtractor
    from scrapy.spiders import CrawlSpider, Rule
    
    from blog_page1.items import BlogPage1Item
    
    class BlogSpider(CrawlSpider):
        name = 'blog'
        allowed_domains = ['blog.jobbole.com']
        start_urls = ['http://blog.jobbole.com/all-posts/']
    
        rules = (
            # 定义列表页面规则
            Rule(LinkExtractor(allow=r'.*?/page/\d+'), follow=True),
            # 定义详情页面规则
            Rule(LinkExtractor(allow=r'http://blog.jobbole.com/\d+'), callback='parse_item', follow=True),
        )
    
        def parse_item(self, response):
            title = response.xpath('//div[@class="entry-header"]/h1/text()').extract_first()
            print('当前访问的标题===>', title)
            yield BlogPage1Item(title=title)
    
  • 2、定义pipelines存储数据

    from scrapy.exporters import JsonLinesItemExporter
    
    class BlogPage1Pipeline(object):
        def __init__(self):
            self.file = open('blog.json', 'wb')
            self.exporter = JsonLinesItemExporter(self.file, ensure_ascii=False, encoding='utf8')
    
        def process_item(self, item, spider):
            self.exporter.export_item(item)
            return item
    
        def close_spider(self, spider):
            self.file.close()
    

results matching ""

    No results matching ""