【Python_Scrapy学习笔记(八)】基于Scrapy框架实现多级页面数据抓取

news2024/11/22 20:12:58

基于Scrapy框架实现多级页面数据抓取

前言

本文中介绍 如何基于 Scrapy 框架实现多级页面数据的抓取,并以抓取汽车之家二手车数据为例进行讲解。

正文

在介绍如何基于 Scrapy 框架实现多级页面数据的抓取之前,先介绍下 Scrapy 框架的请求对象 request 和响应对象 response。

1、请求对象request属性及方法

  1. request.url:请求的 url 地址
  2. request.headers:请求头-字典格式
  3. request.meta:解析函数间 item 数据传递,定义代理
  4. request.cookies:Cookie 参数

2、响应对象response属性及方法

  1. response.url:返回实际数据的 url 地址
  2. response.text:响应内容-字符串格式
  3. response.body:响应内容-字符串格式
  4. response.encoding:响应字符编码
  5. response.status:HTTP响应码

3、请求对象request的meta参数

meta 参数:在不同的解析函数之间传递数据。
在执行 scrapy.Request() 方法时把一些回调函数中需要的数据传进去,meta 必须是一个字典,在下一个函数中可以使用 response.meta 进行访问,meta 会随着 response 响应对象一起回来,作为response 的一个属性。
注意:meta 传递的数据是浅拷贝传递的,如果传递的数据是可变的数据类型,那么很容易造成数据不对应的错误。
利用 mata 参数在不同的解析函数间传递数据:如有需要继续交给调度器的请求,则创建新的 item 对象。

4、基于Scrapy框架实现多级页面数据抓取

多级页面抓取的注意事项:

  1. 多级页面,数据不能直接提交给管道;
  2. 通过 meta 参数传递的数据是浅拷贝传递的,如果传递的数据是可变的数据类型,那么很容易造成数据不对应的错误;
  3. 针对 meta 参数传递数据不对应的的解决方法:传递多个参数。

案例详情:
这里参考 【Python_Scrapy学习笔记(六)】Scrapy框架基本使用流程 里的案例,并在此案例基础之上升级。

  1. 需求梳理:二级页面要爬取表显里程、上牌时间、排量
    在这里插入图片描述

  2. 整体思路:梳理要改写的 py 文件

    1. items.py:定义所有要抓取的数据结构
    2. car.py:将详情页链接继续交给调度器队列
    3. pipelines.py:处理全部汽车信息的item对象
  3. item.py:定义所有要抓取的数据结构,增加要爬取的三个字段

    import scrapy
    
    
    class CarspiderItem(scrapy.Item):
        # define the fields for your item here like:
        # name = scrapy.Field()
        # 汽车的名称、价格、和详情页链接,相当于定义了一个字典,只赋值了key,未赋值value
        name = scrapy.Field()
        price = scrapy.Field()
        link = scrapy.Field()
        # 表显里程、上牌时间、排量
        time = scrapy.Field()
        km = scrapy.Field()
        displacement = scrapy.Field()
    
  4. car.py:将详情页链接继续交给调度器队列,通过 meta 参数传递数据

    import scrapy
    from ..items import CarspiderItem
    
    
    class CarSpider(scrapy.Spider):
        name = "car"
        allowed_domains = ["www.che168.com"]
    
        # i = 1
    
        # 1、删除掉 start_urls 变量
        # start_urls = ["https://www.che168.com/china/a0_0msdgscncgpi1ltocsp1exx0/"]  # 从第一页开始
    
        def start_requests(self):
            """
            2、重写 start_requests() 方法:一次性生成所有要抓取的url地址,并一次性交给调度器入队列
            :return:
            """
    
            for i in range(1, 3):
                url = "https://www.che168.com/china/a0_0msdgscncgpi1ltocsp{}exx0/".format(i)
                # 交给调度器入队列,并指定解析函数
                yield scrapy.Request(url=url, callback=self.parse)
    
        def parse(self, response):
            item = {}
            # 先写基准xpath //body/div/div/ul/li
            li_list = response.xpath("//body/div/div/ul[@class='viewlist_ul']/li")
            for li in li_list:
                item["name"] = li.xpath("./@carname").get()
                item["price"] = li.xpath("./@price").get()
                if li.xpath("./a/@href").get().find('/dealer') == 0:
                    item["link"] = "https://www.che168.com" + li.xpath("./a/@href").get()
                else:
                    item["link"] = "https://" + li.xpath("./a/@href").get()[2:]
                # 此时把每个详情页的链接交给调度器入队列
                
                yield scrapy.Request(url=item["link"], meta={'k1': item['name'], 'k2': item['price'], 'k3': item['link']},
                                     callback=self.get_car_info)
                # meta传递的数据是浅拷贝传递的,如果传递的数据是可变的数据类型,那么很容易造成数据不对应的错误。
                # 当scrapy用请求对象发送请求并将返回结果给下一个解析方法后,接收到的meta里的数据是可以被操作修改的,所以item是会被for循环不断的修改,从而接收到的数据是被修改过后的数据。
                # 利用mata参数在不同的解析函数间传递数据:如有需要继续交给调度器的请求,则创建新的item对象
                # 解决方法:传递多个参数
                # 多级页面,不能直接提交给管道
    
        def get_car_info(self, response):
            """
            function:  提取二级页面的数据
                  in:
                 out:
              return:  int >0 ok, <0 some wrong
              others:
            """
            item = CarspiderItem()  # 给item.py的CarspiderItem类做实例化
            # meta会随着response响应对象一起回来,作为response的一个属性
            # item = response.meta["item"]
            item['name'] = response.meta['k1']
            item['price'] = response.meta['k2']
            item['link'] = response.meta['k3']
            item["time"] = response.xpath(".//div[@class='car-box']/ul/li[2]/h4/text()").get()
            item["km"] = response.xpath(".//div[@class='car-box']/ul/li[1]/h4/text()").get()
            item["displacement"] = response.xpath(".//div[@class='car-box']/ul/li[3]/h4/text()").get()
            yield item
    
    
  5. pipelines.py:处理全部汽车信息的item对象

    class CarspiderPipeline:
        def process_item(self, item, spider):
            print(item) # 这里只做打印处理
            return item
    
  6. 运行效果
    在这里插入图片描述

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

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

相关文章

Linux超级强大的十六进制dump工具:XXD命令,我教你应该如何使用!

在Linux操作系统中&#xff0c;XXD是一个十六进制dump工具&#xff0c;可以将二进制文件转换为十六进制表示&#xff0c;并以可读的形式显示。XXD命令可用于显示文件内容、编辑文件等用途。本文将介绍如何在Linux中使用XXD命令。 安装XXD命令 通常情况下&#xff0c;XXD命令已…

Java面试题总结 | Java基础部分2(持续更新)

文章目录反射的优缺点BIO、AIO、NIO同步异步概念**阻塞与非阻塞****BIO****NIO****AIO**总结设计模式的好处设计模式一定是好用的吗Integer.ValueOf和new Integer的区别Integer.parseInt(s)与Integer.valueOf(s)的区别String是线程安全的吗&#xff1f;StringBuffer和StringBui…

开源GPT-4小羊驼(Vicuna)快速上手指南

小羊驼&#xff08;Vicuna)是什么 Vicuna: 一个开源的GPT&#xff0c;宣称实现了GPT-4 90%的功能。 UC伯克利学者联手CMU、斯坦福等&#xff0c;再次推出一个全新模型70亿/130亿参数的Vicuna&#xff0c;俗称「小羊驼」&#xff08;骆马&#xff09;。 并且和其他以往不同的是…

数据库管理-第六十五期 Oracle 23c新特性(20230411)

数据库管理 2023-04-11第六十五期 Oracle 23c新特性1 免费版23c目录结构2 新特性总结第六十五期 Oracle 23c新特性 上一期装了免费版23c&#xff0c;这一期根据安装的数据库&#xff0c;对Oracle 23c的部分新特性进行实验展示。 1 免费版23c目录结构 通过RPM包安装的免费版2…

静态时序分析Static Timing Analysis1——STA概述、标准工艺库、时钟、IO约束的建立

文章目录前言一、静态时序分析概述1、时序路径分类2、STA和动态仿真比较3、PVT4、不同时钟域5、建立时间、保持时间6、恢复时间、移除时间二、标准工艺库1、标准单元延时模型2、slew derate三、STA约束的建立1、时钟约束1.1 时钟定义1.2 时钟不确定性1.3 时钟延时1.4 生成时钟2…

2023年4月的编程语言排行榜,有你中意的开发语言吗?

编程世界变幻莫测&#xff0c;编程语言也是层出不穷&#xff0c;每隔一段时间就有新的风口出现。2023年的风口非人工智能莫属&#xff0c;人工智能领域中不可获取的编程语言就是Python&#xff0c;作为在算法、数据方面有独特优势的编程语言&#xff0c;从去年开始就展现了它不…

Linux03——文件系统及结构、命令

目录 一、前言 二、文件目录 三、文件系统 四、文件目录命令 五、系统信息命令 六、通讯网络命令 七、磁盘类命令 八、进程管理命令 一、前言 Linux特点是开放性遵循OSI国际标准&#xff1b;多用户每个用户有各自权限&#xff1b;多任务&#xff1b;GUI和系统调用界面&…

Java每日一练(20230411)

目录 1. 同构字符串 &#x1f31f; 2. 随机字符串 &#x1f31f; 3. 交错字符串 &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 1. 同构字符串 给定两个…

京东技术专家首推:Spring微服务架构设计,GitHub星标128K

前言 本书提供了实现大型响应式微服务的实用方法和指导原则&#xff0c;并通过示例全面 讲解如何构建微服务。本书深入介绍了Spring Boot、Spring Cloud、 Docker、Mesos和Marathon&#xff0c;还会教授如何用Spring Boot部署自治服务&#xff0c;而 无须使用重量级应用服务器…

SAP开发环境ABAP的搭建(客户端和服务器),Developer Key和AccessKey的绕过方法

目录 一.前言 二.客户端GUI安装 1.下载好SAP GUI 750 2.解压后找到SAPGUISetup.exe 3.安装 4.安装完整教程 三.服务端搭建 1.安装VmWare虚拟机 2.下载虚拟机镜像 3.打开虚拟机 4.调整内存大小 5.启动虚拟机 四.创建程序 1.创建包 2.创建程序 3.Developer Key和A…

C语言——变参函数

一、定义 一般函数的参数列表是固定的&#xff0c;所以在调用时传入的实参的个数和格式必须和实参匹配&#xff1b;在函数式中&#xff0c;不需要关心实参&#xff0c;直接调用形参即可。 变参函数&#xff0c;就是参数的个数及类型都不确定的函数&#xff0c;常见变参函数如pr…

jenkins的slave节点构建java失败

背景&#xff1a; 主节点构建没问题的&#xff0c;为了缓解压力增加了个从节点&#xff0c;但是发现同个应用分配到从节点构建时报错&#xff0c;主节点构建就正常。但是我的从节点是把主节点克隆过去的&#xff0c; 理论环境配置java——maven啥都是一模一样才是。不理解。 …

Markdown基础语法:快速入门指南

什么是Markdown Markdown是一种轻量级的标记语言&#xff0c;它的目标是让文本内容更加易读、易写和易于转换成HTML等格式。Markdown语法简单、直观&#xff0c;适合用于写作、博客、笔记、文档等场景。Markdown最初由John Gruber和Aaron Swartz于2004年创建&#xff0c;现在已…

从手动实现web开发到借助IDEA实现web开发的具体流程分析,详细介绍webapp的目录结构和web站点的欢迎页面的设置

使用Tomcat手动实现WEB开发 实现静态的web应用(没有java小程序) 第一步&#xff1a;找到CATALINA_HOME\webapps目录(Tomcat服务器要求所有的web应用都要放到webapps目录下, 这样它才能找到你的web应用) 第二步&#xff1a;在CATALINA_HOME\webapps目录下新建一个oa的子目录(…

闭环控制里的采样周期和执行周期

运动控制对系统的实时性要求都非常高。所以大家可以看到运动控制总线的刷新周期越来越快,越来越短。今天我们讨论下实时性不高的总线会带来哪些问题和挑战,以及这种大延时总线如何解决实时性问题,运动控制实时性问题还可以参看下面的文章博客: 随动控制之跟随给定和跟随反…

Python一行命令搭建HTTP服务器并外网访问【内网穿透】

文章目录1.前言2.本地http服务器搭建2.1.Python的安装和设置2.2.Python服务器设置和测试3.cpolar的安装和注册3.1 Cpolar云端设置3.2 Cpolar本地设置4.公网访问测试5.结语转载自远程内网穿透的文章&#xff1a;【Python】快速简单搭建HTTP服务器并公网访问「cpolar内网穿透」 1…

20从零开始学Java之牛闪闪的for循环是怎么用的?

作者&#xff1a;孙玉昌&#xff0c;昵称【一一哥】&#xff0c;另外【壹壹哥】也是我哦 千锋教育高级教研员、CSDN博客专家、万粉博主、阿里云专家博主、掘金优质作者 前言 在前面的文章中&#xff0c;壹哥给大家讲解了顺序结构、分支结构&#xff0c;接下来我们就来学习Java…

面试篇-Java输入输出三兄弟大比拼:IO、NIO、AIO对比分析

1、Java I/O发展史 Java IO&#xff08;Input/Output&#xff09;是Java语言中用于读写数据的API&#xff0c;它提供了一系列类和接口&#xff0c;用于读取和写入各种类型的数据。下面是Java IO发展史的简要介绍&#xff1a; JDK 1.0&#xff08;1996年&#…

Android进阶宝典—事件冲突的解决方法

相信伙伴们在日常的开发工作中&#xff0c;一定会遇到事件冲突的问题&#xff0c;e.g. 一个页面当手指滑动的时候&#xff0c;会翻到下一页&#xff1b;点击的时候&#xff0c;需要响应页面中的元素点击事件&#xff0c;这个时候如果没有处理滑动事件&#xff0c;可能遇到的问题…

c++的多态

目录 1、多态 1.1多态的构成条件 1.2多态的好处 2、虚函数 2.1虚函数重写 2.2虚函数的默认参数 2.3纯虚函数重写 2.4抽象类 2.5虚析构&#xff0c;纯虚析构重写 3、重载、覆盖(重写)、隐藏(重定义)的对比 ​编辑 多态是c面向对象三大特性之一 程序调用函数时&#…