Scrapy框架(十)--增量式爬虫

增量式爬虫
- 概念:监测网站数据更新的情况,只会爬取网站最新更新出来的数据。
- 分析:
  - 指定一个起始url
  - 基于CrawlSpider获取其他页码链接
  - 基于Rule将其他页码链接进行请求
  - 从每一个页码对应的页面源码中解析出每一个电影详情页的URL

  - 核心:检测电影详情页的url之前有没有请求过,这里的示例使用了redis集合的去重特性,也可以使用python集合的去重特性。
  - 将爬取过的电影详情页的url存储
  - 存储到redis的set数据结构

  - 对详情页的url发起请求,然后解析出电影的名称和简介
  - 进行持久化存储

示例:爬取电影的名称和简介,只爬取之前没有爬取过的电影。

爬虫文件

# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from redis import Redis
from moviePro.items import MovieproItem

class MovieSpider(CrawlSpider):
    name = 'movie'
    # allowed_domains = ['www.xxx.com']
    start_urls = ['https://www.4567kan.com/frim/index1.html']

    rules = (
        Rule(LinkExtractor(allow=r'index1-d+.html'), callback='parse_item', follow=False),
    )

    conn = Redis(host='127.0.0.1',port=6379)
    def parse_item(self, response):
        li_list = response.xpath('/html/body/div[1]/div/div/div/div[2]/ul/li')
        for li in li_list:
            title = li.xpath('./div/div/h4/a/text()').extract_first()
            detail_url = 'https://www.4567kan.com/'+li.xpath('./div/div/h4/a/@href').extract_first()
            ex = self.conn.sadd('urls', detail_url)
            # 利用redis的集合类型 如果存在 返回0  不存在 返回1
            if ex == 1:
                print("爬取成功")
                yield scrapy.Request(url=detail_url,callback=self.parse_detail)
            else:
                print('暂无新资源')

    def parse_detail(self,response):
        item = MovieproItem()
        desc = response.xpath('/html/body/div[1]/div/div/div/div[2]/p[5]/span[2]/text()').extract_first()
        title = response.xpath('/html/body/div[1]/div/div/div/div[2]/h1/text()').extract_first()
        item['desc'] = desc
        item['title'] = title
        yield item

    def closed(self,response):
        self.conn.close()

items.py

import scrapy


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

pipelines.py

import json

class MovieproPipeline:
    def open_spider(self,spider):
        self.conn = spider.conn

    def process_item(self, item, spider):
        dic = {
            'title':item['title'],
            'desc': item['desc']
        }
        dic = json.dumps(dic)
        # 向redis中存放一个数据结构
        self.conn.lpush('movieDate',dic)
        return item
原文地址:https://www.cnblogs.com/sxy-blog/p/13216251.html