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()

 

 

 

  

 

posted @ 2019-09-17 08:50  tulintao  阅读(407)  评论(0编辑  收藏  举报