zoukankan      html  css  js  c++  java
  • scrapy-redis分布式爬取猫眼电影

    能够利用redis缓存数据库的优点去重来避免数据的大面积冗余

    1、首先就是要创建猫眼爬虫项目

    2、进入项目内部创建一个爬虫文件

    创建完文件之后就是要爬取的内容,我这边以爬取猫眼电影的title和link为例(这个完全看个人你可以先去写爬虫,然后再来写items文件)

    3、编写item文件

    class MaoyanTestItem(scrapy.Item):
        # define the fields for your item here like:
        # name = scrapy.Field()
        title = scrapy.Field()
        link = scrapy.Field()
        pass

    4、编写爬虫文件(确定自己要爬的内容,然后与items中的指定字段连接起来)

    import scrapy
    from fake_useragent import UserAgent
    from scrapy.selector import Selector
    from maoyan_test.items import MaoyanTestItem
    
    
    headers = {
        'user-agent': UserAgent(verify_ssl=False).chrome
    }
    
    
    class MovieSpiderSpider(scrapy.Spider):
        name = 'movie'
        allowed_domains = ['www.maoyan.com/board/4']
        start_urls = ['http://www.maoyan.com/board/4?offset=%s']
    
        def start_requests(self):
            for i in range(10):
                url = self.start_urls[0] % str((i*10))
                yield scrapy.Request(url, callback=self.parse, dont_filter=False, headers=headers)
    
        def parse(self, response):
            item = MaoyanTestItem()
            sel = Selector(response)
            movie_list = sel.xpath('//dl[@class="board-wrapper"]/dd')
            for movie in movie_list:
    
                title = movie.xpath('a/@title').extract_first()
                link = 'https://www.maoyan.com' + movie.xpath('a/@href').extract_first()
                item['title'] = title
                item['link'] = link
                yield item

    5、编写Pipline文件:--> 这里面主要是通过redis缓存数据库来对数据进行筛选,然后将数据主要保存到Mysql中

      首先配置settings文件

    # 这个是需要手动加上的,通过scrapy-redis自带的pipeline将item存入redis中
    ITEM_PIPELINES = {
        'maoyan_test.pipelines.MaoyanTestPipeline': 300,
        'scrapy_redis.pipelines.RedisPipeline': 400
    }
    # 启动redis自带的去重
    DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
    # 启用调度器
    SCHEDULER = "scrapy_redis.scheduler.Scheduler"
    # 是否在关闭spider的时候保存记录
    SCHEDULER_PERSIST = True
    # 使用优先级调度请求队列(默认使用)
    SCHEDULER_QUEUE_CLASS = 
     'scrapy_redis.queue.SpiderPriorityQueue'
    # 指定redis的地址和端口,有密码的需要加上密码
    REDIS_HOST = '127.0.0.1'
    REDIS_PORT = '6379'
    REDIS_PARAMS = {
        'password': '123456',
    }
    
    #SCHEDULER_QUEUE_KEY = '%(spider)s:requests'  # 调度器中请求存放在redis中的key
    #SCHEDULER_SERIALIZER = "scrapy_redis.picklecompat"  # 对保存到redis中的数据进行序列化,默认使用pickle
    
    #SCHEDULER_FLUSH_ON_START = False  # 是否在开始之前清空 调度器和去重记录,True=清空,False=不清空
    # SCHEDULER_IDLE_BEFORE_CLOSE = 10  # 去调度器中获取数据时,如果为空,最多等待时间(最后没数据,未获取到)。
    #SCHEDULER_DUPEFILTER_KEY = '%(spider)s:dupefilter'  # 去重规则,在redis中保存时对应的key  chouti:dupefilter
    #SCHEDULER_DUPEFILTER_CLASS = 'scrapy_redis.dupefilter.RFPDupeFilter'  # 去重规则对应处理的类
    #DUPEFILTER_DEBUG = False
    #上述的扩展类需要的
    MYEXT_ENABLED = True  # 开启扩展
    IDLE_NUMBER = 10  # 配置空闲持续时间单位为 10个 ,一个时间单位为5s
    
    #如果为True,则使用redis的'spop'进行操作。
    #因为本次请求每一次带上的都是时间戳,所以就用了lpush
    #如果需要避免起始网址列表出现重复,这个选项非常有用。开启此选项urls必须通过sadd添加,否则会出现类型错误。
    #REDIS_START_URLS_AS_SET = True

      之后就是要在pipeline文件中将真是的数据保存到MySQL中:

    import pymysql
    
    
    class MaoyanTestPipeline(object):
        comments = []
    
        def __init__(self):
            self.conn = pymysql.connect(
                host='localhost',
                user='root',
                passwd='123456',
                port=3306,
                db='spider',
                charset='utf8',
                autocommit=True
            )
            self.cursor = self.conn.cursor()
    
        def process_item(self, item, spider):
    
            self.comments.append([item['title'], item['link']])
            if len(self.comments) == 1:
                self.insert_to_sql(self.comments)
                self.comments.clear()
    
            return item
    
        def close_spider(self, spider):
            self.insert_to_sql(self.comments)
    
        def insert_to_sql(self, data):
            try:
                sql = 'insert into maoyan_movie (title, link) values (%s, %s);'
                print(data)
                self.cursor.executemany(sql, data[0])
            except:
                print('插入数据有误...')
                self.conn.rollback()

      

  • 相关阅读:
    vert.x笔记:6.vert.x集群化部署
    vert.x笔记:5.vert.x集成dubbo服务
    Wampserver 配置端口可访问服务
    git credential for windows 总是弹出的问题
    如何用B表的数据,更新A表的值
    WampServer部署https 服务的过程
    PHP 命名空间冲突解决方式
    Windows下 Docker 简单部署 Django应用
    C#实现后台格式化U盘的功能
    Winform 实现断点续传的思路及代码
  • 原文地址:https://www.cnblogs.com/tulintao/p/11531457.html
Copyright © 2011-2022 走看看