Scrapy CrawlSpider介绍和使用

news2025/1/11 9:04:02

 一、介绍CrawlSpider

   CrawlSpider其实是Spider的一个子类,除了继承到Spider的特性和功能外,还派生除了其自己独有的更加强大的特性和功能。其中最显著的功能就是”LinkExtractors链接提取器“。Spider是所有爬虫的基类,其设计原则只是为了爬取start_url列表中网页,而从爬取到的网页中提取出的url进行继续的爬取工作使用CrawlSpider更合适。

 源码:

class CrawlSpider(Spider):
    rules = ()
    def __init__(self, *a, **kw):
        super(CrawlSpider, self).__init__(*a, **kw)
        self._compile_rules()

    #首先调用parse()来处理start_urls中返回的response对象
    #parse()则将这些response对象传递给了_parse_response()函数处理,并设置回调函数为parse_start_url()
    #设置了跟进标志位True
    #parse将返回item和跟进了的Request对象    
    def parse(self, response):
        return self._parse_response(response, self.parse_start_url, cb_kwargs={}, follow=True)

    #处理start_url中返回的response,需要重写
    def parse_start_url(self, response):
        return []

    def process_results(self, response, results):
        return results

    #从response中抽取符合任一用户定义'规则'的链接,并构造成Resquest对象返回
    def _requests_to_follow(self, response):
        if not isinstance(response, HtmlResponse):
            return
        seen = set()
        #抽取之内的所有链接,只要通过任意一个'规则',即表示合法
        for n, rule in enumerate(self._rules):
            links = [l for l in rule.link_extractor.extract_links(response) if l not in seen]
            #使用用户指定的process_links处理每个连接
            if links and rule.process_links:
                links = rule.process_links(links)
            #将链接加入seen集合,为每个链接生成Request对象,并设置回调函数为_repsonse_downloaded()
            for link in links:
                seen.add(link)
                #构造Request对象,并将Rule规则中定义的回调函数作为这个Request对象的回调函数
                r = Request(url=link.url, callback=self._response_downloaded)
                r.meta.update(rule=n, link_text=link.text)
                #对每个Request调用process_request()函数。该函数默认为indentify,即不做任何处理,直接返回该Request.
                yield rule.process_request(r)

    #处理通过rule提取出的连接,并返回item以及request
    def _response_downloaded(self, response):
        rule = self._rules[response.meta['rule']]
        return self._parse_response(response, rule.callback, rule.cb_kwargs, rule.follow)

    #解析response对象,会用callback解析处理他,并返回request或Item对象
    def _parse_response(self, response, callback, cb_kwargs, follow=True):
        #首先判断是否设置了回调函数。(该回调函数可能是rule中的解析函数,也可能是 parse_start_url函数)
        #如果设置了回调函数(parse_start_url()),那么首先用parse_start_url()处理response对象,
        #然后再交给process_results处理。返回cb_res的一个列表
        if callback:
            #如果是parse调用的,则会解析成Request对象
            #如果是rule callback,则会解析成Item
            cb_res = callback(response, **cb_kwargs) or ()
            cb_res = self.process_results(response, cb_res)
            for requests_or_item in iterate_spider_output(cb_res):
                yield requests_or_item

        #如果需要跟进,那么使用定义的Rule规则提取并返回这些Request对象
        if follow and self._follow_links:
            #返回每个Request对象
            for request_or_item in self._requests_to_follow(response):
                yield request_or_item

    def _compile_rules(self):
        def get_method(method):
            if callable(method):
                return method
            elif isinstance(method, basestring):
                return getattr(self, method, None)

        self._rules = [copy.copy(r) for r in self.rules]
        for rule in self._rules:
            rule.callback = get_method(rule.callback)
            rule.process_links = get_method(rule.process_links)
            rule.process_request = get_method(rule.process_request)

    def set_crawler(self, crawler):
        super(CrawlSpider, self).set_crawler(crawler)
        self._follow_links = crawler.settings.getbool('CRAWLSPIDER_FOLLOW_LINKS', True)

文档:Spiders — Scrapy 2.9.0 documentation

二、框架搭建

1.创建scrapy框架工程
   scrapy startproject Meitou

2.进入工程目录
   cd Meitou

3.创建爬虫文件
    scrapy genspider -t crawl 爬虫任务名称 爬取的范围域 
    scrapy genspider -t crawl crawl_yjin xx.com
    此指令对比以前指令多了"-t crawl",表示创建的爬虫文件是基于CrawlSpider这个类的,而不再是Spider这个基类。

4.启动爬虫文件
    scrapy crawl crawl_yjin --nolog

(一)、查看生成的爬虫文件 :

 Rule(规则): 规范url构造请求对象的规则

 LinkExtractor(链接提取器):规范url的提取范围

 CrawlSpider:是一个类模板,继承自Spider,功能就更加的强大

(二)、查看LinkExtractor源码: 

  LinkExtractor 链接提取器

  作用:提取response中符合规则的链接。

 主要参数含义:

LinkExtractor:规范url提取可用的部分
allow=(): 满足括号中“正则表达式”的值会被提取,如果为空,则全部匹配。 
deny=(): 与这个正则表达式(或正则表达式列表)不匹配的URL一定不提取。
allow_domains=():允许的范围域
deny_domains=(): 不允许的范围域
restrict_xpaths=(): 使用xpath表达式,和allow共同作用过滤链接(只选到节点,不选到属性)
tags=('a', 'area'): 指定标签
attrs=('href',): 指定属性

 (三)、查看Rule源码: 

     Rule : 规则解析器。根据链接提取器中提取到的链接,根据指定规则提取解析器链接网页中的内容

     Rule (LinkExtractor(allow=r"Items/"), callback="parse_item", follow=True)

  主要参数含义:

  • - link_extractor为LinkExtractor,用于定义需要提取的链接
  • - callback参数:当link_extractor获取到链接时参数所指定的值作为回调函数
  • - callback参数使用注意:  当编写爬虫规则时,请避免使用parse作为回调函数。于CrawlSpider使用parse方法来实现其逻辑,如果您覆盖了parse方法,crawlspider将会运行失败
  • - follow:指定了根据该规则从response提取的链接是否需要跟进。 当callback为None,默认值为True
  • - process_links:主要用来过滤由link_extractor获取到的链接
  • - process_request:主要用来过滤在rule中提取到的request

 rules=( ):指定不同规则解析器。一个Rule对象表示一种提取规则。

(四)、CrawlSpider整体爬取流程:

 (a) 爬虫文件首先根据起始url,获取该url的网页内容

 (b) 链接提取器会根据指定提取规则将步骤a中网页内容中的链接进行提取

 (c) 规则解析器会根据指定解析规则将链接提取器中提取到的链接中的网页内容根据指定的规则进行解析

 (d) 将解析数据封装到item中,然后提交给管道进行持久化存储

 

三、基于CrawlSpider使用

(1)spider爬虫文件代码

import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule


class CrawlYjinSpider(CrawlSpider):
    name = "crawl_yjin"
    allowed_domains = ["xiachufang.com"]
    start_urls = ["https://www.xiachufang.com/category/40073/"]  # 起始url (分类列表的小吃)

    # 创建一个Rule对象(也创建一个LinkExtractor对象)
    rules = (

        # 菜单详情地址
        # https://www.xiachufang.com/recipe/106909278/
        # https://www.xiachufang.com/recipe/1055105/
        Rule(LinkExtractor(allow=r".*?/recipe/\d+/$"), callback="parse_item", follow=False),

    )

    # 解析菜单详情
    def parse_item(self, response):
        # 不需要手动构造item对象
        item = {}
        # print(response.url)
        # 图片链接,名称,评分,多少人做过,发布人
        item['imgs'] = response.xpath('//div/img/@src').get()
        #去除空格和\n
        item['title']=''.join(response.xpath('//div/h1/text()').get()).replace(' ','').replace('\n','')
        item['score']=response.xpath('//div[@class="score float-left"]/span[@class="number"]/text()').extract_first()
        item['number']=response.xpath('//div[@class="cooked float-left"]/span[@class="number"]/text()').get()
        item['author']=''.join(response.xpath('//div[@class="author"]/a/img/@alt').get()).replace('的厨房','')

        # print(item)

        return item

(2)数据保存>>pipelines管道文件

import json

from itemadapter import ItemAdapter


class MeitouPipeline:
    """处理items对象的数据"""
    def __init__(self):
        self.file_=open('xcf-1.json','w',encoding='utf-8')
        print('文件打开了。。。')

    def process_item(self, item, spider):
        """item接收爬虫器丢过来的items对象"""
        py_dict=dict(item) # 先把携带键值对数据items对象转成字典
        #dict转换成json数据
        json_data=json.dumps(py_dict,ensure_ascii=False)+",\n"
        #写入
        self.file_.write(json_data)
        print("写入数据...")
        return item


    def __del__(self):
        self.file_.close()  #关闭
        print('文件关闭了....')

(3) settings相关设置 >>settings.py设置文件

# 全局用户代理,默认是被注释了,不生效
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36'

# Obey robots.txt rules
ROBOTSTXT_OBEY = False

# 设置下载延时
DOWNLOAD_DELAY = 1

#开启管道
ITEM_PIPELINES = {
   "Meitou.pipelines.MeitouPipeline": 300,
}

(4)运行程序 >>scrapy crawl crawl_yjin  --nolog
   

   查看保存的json文件

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/567543.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Nodejs】Node-js概述

Node.js 文章目录 Node.js一、Node.js概述1.1、介绍1.2、官网1.3、Node.js应用场景1.4、安装Node.js1.5、npm包管理器1.5.1、介绍1.5.2、切换npm源1.5.3、生成JSON配置文件1.5.4、查看当前安装的树形模块1.5.5、安装模块1.5.6、自定义脚本命令1.5.7 、自动重启应用 1.6、模块化…

机房管理技能,医疗行业必备!

机房是一个很复杂的地方,存放设备数量大且杂,再加上大量使用电,机房存在各种各样的隐患,给机房管理带来极大的难度。 因此,想要很好的管理机房、避免机房出现各种危险,就需要应用机房动环监控系统&#xff…

MT8395(Genio 1200)处理器性能参数介绍

MT8395(Genio 1200)是一款专为AI与高性能物联网应用而设计的通用型SoC,采用6nm制程工艺,已集成四核A78和四核A55的八核CPU。Genio 1200还集成Mali-G57图形处理器,内置独立的双核AI处理器,可应用于智能家电、中控设备、商业显示、工…

如何在Windows 11更新后解决C盘已满的问题?

Windows 11比Windows 10需要占用C盘更多的空间,在升级到Windows 11后,如果升级后出现问题,安装程序可以帮你退回到Windows 10。无论怎样,在升级到Windows 11后,系统会自动制作以前的数据的副本,这会占用大量…

chatgpt赋能python:Pythonshowinfo:了解Python中弹出消息框的方法以及使用场景

Python showinfo: 了解Python中弹出消息框的方法以及使用场景 Python是一种著名的编程语言,用来编写各种应用程序和脚本。在Python中,弹出消息框是一种帮助开发人员和用户更好地交互的常见方法之一。showinfo是Python中的一个函数,它可以用来…

chatgpt赋能python:Python与SICP:重塑编程的未来

Python与SICP:重塑编程的未来 介绍 随着现代生活的发展,计算机在我们的生活中扮演越来越重要的角色。而Python语言则成为了众多开发者使用的首选语言。作为一门高级编程语言,Python在开发业界广受欢迎,并且得到了MIT计算机科学家…

成年人自学黑客,远比你想的更难......

什么是黑客 Hacker一词,最初曾指热心于计算机技术、水平高超的电脑高手,尤其是程序设计人员 黑客演变出哪些类型 白帽黑客 白帽黑客是指通过实施渗透测试,识别网络安全漏洞,为政府及组织工作并获得授权或认证的黑客。他们也确保…

1123 Is It a Complete AVL Tree (PAT甲级)

这道题是看了柳婼的解法才搞定的。开始想着把height和parent放到结构体中去&#xff0c;很繁琐最后还搞不定…… #include <cstdio> #include <algorithm> #include <vector>struct node{int key;node* left nullptr;node* right nullptr; };int N, t, pi…

【Netty】字节缓冲区 ByteBuf (六)(上)

文章目录 前言一、ByteBuf类二、ByteBuffer 实现原理2.1 ByteBuffer 写入模式2.2 ByteBuffer 读取模式2.3 ByteBuffer 写入模式切换为读取模式2.4 clear() 与 compact() 方法2.5 ByteBuffer 使用案例 总结 前言 回顾Netty系列文章&#xff1a; Netty 概述&#xff08;一&…

【2023 · CANN训练营第一季】昇腾AI入门课(TensorFlow)——第一章 昇腾AI基础知识介绍

一、昇腾AI全栈架构 异腾AI全栈可以分成四个大部分: 1.应用使能层面&#xff0c;此层面通常包含用于部署模型的软硬件&#xff0c;例如API、SDK、部署平 台&#xff0c;模型库等等。 2.AI框架层面&#xff0c;此层面包含用于构建模型的训练框架&#xff0c;例如华为的MindSpore…

Redis-数据结构

前言 ​ 了解Redis&#xff0c;都大概知道Redis有5种基本数据类型&#xff1a;字符串(string)、列表(list)、哈希(hash)、集合(set)、有序集合(zset)、5.0中Stream数据类型。但是这些数据类型的底层都是按照对象结构与对应的编码组合而成。这也就是说有的底层数据结构可以是多…

Python+Yolov5果树上的水果(苹果)检测识别

程序示例精选 PythonYolov5果树上的水果(苹果)检测识别 如需安装运行环境或远程调试&#xff0c;见文章底部个人QQ名片&#xff0c;由专业技术人员远程协助&#xff01; 前言 这篇博客针对<<PythonYolov5果树上的水果(苹果)检测识别>>编写代码&#xff0c;代码整洁…

Spring Data Mongo更新整个对象

第一步&#xff1a;在pom.xml文件中引入下述依赖&#xff0c;当前Spring Boot的版本为 2.7.6&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId><version>…

【产品人卫朋】华为IPD体系:IPD相关术语

目录 术语合集 课程 术语合集 BB&#xff1a;building block&#xff0c;组件 BG&#xff1a;business group&#xff0c;业务群 BLM&#xff1a;business leadership model&#xff0c;业务领先模型 BMT&#xff1a;business management team&#xff0c;业务管理团队 B…

这6个超实用的图片素材网站,高清、免费,赶紧马住

推荐6个超实用的图片素材网站&#xff0c;高清无水印&#xff0c;绝对值得收藏&#xff01; 1、菜鸟图库 https://www.sucai999.com/pic.html#?vNTYxMjky 网站主要是为新手设计师提供免费素材的&#xff0c;素材的质量都很高&#xff0c;类别也很多&#xff0c;像平面、UI、…

Restful接口开发与测试—接口测试

开发完接口&#xff0c;接下来我们需要对我们开发的接口进行测试。接口测试的方法比较多&#xff0c;使用接口工具或者Python来测试都可以&#xff0c;工具方面比如之前我们学习过的Postman或者Jmeter &#xff0c;Python脚本测试可以使用Requests unittest来测试。 测试思路…

数据结构中常见的树

二叉树&#xff1a;每个子节点只有两个节点的树&#xff0c;每个结点至多拥有两棵子树(即二叉树中不存在度大于2的结 点)&#xff0c;并且&#xff0c;二叉树的子树有左右之分&#xff0c;其次序不能任意颠倒 我们一般在解题过程中二叉树有两种主要的形式&#xff1a;满二叉树…

徐延涛:医疗健康企业如何重构客户管理的“营销”与“服务”?

随着人口老龄化和生活健康水平的提升&#xff0c;中国的医疗健康行业市场规模前景向好。《2023易凯资本中国健康产业白皮书》显示&#xff0c;从2022年到2030年的八年里&#xff0c;中国健康产业的整体规模将从10万亿元增长到接近20万亿&#xff0c;年复合增长率将达到9.5%-10%…

TS入门(TS类型有哪些?怎么使用?)

TS简介 TS&#xff08;TypeScript&#xff09;是一种由微软开发的开源编程语言&#xff0c;它是 JavaScript 的超集&#xff0c;能够为 JavaScript 添加静态类型检查和面向对象编程的特性。TS 可以在编译时进行类型检查&#xff0c;从而提高代码的可读性、可维护性和可靠性&am…

PMP课堂模拟题目及解析(第12期)

111. 客户拒绝了一项交付成果&#xff0c;因为它不符合约定的质量规格&#xff0c;项目团队调查该问题&#xff0c;并确定供应商提供的零件有问题&#xff0c;供应商拒绝纠正这种情况。项目经理应该审查什么&#xff1f; A. 与供应商订立的服务水平协议 B. 采购管理计划和合…