zoukankan      html  css  js  c++  java
  • 增量式爬虫

     

    增量式爬虫

     

    需求: 定时 更新程序 以便爬取网站中最近更新的数据

     

    一、增量式爬虫

     
    • 概念: 通过爬虫程序检测某网站数据更新的情况,以便可以爬取到该网站更新出的新数据
    • 如何进行增量式的爬取工作:
      • 在发送请求之前判断 此 URL 是不是之前爬过
      • 在解析内容之后判断 这部分内容 之前是否爬过
      • 在写入 存储介质时 判断 内容是不是已经在介质中存在
     
    • 分析: 不难发现,其实增量式爬取的核心是 去重 ,至于说去重的操作在哪个步骤起作用,只能说各有利弊,在我看来, 前两种思路需要根据实际情况取一个(也可能都用)。
      • 第一种思路适合有不断新页面的出现,比如说小说的新章节,每天的最新新闻等等;
      • 第二种思路则适合页面内容会不断更新的网站。
      • 第三种思路是相当于最后一道防线。这样做可以最大程度上达到去重的目的。
     

    去重方法:

     
    • 思路: 通过已有的机制达到去重的目的 1、redis的 set集合。 2、python 的 set 集合
    • 我们选择 redis 的 set 集合, 以求最大效率。
    • 将爬取过程中产生的 URL 进行存储,存储在 redis 的 set 中,
      • 根据 Redis.sadd(key,value) 的返回结果判断此 URL 是否已爬取过,
      • 1 表示存在,则发起请求; 0 表示不存在,则不进行请求。
    • 对爬取到的 网页内容进行唯一标识的制定, 然后将该唯一标识存储在 redis 的 set 中,当下次爬取到网页数据内容的时候,在进行持久化存储之前, 首先判断一下该 数据的 唯一标识在 redis 的 set 中是否存在,再决定 是否执行入库操作。
     

    案例 一、

     

    需求:爬取4567tv网站中所有的 电影名 和 作者名

    In [ ]:
    - 说明 1 : 项目配置文件 settings.py :
        - 默认配置
    # 添加 UA
    USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36'
    # 是否遵循爬虫协议 , 不遵从
    ROBOTSTXT_OBEY = False
    # 开启 scrapy 默认管道 
    ITEM_PIPELINES = {
       'increment1_Pro.pipelines.Increment1ProPipeline': 300,
    }
    - 说明 2: items.py 文件 自己根据代码编写
    
     

    爬虫文件

    In [ ]:
    # -*- coding: utf-8 -*-
    import scrapy
    from scrapy.linkextractors import LinkExtractor
    from scrapy.spiders import CrawlSpider, Rule
    from redis import Redis
    from increment1_Pro.items import Increment1ProItem
    
    
    class MovieSpider(CrawlSpider):
        name = 'movie'
        # allowed_domains = ['www.xxx.com']
        start_urls = ['https://www.4567tv.tv/index.php/vod/show/class/%E6%81%90%E6%80%96/id/9.html']
    
        rules = (
            Rule(LinkExtractor(allow=r'/index.php/vod/show/class/%E6%81%90%E6%80%96/id/9/page/d+.html'), callback='parse_item', follow=True),
        )
        def parse_item(self, response):
            conn = Redis(host='127.0.0.1',port=6379)
    
            detail_url_list ='https://www.4567tv.tv' + response.xpath('//li[@class="col-md-6 col-sm-4 col-xs-3"]/div/a/@href')
    
            for url in detail_url_list:
                # ex 若 为 1 ,表示 为新数据
                ex = conn.sadd('movies_url',url)
                if ex == 1:
                    yield  scrapy.Request(url=url,callback=self.self.parse_detail)
                else:
                    print("此站<%s>无更新数据,暂无新数据可爬"%url)
    
        def parse_detail(self,response):
            item = Increment1ProItem()
            item['name'] = response.xpath('//div[@class="stui-content__detail"]/h1/text()').extract_first()
            item['actor'] = response.xpath('/html/body/div[1]/div/div/div/div[2]/p[3]/a/text()').extract_first()
    
            yield item
    
     

    管道文件:

    In [ ]:
    # -*- coding: utf-8 -*-
    from redis import Redis
    class Increment1ProPipeline(object):
        def open_spider(self,spider):
            self.conn=Redis(host='127.0.0.1',port=6379)
    
        def process_item(self, item, spider):
            # dic = {
            #     'name': item['name'],
            #     'actor': item['actor'],
            # }
            print('正在入库!')
            self.conn.lpush('movie_data',item)
            return item
    
     

    案例 二、

     

    需求:爬取糗事百科中的 段子内容 和 作者名。

     

    爬虫文件:

    In [ ]:
    # -*- coding: utf-8 -*-
    import scrapy
    from scrapy.linkextractors import LinkExtractor
    from scrapy.spiders import CrawlSpider, Rule
    from increment_data.items import IncrementDataItem
    from redis import Redis
    import hashlib
    
    class QiubaiSpider(CrawlSpider):
        name = 'qiubai'
        # allowed_domains = ['www.xx.com']
        start_urls = ['https://www.qiushibaike.com/text/']
    
        rules = (
            Rule(LinkExtractor(allow=r'/text/page/d+/'), callback='parse_item', follow=True),
        )
    
        def parse_item(self, response):
            div_list = response.xpath('//div[@class="article block untagged mb15 typs_hot"]')
            conn = Redis(host='127.0.0.1',port=6379)
            for div in div_list:
                item = IncrementDataItem()
                item['author'] = div.xpath('./div[1]/a[2]/h2/text() | ./div[1]/span[2]/h2/text()').extract_first()
                # item['content'] = response.xpath('./a[1]/div/span/text()').extract_first()
                item['content'] = div.xpath('.//div[@class="content"]/span/text()').extract()
                item['content'] = ''.join(item['content'])
                source = item['author'] + item['content']
    
                # 自定制 一种形式的 数据指纹, 是数据的唯一标识
                hashValue = hashlib.sha256(source.encode()).hexdigest()
    
                ex = conn.sadd("qiubai_hash",hashValue)
                if ex == 1:
                    yield item
                else:
                    print("此数据 已 爬")
                    
    
     

    管道文件:

    In [ ]:
    # -*- coding: utf-8 -*-
    from redis import Redis
    #####################  注意  ########################
    """
        在这里 向 redis 的列表中 lpush 字典时 ,则python  中 redis 的版本需要为 2.10.6,否则报错
            pip3 install redis==2.10.6
    """
    class IncrementDataPipeline(object):
        conn = Redis(host='127.0.0.1', port=6379)
        def process_item(self, item, spider):
            dic = {
                'author': item['author'],
                'content': item['content'],
            }
            self.conn.lpush('qiubai_data',dic)
            print('爬取到一条数据, 正在入库')
            return item
        
    
  • 相关阅读:
    虚拟化VMware之虚拟机备份(1)
    虚拟化VMware之虚拟机备份(1)
    柯塔娜大合唱,互联网安全观
    柯塔娜大合唱,互联网安全观
    如何在虚拟机上Centos系统安装Nginx服务
    给已验证登录的用户添加访问限制
    Python爬虫入门教程 23-100 石家庄链家租房数据抓取
    login_required装饰器(1)
    Oracle 18c 新特性:动态 Container Map 增强 Application Container 灵活性
    如果登录不成功,跳转到登录页面
  • 原文地址:https://www.cnblogs.com/shiwei1930/p/10932618.html
Copyright © 2011-2022 走看看