Python爬虫之Scrapy框架系列(5)——项目实战【某瓣Top250电影所有信息的txt文本存储】

news2024/11/14 20:18:10

上篇文章已经成功解析提取到豆瓣Top250电影想要的所有数据。下一步就是将其交给管道进行存储。

目录:

  • 1. 编写items.py文件(定义结构化数据字段)
  • 2. 爬虫文件里将数据一一对应字段名:
  • 3. 将数据返回给管道:
  • 4. 编写pipelines.py文件进行数据存储:
  • 5. 某瓣Top250首页25个电影更多信息已经抓取完毕,效果如下:
  • 拓展:上面实现了某瓣首页25个电影信息的爬取,那么如何爬取更多页呢?
    • 1. 首先,分析如何爬取两页:
    • 2. 获取两页的信息都可以实现了,那么获取更多(比如:10页),只要找到每页url的规律,给个循环就OK啦!
      • 2.1 剖析每页url可知:每加一页,对应的start参数的值就会加25。
      • 2.2 在爬虫文件每个请求执行完成功之后,利用格式化输出.format()方法向引擎发送每页的请求即可!
      • 2.3 运行会发现很棒哦!

1. 编写items.py文件(定义结构化数据字段)

  • 首先,引擎交给spider(爬虫文件)的信息已经被爬虫解析并提取正确的信息,下一步是spider(爬虫文件)将数据再次交给引擎,而能否成功交给引擎,这就取决于items.py文件(定义结构化数据字段)是否有对应的字段名等待插入数据:
# -*- coding: utf-8 -*-

# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html

import scrapy


class DoubanItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    #需要定义字段名  就像数据库那样,有字段名,才能插入数据(即存储数据)
    # films_name=scrapy.Field()   #定义字段名
    film_name=scrapy.Field()
    star_name=scrapy.Field()
    score=scrapy.Field()

items.py文件中已经创建好字段名等待插入数据了,下一步就是:

2. 爬虫文件里将数据一一对应字段名:

在刚刚的爬虫文件的循环下写入即可:

            # 使用字段名  收集数据
            item=item=DoubanItem()
            item["film_name"]=film_name
            item["star_name"]=star_name
            item["score"]=score

注意:在settings.py文件中开启管道并关闭robots协议!

3. 将数据返回给管道:

  • 引擎将数据交给管道的中间的item这一步已经成功走过去了,下一步就是如何将数据返回给管道:在这里要注意一个问题:惯性思维会让我们在这个函数里定性的使用return返回item,但是,切记return返回的是parse这个方法(会造成只会传给管道第一个电影信息的bug)。而我们所需要的是返回每次解析后的数据,so我们想到了生成器,使用yield返回,这样每搞一次数据出来,生成器就给一次数据,循环如此,非常nice!!!

我们只需在爬虫文件的循环最底下加入即可:

			             # 形式:{"film_name":"肖申克的救赎","star_name":"蒂姆","score":"9.7"}

						 yield item

4. 编写pipelines.py文件进行数据存储:

  • 引擎已经将数据交给管道(即pipelines.py管道文件),但是,我们这是25个请求,就会进行25次处理,也就意味着,引擎会交给管道25次数据,那么我们在管道里进行储存数据的时候,按往常来说就要来来回回打开关闭文件,进行数据的写入。这样显然不好。所以:在此引入管道文件里的两种牛批的方法:
#爬虫文件开启,此方法就开启
def open_spider(self,spider):
	pass
	
#爬虫文件关闭,此方法就开启
def close_spider(self,spider):
	pass
  • 这就非常合我们的需求,结合这两个方法,我们只需要在open_spider()方法里加入打开文件操作;在close_spider()方法里加入关闭文件操作即可,这样就避免了文件的来来回回的开启关闭,好处不言而喻。

  • 来看看升级版的pipelines.py文件(管道文件):

# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html

import json
class DoubanPipeline(object):
    def open_spider(self,spider):   #爬虫文件开启,此方法就开启
        self.f=open("films.txt","w",encoding="utf-8")       #打开文件

    def process_item(self, item, spider):        #会来25次,就会调用25次这个方法  如果按常规来写,文件就会被操作25次打开关闭
        #为了能写进text  json.dumps将dic数据转换为str
        json_str=json.dumps(dict(item),ensure_ascii=False)+"\n"
        self.f.write(json_str)                              #爬虫文件开启时,文件就已经打开,在此直接写入数据即可!
        return item

    def close_spider(self,spider):  #爬虫文件关闭,此方法就开启
        self.f.close()                                      #爬虫文件关闭时,引擎已经将全部数据交给管道,关闭文件

5. 某瓣Top250首页25个电影更多信息已经抓取完毕,效果如下:

在这里插入图片描述

拓展:上面实现了某瓣首页25个电影信息的爬取,那么如何爬取更多页呢?

1. 首先,分析如何爬取两页:

  • 注意:Scrapy框架运行的流程,任何模块发出的请求都是给到引擎的,所以,我们只需要在爬虫文件中的第一次请求的数据提交给管道之后,使用yield发起一个请求(某瓣电影Top250第二页的url),那么,这个请求就会自动的交给了引擎,就开启了新一轮的自动化走流程,但是,在最后引擎需要将数据再送给spider爬虫文件让其解析并获取真正想要存储到管道的数据,所以就需要callback回调自身这个parse函数。
    逻辑如下图:

在这里插入图片描述

2. 获取两页的信息都可以实现了,那么获取更多(比如:10页),只要找到每页url的规律,给个循环就OK啦!

2.1 剖析每页url可知:每加一页,对应的start参数的值就会加25。

'''
各页url规律剖析:
https://xxx.com/top250
https://xxx.com/top250?start=0&filter=
https://xxx.com/top250?start=25&filter=
https://xxx.com/top250?start=50&filter=
'''

2.2 在爬虫文件每个请求执行完成功之后,利用格式化输出.format()方法向引擎发送每页的请求即可!

  • (每完成一个请求的全部流程,page_num就会加一,25倍的page_num就对应了每页url的start参数的值;注意:我们会发现总共就10页有信息,多了就没得信息了,所以设置了if判断,如果url获取的信息为空,就返回空,引擎接到空的请求,就会自动关闭)
# -*- coding: utf-8 -*-
import scrapy
import re

from ..items import DoubanItem  # 因为我们要使用包含定义字段名的类,所以需要导入


class DbSpider(scrapy.Spider):
    name = 'db'
    allowed_domains = ['xxx.com']
    start_urls = ['xxx/top250']
    page_num = 0  # 类变量

    def parse(self, response):  # 解析和提取数据
        # 获取电影信息数据
        # films_name=response.xpath('//div[@class="info"]/div/a/span[1]/text()').extract()
        node_list = response.xpath('//div[@class="info"]')  # 25个
        if node_list:  # 此判断的作用:在爬取到10页之后,就获取不到了!判断每次是否获取到数据,如果没有则返回空(即停止了)
            for node in node_list:
                # 电影名字
                film_name = node.xpath('./div/a/span[1]/text()').extract()[0]
                # 主演   拿标签内容,再正则表达式匹配
                con_star_name = node.xpath('./div/p[1]/text()').extract()[0]
                if "主" in con_star_name:
                    star_name = re.findall("主演?:? ?(.*)", con_star_name)[0]
                else:
                    star_name = "空"
                # 评分
                score = node_list.xpath('./div/div/span[@property="v:average"]/text()').extract()[0]

                # 使用字段名  收集数据
                item = DoubanItem()
                item["film_name"] = film_name
                item["star_name"] = star_name
                item["score"] = score

                # 形式:{"film_name":"肖申克的救赎","star_name":"蒂姆","score":"9.7"}
                yield item  # 不使用return的原因是,return返回的是parse这个方法(会造成只会传给管道第一个电影信息的bug)。而我们所需要的是返回每次解析后的数据
            self.page_num += 1
            print("page_num:", self.page_num)
            page_url = "xxx/top250?start={}&filter=".format(self.page_num * 25)
            yield scrapy.Request(page_url, callback=self.parse)
            # 注意:各个模块的请求都会交给引擎,然后经过引擎的一系列操作;但是,切记:引擎最后要把得到的数据再来给到
            # spider爬虫文件让它解析并获取到真正想要的数据(callback=self.parse)这样就可以再给到自身。
        else:
            return


'''
各页url规律剖析:
https://xxx.com/top250
https://xxx.com/top250?start=0&filter=
https://xxx.com/top250?start=25&filter=
https://xxx.com/top250?start=50&filter=
'''

'''
网页源码剖析:
<div class="info">
                    <div class="hd">
                        <a href="https://xxx.com/subject/1292052/" class="">
                            <span class="title">肖申克的救赎</span>
                                    <span class="title">&nbsp;/&nbsp;The Shawshank Redemption</span>
                                <span class="other">&nbsp;/&nbsp;月黑高飞(港)  /  刺激1995(台)</span>
                        </a>


                            <span class="playable">[可播放]</span>
                    </div>
                    <div class="bd">
                        <p class="">
                            导演: 弗兰克·德拉邦特 Frank Darabont&nbsp;&nbsp;&nbsp;主演: 蒂姆·罗宾斯 Tim Robbins /...<br>
                            1994&nbsp;/&nbsp;美国&nbsp;/&nbsp;犯罪 剧情
                        </p>


                        <div class="star">
                                <span class="rating5-t"></span>
                                <span class="rating_num" property="v:average">9.7</span>
                                <span property="v:best" content="10.0"></span>
                                <span>1983356人评价</span>
                        </div>

                            <p class="quote">
                                <span class="inq">希望让人自由。</span>
                            </p>
                    </div>
</div>
'''

切记:
要在settings.py文件中开启延时。
不然:网站很容易检测出来,后果严重!!!

在这里插入图片描述

2.3 运行会发现很棒哦!

在这里插入图片描述

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

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

相关文章

MCAL系列介绍04-ICU

本文框架1. 前言2. 基本概念3. ICU采集过程3.1 获取周期占空比3.2 获取边沿数量3.3 获取时间戳4. Autosar系列文章快速链接1. 前言 ICU驱动器是使用Input Capture Uint模块&#xff08;ICU&#xff09;解调PWM信号、计数脉冲、测量频率和占空比、生成简单中断以及唤醒中断的模…

树莓派配置Python虚拟环境、安装PyQt5、安装PySide2

要从头设置好一台可用于开发的树莓派&#xff0c;可以参考树莓派 4B 无屏幕&#xff0c;连接WiFi、SSH、VNC&#xff0c;系统换源、pip换源&#xff0c;安装中文输入法 Python虚拟环境 树莓派&#xff08;或者说arm平台&#xff09;使用Python虚拟环境的正确方式是使用pipenv…

【手写 Vue2.x 源码】第三十九篇 - 组件部分 - 创建组件虚拟节点

一&#xff0c;前言 上篇&#xff0c;介绍了组件部分-组件的合并&#xff0c;主要涉及以下几个点&#xff1a; 组件初始化情况&#xff1b;组件合并的位置&#xff1b;组件合并的策略&#xff1b;组件合并后测试&#xff1b; 本篇&#xff0c;组件部分-组件的编译&#xff1…

【C语言】对<进阶版三子棋>的完善和改进

这篇文章主要是对前面三子棋游戏的完善和改进。 文章目录 目录 1.将棋子*和#&#xff0c;改为1和0&#xff1b; 2.电脑下棋显示坐标 3.可以选择电脑先手或玩家先手 4.在退出游戏时显示游戏信息 5.完善后的游戏效果 二、完整程序代码 1.game.h 2.test.c 3.game.c 总结 前言 h…

【教程】虚拟环境与Pytorch安装

【教程】虚拟环境与Pytorch安装NVIDIA驱动安装虚拟环境创建激活/删除相关库的安装Pytorch安装安装地址可能遇到的问题处理报错安装卡顿测试是否安装完成参考NVIDIA驱动安装 NVIDIA驱动可在官网进行安装&#xff1a;NVIDIA驱动官网 命令行输入nvidia-smi可查看cuda版本等信息&…

Linux常用命令——ss命令

在线Linux命令查询工具(http://www.lzltool.com/LinuxCommand) ss 比 netstat 好用的socket统计信息&#xff0c;iproute2 包附带的另一个工具&#xff0c;允许你查询 socket 的有关统计信息。 补充说明 ss命令用来显示处于活动状态的套接字信息。ss命令可以用来获取socket…

XGBoost的原理、工程实现与优缺点

Xgboost简介 XGBoost是陈天奇等人开发的一个开源机器学习项目&#xff0c;高效地实现了GBDT算法并进行了算法和工程上的许多改进&#xff0c;被广泛应用在Kaggle竞赛及其他许多机器学习竞赛中并取得了不错的成绩。XGBoost本质上还是一个GBDT&#xff0c;但是力争把速度和效率发…

C++普通类,派生类,虚基类的成员构造顺序以及构造函数调用顺序详解

目录前言普通类构造析构顺序解析依赖关系产生的错误派生类构造析构顺序解析扩展菱形多继承场景含虚基类的派生类构造析构顺序解析扩展菱形多继承场景(引入虚继承)前言 C规定“对象的析构过程必须与其构造过程相反”这一语法规则。 因此我们研究透彻了构造过程&#xff0c;那么…

宕机了,Redis如何避免数据丢失?

今天是大年初一&#xff0c;祝大家新年快乐&#xff0c;新的一年技术增进&#xff0c;工资翻倍。 目前&#xff0c;Redis的持久化主要有两大机制&#xff0c;即AOF日志和RDB快照&#xff0c;在接下来的两节课里&#xff0c;我们就分别学习一下吧。 AOF日志是如何实现的&#…

结构型模式-装饰器模式

1.概述 快餐店有炒面、炒饭这些快餐&#xff0c;可以额外附加鸡蛋、火腿、培根这些配菜&#xff0c;当然加配菜需要额外加钱&#xff0c;每个配菜的价钱通常不太一样&#xff0c;那么计算总价就会显得比较麻烦。 使用继承的方式存在的问题&#xff1a; 扩展性不好 如果要再加…

Alibaba微服务组件Sentinel学习笔记

1 .Sentinel 是什么 随着微服务的流行&#xff0c;服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式服务架构的流量控制组件&#xff0c;主要以 流量为切入点&#xff0c;从限流、流量整形、熔断降级、系统负载保护、热点防护等多个维度来帮助开发者保障微服务的…

一篇读懂图神经网络

来源&#xff1a;投稿 作者&#xff1a;张宇 编辑&#xff1a;学姐 近年来&#xff0c;作为一项新兴的图数据学习技术&#xff0c;图神经网络&#xff08;GNN&#xff09;受到了非常广泛的关注&#xff0c;在各大顶级学术会议上&#xff0c;图神经网络相关的论文也占了相当可观…

https://app.diagrams.net/在线画图的一些技巧

最近工作需要,实践了在线画图的case, 下面就把使用心得记录一下: 关于diagrams 的一些小技巧: 登入的网页是:Flowchart Maker & Online Diagram Software 1: 利用group 的选项,这个可以整体移动,不用担心会漏掉一个: 就是选中一个图标,然后,看右边arrange 下面…

20230123使AIO-3568J开发板在Android12下永不休眠

20230123使AIO-3568J开发板在Android12下永不休眠 2023/1/23 13:59 1、 Z:\android12-rk3568-new\device\rockchip\common\device.mk # Bluetooth HAL PRODUCT_PACKAGES \ libbt-vendor \ android.hardware.bluetooth1.0-impl \ android.hardware.bluetooth1.0-se…

Hadoop基础之《(1)—大数据基本概念》

一、Hadoop 1、Hadoop大数据框架&#xff0c;处理分布式环境下数据存储和计算 2、Hadoop的HDFS处理存储 3、Hadoop的MapReduce处理计算 map让任务数据拆分到每一台去执行 reduce处理后的任务合并 4、Hive作用是在Hadoop上能够让用户来写SQL处理数据 Hive的执行引擎&#xff0c;…

深度学习TensorFlow—GPU2.4.0版环境配置,一文简单易懂详细大全,CUDA11.0、cuDNN8.0

深度学习TensorFlow—GPU2.4.0版环境配置&#xff0c;一文简单易懂详细大全&#xff0c;CUDA11.0、cuDNN8.0 前提&#xff1a;电脑拥有英伟达独立显卡!!!&#xff0c;并且安装了anaconda&#xff01;&#xff01;&#xff01; 前提&#xff1a;电脑拥有英伟达独立显卡!!!&…

vue事件车之兄弟组件之间传值

目录前言一&#xff0c;全局事件总线介绍1.1 原理介绍1.2 x需要满足的条件二&#xff0c;知识点的复习2.1 vc是什么2.2 vm管理vc如何体现2.3 原型2.4 上述知识的串联三&#xff0c;实现需求3.1 x的编写及讲解3.2 使用x四&#xff0c;标准写法4.1 写法改动4.2 销毁五 关键代码后…

兔年首文迎新春-Cesium橘子洲烟花礼赞

兔年新春今天是兔年大年初二&#xff0c;神州大地&#xff0c;在经历了疫情的三年后迎来开放的一个春节。大家都沉浸在欢乐幸福的春节气氛中。玉兔迎新春&#xff0c;祝福齐送到&#xff1a;白兔祝你身体安康&#xff0c;黑兔祝你薪水高涨&#xff0c;灰兔送你梦想如意&#xf…

Maven高级

Maven高级 1&#xff0c;分模块开发 1.1 分模块开发设计 (1)按照功能拆分 我们现在的项目都是在一个模块中&#xff0c;比如前面的SSM整合开发。虽然这样做功能也都实现了&#xff0c;但是也存在了一些问题&#xff0c;我们拿银行的项目为例来聊聊这个事。 网络没有那么发…

Java多线程03——等待唤醒机制(and阻塞队列实现)

目录1.等待唤醒机制1.ThreadDemo2.Desk3.Cook4.Foodie2.等待唤醒机制&#xff08;阻塞队列方式实现&#xff09;1.ThreadDemo022.Cook023.Foodie023.线程的状态1.等待唤醒机制 生产者和消费者 桌子上有食物&#xff0c;消费者吃&#xff0c;桌子上没有食物&#xff0c;消费者等…