【Python从入门到进阶】49、当当网Scrapy项目实战(二)

news2025/1/11 7:37:04

接上篇《48、当当网Scrapy项目实战(一)》
上一篇我们正式开启了一个Scrapy爬虫项目的实战,对当当网进行剖析和抓取。本篇我们继续编写该当当网的项目,讲解刚刚编写的Spider与item之间的关系,以及如何使用item,以及使用pipelines管道进行数据下载的操作。

一、使用item封装数据

在上一篇我们通过编写的爬虫文件,获取到当当网“一般管理类”书籍的第一页的明细列表信息。但是我们仅仅是将爬取到的目标信息print打印到控制台了,没有保存下来,这里我们就需要item先进行数据的封装。在“dang.py”爬虫文件里,我们获取到了目标数据,这些数据是我们之前通过item定义过这些数据的数据结构,但是没有使用过:

import scrapy

class ScrapyDangdang01Item(scrapy.Item):
    # 书籍图片
    src = scrapy.Field()
    # 书籍名称
    title = scrapy.Field()
    # 书籍作者
    search_book_author = scrapy.Field()
    # 书籍价格
    price = scrapy.Field()
    # 书籍简介
    detail = scrapy.Field()

那么,我们如何使用item定义好的数据结构呢?我们在爬虫文件中,首先通过from引用上面的class的名称:

from scrapy_dangdang_01.items import ScrapyDangdang01Item

注:可能编译器会报错,这是编译器版本的问题,不影响后面的执行,可以忽略。
导入完毕之后,我们创建一个book对象,这个对象就是把上面那些零散的信息全部都组装起来的集合体,然后在构造函数中,将所有抓取到的属性,挨个赋值到item文件中的各个属性中去:

book = ScrapyDangdang01Item(src=src, title=title, search_book_author=search_book_author, price=price, detail=detail)

然后这个book对象,就要交给pipelines进行下载。

二、设置yield返回目标对象

这里我们需要使用到Python中的yield指令,它的作用如下:

        yield是Python中的一个关键字,主要用于定义生成器(generator)。生成器是一种特殊的迭代器,可以逐个地生成并返回一系列的值,而不是一次性地生成所有的值。这可以节省大量的内存,尤其是在处理大量数据时。

        yield的工作原理类似于return,但它不仅仅返回一个值,还可以保存生成器的状态,使得函数在下次调用时可以从上次离开的地方继续执行。
下面是一个简单的生成器函数的例子:

def simple_generator():  
    n = 1  
    while n <= 5:  
        yield n  
        n += 1  
  
for i in simple_generator():  
    print(i)

        在这个例子中,simple_generator 是一个生成器函数,它使用 yield 来生成一系列的数字。当我们对这个生成器进行迭代(例如,在 for 循环中)时,它会逐个生成数字 1 到 5,并打印出来。

所以我们这里使用yield是用来将上面for循环中的每一个book交给pipelines处理,循环一个处理一个。编写代码如下:

# 将数据封装到item对象中
book = ScrapyDangdang01Item(src=src, title=title, search_book_author=search_book_author, price=price, detail=detail)

# 获取一个book对象,就将该对象交给pipelines
yield book

此时for循环每执行一次,爬虫函数就会返回一个封装好的book对象。完整的爬虫文件代码如下(scrapy_dangdang_01/scrapy_dangdang_01/spiders/dang.py):

import scrapy

from scrapy_dangdang_01.items import ScrapyDangdang01Item

class DangSpider(scrapy.Spider):
    name = "dang"
    allowed_domains = ["category.dangdang.com"]
    start_urls = ["http://category.dangdang.com/cp01.22.01.00.00.00.html"]

    def parse(self, response):
        # 获取所有的图书列表对象
        li_list = response.xpath('//ul[@id="component_59"]/li')

        # 遍历li列表,获取每一个li元素的几个值
        for li in li_list:
            # 书籍图片
            src = li.xpath('.//img/@data-original').extract_first()
            # 第一张图片没有@data-original属性,所以会获取到控制,此时需要获取src属性值
            if src:
                src = src
            else:
                src = li.xpath('.//img/@src').extract_first()
            # 书籍名称
            title = li.xpath('.//img/@alt').extract_first()
            # 书籍作者
            search_book_author = li.xpath('./p[@class="search_book_author"]//span[1]//a[1]/@title').extract_first()
            # 书籍价格
            price = li.xpath('./p[@class="price"]//span[@class="search_now_price"]/text()').extract_first()
            # 书籍简介
            detail = li.xpath('./p[@class="detail"]/text()').extract_first()
            # print("======================")
            # print("【图片地址】", src)
            # print("【书籍标题】", title)
            # print("【书籍作者】", search_book_author)
            # print("【书籍价格】", price)
            # print("【书籍简介】", detail)

            # 将数据封装到item对象中
            book = ScrapyDangdang01Item(src=src, title=title, search_book_author=search_book_author, price=price, detail=detail)

            # 获取一个book对象,就将该对象交给pipelines
            yield book

三、编写pipelines保存数据至本地

首先我们进入setting.py中,设置“ITEM_PIPELINES”参数,在其中添加我们设置的pipelines管道文件的路径地址:

# 管道可以有很多个,前面是管道名后面是管道优先级,优先级的范围是1到1000,值越小优先级越高
ITEM_PIPELINES = {
    "scrapy_dangdang_01.pipelines.ScrapyDangdang01Pipeline": 300,
}

此时我们进入pipelines.py中编写管道逻辑:

from itemadapter import ItemAdapter

# 如果需要使用管道,要在setting.py中打开ITEM_PIPELINES参数
class ScrapyDangdang01Pipeline:
    # process_item函数中的item,就是爬虫文件yield的book对象
    def process_item(self, item, spider):
        # 这里写入文件需要用'a'追加模式,而不是'w'写入模式,因为写入模式会覆盖之前写的
        with open('book.json', 'a', encoding='utf-8') as fp:
            # write方法必须写一个字符串,而不能是其他的对象
            fp.write(str(item))
        return item

此时我们执行爬虫函数,可以看到执行成功:

然后我们打开生成的book.json文件,“Ctrl+Alt+l”排版之后,可以看到我们爬取的数据已经生成了:

上面就是管道+爬虫+item的综合使用模式。

四、进行必要的优化

在上面的pipelines管道函数中,我们每一次获取到爬虫for循环yield的book对象时,都需要打开一次文件进行写入,比较耗费读写资源,对文件的操作过于频繁。

优化方案:在爬虫执行开始的时候就打开文件,爬虫执行结束之后再关闭文件。此时我们就需要了解pipelines的生命周期函数。分别为以下几个方法:

(1)open_spider(self, spider): 当爬虫开始时,这个方法会被调用。你可以在这里进行一些初始化的操作,比如打开文件、建立数据库连接等。
(2)close_spider(self, spider): 当爬虫结束时,这个方法会被调用。你可以在这里进行清理操作,比如关闭文件、断开数据库连接等。
(3)process_item(self, item, spider): 这是pipelines中最核心的方法。每个被抓取并返回的项目都会经过这个方法。你可以在这里对数据进行清洗、验证、转换等操作。这个方法必须返回一个项目(可以是原项目,也可以是经过处理的新项目),或者抛出一个DropItem异常,表示该项目不应被进一步处理。

此时我们就可以使用open_spider定义爬虫开始时打开文件,close_spider定义爬虫结束时关闭文件,而在爬虫运行期间的process_item方法中,只进行写的操作,完整代码如下:

from itemadapter import ItemAdapter
import json

# 如果需要使用管道,要在setting.py中打开ITEM_PIPELINES参数
class ScrapyDangdang01Pipeline:
    # 1、在爬虫文件开始执行前执行的方法
    def open_spider(self,spider):
        print('++++++++爬虫开始++++++++')
        # 这里写入文件需要用'a'追加模式,而不是'w'写入模式,因为写入模式会覆盖之前写的
        self.fp = open('book.json', 'a', encoding='utf-8') # 打开文件写入

    # 2、爬虫文件执行时,返回数据时执行的方法
    # process_item函数中的item,就是爬虫文件yield的book对象
    def process_item(self, item, spider):
        # write方法必须写一个字符串,而不能是其他的对象
        self.fp.write(str(item)) # 将爬取信息写入文件
        return item

    # 在爬虫文件开始执行后执行的方法
    def close_spider(self, spider):
        print('++++++++爬虫结束++++++++')
        self.fp.close() # 关闭文件写入

这样就能解决对文件操作频繁,耗费读写资源的问题了。

五、多管道的支持

pipelines支持设置多个管道,例如我们在原来的pipelines.py中再定义一个管道class类,用来下载每一个图书的图片:

# 下载爬取到的book对象中的图片文件
class ScrapyDangdangImagesPipeline:
    def process_item(self, item, spider):
        # 获取book的src属性,并按照地址下载图片,保存值books文件夹下
        url = 'http:' + item.get('src')
        filename = './books/' + item.get('title') + '.jpg'
        # 检查并创建目录
        if not os.path.exists('./books/'):
            os.makedirs('./books/')
        urllib.request.urlretrieve(url=url, filename=filename)
        return item

然后我们在setting.py中的ITEM_PIPELINES参数中追加这个管道:

# 管道可以有很多个,前面是管道名后面是管道优先级,优先级的范围是1到1000,值越小优先级越高
ITEM_PIPELINES = {
    "scrapy_dangdang_01.pipelines.ScrapyDangdang01Pipeline": 300,
    "scrapy_dangdang_01.pipelines.ScrapyDangdangImagesPipeline": 301
}

运行爬虫文件,可以看到相关的图片已经全部下载下来:

并且都是可以打开的图片:

至此管道+爬虫+item的综合使用模式讲解完毕。下一篇我们来讲解Scrapy的多页面下载如何实现。

参考:尚硅谷Python爬虫教程小白零基础速通
转载请注明出处:https://guangzai.blog.csdn.net/article/details/136283532

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

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

相关文章

Stable Diffusion 3内测申请~~~快冲鸭~~~~~

Stability AI 将其更改为 Stable Diffusion 3。VentureBeat 报道称&#xff0c;Stability AI 的下一代旗舰 AI 图像生成模型将使用类似于 OpenAI 的 Sora 的扩散变压器框架。其当前模型仅依赖于扩散架构。虽然尚未发布&#xff0c;但您可以在等候名单中注册。 以下内容机翻&am…

matlab悬臂梁有限元分析

1、内容简介 略 47-可以交流、咨询、答疑 2、内容说明 略 建模说明 设计一个长方体的悬臂梁&#xff0c;长宽高分别为100m、10m和15m&#xff0c;材料特性为杨氏模量2e5&#xff0c;泊松比0.3&#xff0c; Matlab有限元分析&#xff08;截图&#xff09; 上图为悬臂梁的扰度…

2023年Q4 Coremail管理员社区季刊发布

2023年Q4季刊新鲜出炉&#xff0c;本期内容涵盖了Coremail管理员社区Q4征稿活动、社区热门内容以及直播活动的总结。 本文为2023年Q4 Coremail管理员社区季刊精彩内容的节选&#xff0c;完整内容请上Coremail管理员社区进行查看。 1、Coremail管理员社区季刊介绍 2023 年4月&a…

CUDA编程 - 用向量化访存优化 - Cuda elementwise - Add(逐点相加)- 学习记录

Cuda elementwise - Add 一、简介1.1、ElementWise Add1.2、 float4 - 向量化访存 二、实践2.1、如何使用向量化访存2.1、简单的逐点相加核函数2.2、ElementWise Add float4&#xff08;向量化访存&#xff09;2.3、完整代码 一、简介 1.1、ElementWise Add Element-wise 操作…

table展示子集踩坑

##elemenui中table通过row中是否有children进行判断是否展示子集&#xff0c;通过设置tree-prop的属性进行设置&#xff0c;子级的children的名字可以根据自己的子级名字进行替换&#xff0c;当然同样可以对数据处理成含有chilren的子级list。 问题&#xff1a; 1.如果是根据后…

wpf 简单实验 数据更新 列表更新

1.概要 1.1 需求 一个列表提供添加修改删除的功能&#xff0c;添加和修改的内容都来自一个输入框 1.2 要点 DisplayMemberPath"Zhi"列表.ItemsSource datalist;(列表.SelectedItem ! null)(列表.SelectedItem as A).Zhi 内容.Text;datalist.Remove((列表.Selec…

YUV Format

title: 音视频同步 date: 2024-02-26 21:01:24 comments: true #是否可评论 toc: true #是否显示文章目录 categories: #分类 - 多媒体技术 tags: #标签 - 多媒体技术 summary: YUV Format YUV Format 简介 国际视频组织定义了多种yuv数据格式。文章中每一个像素都只有8bits…

大佬推荐的网络安全学习路线(从基础到高级)

说起网络安全&#xff0c;你可能会担心它是一个过时的行业。有人说&#xff0c;网络安全快卷死了&#xff0c;你既要攻又要防&#xff0c;并且随着技术的发展&#xff0c;你还要不断地学习&#xff0c;不在卷中生&#xff0c;就在卷中死。 实际上&#xff0c;随着数字化进程的…

Nest.js权限管理系统开发(八)jwt登录

安装相关依赖 虽然仅使用nestjs/jwt就能实现身份验证的功能&#xff0c;但是使用passport能在更高层次上提供更多便利。Passport 拥有丰富的 strategies 生态系统&#xff0c;实现了各种身份验证机制。虽然概念简单&#xff0c;但你可以选择的 Passport 策略集非常丰富且种类繁…

【性能测试】企业性能测试-并发用户数估算(详细)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 并发用户数&#…

05 Flink 的 WordCount

前言 本文对应于 spark 系列的 Spark 的 WordCount 这里主要是 从宏观上面来看一下 flink 这边的几个角色, 以及其调度的整个流程 一个宏观 大局上的任务的处理, 执行 基于 一个本地的 flink 集群 测试用例 /*** com.hx.test.Test01WordCount** author Jerry.X.He* ver…

第十二章 Linux——日志管理

第十二章 Linux——日志管理 基本介绍系统常用日志日志管理服务日志轮替基本介绍日志轮替文件命名logrotate配置文件自定义加入日志轮转应用实例 日志轮替机制原理查看内存日志 基本介绍 日志文件是重要的系统信息文件&#xff0c;其中记录了许多重要的系统事件&#xff0c;包…

跨浏览器测试:如何确保你的应用在各种浏览器上都能正常运行

在当今的互联网时代&#xff0c;浏览器已成为我们获取信息、与他人交流、工作和娱乐的主要工具。然而&#xff0c;不同的浏览器、不同的版本和不同的操作系统可能会对你的应用造成不同的影响&#xff0c;可能使其表现出各种不同的行为和问题。为了确保你的应用能在各种浏览器环…

F2图例封装 - Bar

基于vue3 和 F2 3.5.0 <template><div :style"{minHeight: ${height}px,width: 100% }" ref"container"><canvas v-show"showChart" :id"chartId" class"chart-canval"></canvas><empty-box v-…

人工智能产生的幻觉问题真的能被看作是创造力的另一种表现形式吗?

OpenAI的首席执行官山姆奥特曼&#xff08;Sam Altman&#xff09;曾声称&#xff0c;人工智能产生的“幻觉”其实未尝不是一件好事&#xff0c;因为实际上GPT的优势正在于其非凡的创造力。 目录 一.幻觉问题的概念 二.幻觉产生的原因 三.幻觉的分类 四.减轻AI的幻觉问题到…

【云原生】Spring Cloud Gateway的底层原理与实践方法探究

&#x1f389;&#x1f389;欢迎光临&#x1f389;&#x1f389; &#x1f3c5;我是苏泽&#xff0c;一位对技术充满热情的探索者和分享者。&#x1f680;&#x1f680; &#x1f31f;特别推荐给大家我的最新专栏《Spring 狂野之旅&#xff1a;从入门到入魔》 &#x1f680; 本…

【深度学习笔记】深度学习训练技巧

深度学习训练技巧 1 优化器 随机梯度下降及动量 随机梯度下降算法对每批数据 ( X ( i ) , t ( i ) ) (X^{(i)},t^{(i)}) (X(i),t(i)) 进行优化 g ∇ θ J ( θ ; x ( i ) , t ( i ) ) θ θ − η g g\nabla_\theta J(\theta;x^{(i)},t^{(i)})\\ \theta \theta -\eta g g…

Aigtek前置微小信号放大器在传感器检测中的应用有哪些

传感器是将物理量转换为电信号的装置&#xff0c;其精度和灵敏度直接影响到检测系统的性能。而传感器的输出信号通常都非常微弱&#xff0c;需要进行放大处理才能得到可靠的测量结果。前置微小信号放大器&#xff0c;作为一种重要的传感器检测元件&#xff0c;在传感器检测中发…

苏宁商品详情大揭秘:一键解锁API接口,电商数据尽在掌握

苏宁商品详情API接口技术深度探索 一、引言 在电商领域&#xff0c;获取商品详情是许多业务场景的基础需求。苏宁商品详情API接口为此提供了便捷的途径。本文将带你深入了解苏宁商品详情API接口的技术细节&#xff0c;帮助你更好地利用这一接口&#xff0c;提升业务效率。 二…

春节医美热,爱美客、昊海生科谁更赚钱?

在颜值经济赛道上&#xff0c;医美项目逐渐成为消费主流。随着春节假期的到来&#xff0c;医美消费又将迎来高峰期。 “医美三剑客”中&#xff0c;爱美客(300896.SZ)、昊海生科(688366.SH)近日相继公布了2023年的业绩报告&#xff1a;2023年&#xff0c;爱美客预计实现净利润…