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