文章目录

  • 九、CrawlSpider⭐⭐⭐
    • 实战项目
    • 问题总结
  • 十、分布式爬虫
  • 十一、增量式爬虫
  • 总结

九、CrawlSpider⭐⭐⭐

是一个类,基于Spider的子类。
子类继承父类所有的功能,并能派生出自己的功能!

  • 用于全栈数据的爬取
  1. 基于Spider:手动请求
  2. 基于CrawlSpider
  • 使用流程
  1. 创建工程(同以前不变)
  2. cd XXX
  3. 创建爬虫文件(CrawlSpider):
  • scrapy genspider -t crawl xxx www.xxx.comscrapy genspider -t crawl sun www.xxx.com
  • 链接提取器:根据指定的规则(allow)进行指定的提取
  • 规则解析器:将链接提取器的链接进行指定规则(callback)的解析操作

实战项目

  • 需求

爬取sun网站网站中的编号、新闻标题、新闻内容、编号

  • 分析

爬取的数据没有在同一张页面中

  • 流程
  1. 可以使用链接提取器提取所有的页码链接
  2. 让链接提取器提取所有的新闻详情页
  • 源码解析
  1. sun.py
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rulefrom sunPro.items import SunproItem,DetailItem# 需求:爬取sun网站网站中的编号、新闻标题、新闻内容、编号
class SunSpider(CrawlSpider):name = 'sun'# allowed_domains = ['www.xxx.com']start_urls = ['https://wzzdg.sun0769.com/political/index/politicsNewest?id=1&page=1']# 链接提取器:根据指定规则(allow="正则")进行指定链接的提取link = LinkExtractor(allow=r'id=1&page=\d+')link_detail = LinkExtractor(allow=r'index\?id=\d+')rules = (# 规则解析器:将链接提取器的链接进行指定规则(callback)的解析操作# 提取链接的个数和回调的次数是相同的Rule(link, callback='parse_item', follow=True),Rule(link_detail, callback='parse_detail'),# follow=True:可以将链接提取器 继续作用到链接提取器提取到的链接 所对应的页面中# follow=True:对全栈链接的提取)# https://wzzdg.sun0769.com/political/politics/index?id=526663 # https://wzzdg.sun0769.com/political/politics/index?id=526662# 如下两个方法中不可以实现请求传参,因为就没有使用scrapy.Request()   ⭐行星# 无法将两个解析方法解析的数据存储到一个item中,因此存储到两个# 解析新闻编号和标题def parse_item(self, response):# xpaht表达式中不可以出现tbody标签li_list = response.xpath('/html/body/div[2]/div[3]/ul[2]/li')for li in li_list:# 新闻编号、新闻标题获取new_num = li.xpath('./span[1]/text()').extract_first()new_title = li.xpath('./span[@class="state3"]/a/text()').extract_first()# print('new_num:',new_num,'new_num_title:',new_title)item = SunproItem()item['title'] = new_titleitem['new_num'] = new_numyield item# 解析详情页新闻内容、编号def parse_detail(self,response):new_id = response.xpath('/html/body/div[3]/div[2]/div[2]/div[1]/span[4]/text()').extract_first()new_content = response.xpath('/html/body/div[3]/div[2]/div[2]/div[2]/pre/text()').extract_first()# print('new_id:',new_id,'new_content:',new_content)item = DetailItem()item['new_id'] = new_iditem['new_content'] = new_contentyield item
  1. items.py

sun.py文件中的两个方法【parse_item,parse_detail】中不可以实现请求传参,因为就没有使用scrapy.Request() ⭐⭐

  • 无法将两个解析方法解析的数据存储到一个item中,因此存储到两个
class SunproItem(scrapy.Item):# define the fields for your item here like:title = scrapy.Field()new_num = scrapy.Field()class DetailItem(scrapy.Item):# define the fields for your item here like:new_id = scrapy.Field()new_content = scrapy.Field()
  1. pipelines.py

将数据写入数据库时,如何保证新闻的一致性
通过new_id与new_num 两个数值是一样的

class SunproPipeline:# 一定要区分不同的item# 如何判定item类型def process_item(self, item, spider):if item.__class__.__name__ == 'DetailItem':⭐⭐print(item['new_id'],item['new_content'])else:print(item['new_num'],item['title'])return item
  1. 最后修改settings.py文件

问题总结

  1. CrawlSpider爬图片的时候遇到了不完整url⭐⭐
  2. re正则的使用

在线正则表达式测试工具


十、分布式爬虫

  • 概念

我们需要搭建一个分布式的集群,让其对一组资源进行分布联合爬取

  • 作用

提升爬取数据的效率

  • 如何实现分布式?

安装一个scrapy-redis的组件

原生的scrapy是不可以实现分布式爬虫,必须让scrapy结合着scrapy-redis组件一起实习那分布式爬虫

  • 为什么原生的scrapy不可以实现分布式?
  1. 调度器不可以被分布式集群共享
  2. 管道不可以被分布式集群共享
  • scrapy-redis组件作用:

可以给原生的scrapy框架提供可以被共享的管道和调度器

  • 实现流程⭐⭐
  1. 创建一个工程【同以往一样】
  2. 创建一个基于CrawlSpider的爬虫文件
  • scrapy startproject fbsPro
  • cd .\fbsPro\
  • scrapy genspider -t crawl fbs www.xxx.com
  1. 修改当前的爬虫文件:
  • 导包:from scrapy_redis.spiders import RedisCrawlSpider
  • 注释:start_urls和allowed_domains
  • 添加新属性:redis_key = 'xxxx'可以被共享的调度器队列的名称
  • 编写数据解析相关的操作
  • 将当前爬虫类的父类改为RedisCrawlSpider
  1. 修改配置文件settings.py
  • 指定使用可以被共享的管道
    ITEM_PIPELINES = {
    ‘scrapy_redis.pipelines.RedisPipeline’: 400,
    }
  • 指定调度器
    SCHEDULER ="scrapy_redis.scheduler.Scheduler"
    SCHEDULER_PERSIST = True
    DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
  • 指定redis服务器
    REDIS_HOST = 'redis服务中的ip地址'# 不指定则默认本地
    REDIS_PORT = 6379
  • redis相关操作配置
  1. 配置redis的配置文件:
  • Linux或者Mac:redis.conf
  • Windows:redis.windows.conf
  • 打开配置文件修改:
    • 将bind 127.0.0.1进行删除
    • 关闭保护模式 :protected-mode yes改为protected-mode no
  1. 结合着配置文件开启redis服务: redis-server 配置文件
  2. 启动客户端 :redis-cli




  • 执行工程
  • scrapy runspider xxx.py
  • 向调度器的队列中放入起使url
  • 调度器的队列在redis的客户端中
    • lpush xxx www.xxx.com

  • 查看数据

  • 爬取到的数据存储在了redis的ProName:items这个数据结构中

十一、增量式爬虫

三类:

  1. 通用爬虫
  2. 聚焦爬虫
  3. 增量式爬虫
  • 概念

检测网站数据更新的情况,只会爬取网站最新更新出来的数据。

  • 需求

获得该网页的名称和简介

  • 分析
  1. 指定一个起使的url
  2. 基于CrawlSpider获取其他页码链接
  3. 基于Rule将其他页码链接进行请求
  4. 从每一个页码对应的页面源码中解析出每一个电影详情页的url