【Python从入门到进阶】51、电影天堂网站多页面下载实战

接上篇《50、当当网Scrapy项目实战(三)》
上一篇我们讲解了使用Scrapy框架在当当网抓取多页书籍数据的效果,本篇我们来抓取电影天堂网站的数据,同样采用Scrapy框架多页面下载的模式来实现。

一、抓取需求

打开电影天堂网站(https://dy2018.com/),点击最新电影的更多页面(https://www.dy2018.com/html/gndy/dyzz/index.html),这里需要抓取最新电影的名字,以及详情页的图片:


要完成这个目标,我们需要造Scrapy框架中封装一个里外嵌套的item对象。下面我们来进行开发。

二、创建工程及爬虫文件

首先我们打开编辑器,打开控制台,进入爬虫文件夹,使用“scrapy startproject 项目名”指令,来创建我们的爬虫工程:

然后进入配置文件settings.py,设置ROBOTSTXT_OBEY参数为false,即不遵循robots协议。
然后进入工程文件的spiders文件夹下,使用“scrapy genspider 爬虫文件名 爬取路径”创建我们的爬虫文件,这里我命名爬虫文件为“movies”:

三、编写爬虫逻辑

默认生成的spider爬虫代码如下:

import scrapy

class MoviesSpider(scrapy.Spider):
    name = "movies"
    allowed_domains = ["www.dy2018.com"]
    start_urls = ["https://www.dy2018.com/html/gndy/dyzz/index.html"]

    def parse(self, response):
        pass

我们把其中的“pass”替换为“print("=============")”,使用“scrapy crawl 爬虫文件名”执行该爬虫:

可以看到正常输出了我们打印的等于号,可以证明网站并没有设置反爬虫。下面我们来编写实际内容,首先我们先定义我们最终要包装成的item对象:

import scrapy

class ScrapyMovieItem(scrapy.Item):
    name = scrapy.Field()
    src = scrapy.Field()

这里我们主要定义了两个参数,一个是电影名字name,一个是电影封面地址src。

然后我们回到电影天堂列表界面,F12查看电影名字的Html代码:

可以看到是由td包裹的标签,其中a标签中的内容即为电影名字,其中的href参数为电影的详情页面地址。
然后邮件Html中的电影名所在标签,使用xpath工具,获取到电影名字的xpath路径:

xpath地址为:

/html/body/div/div/div[3]/div[6]/div[2]/div[2]/div[2]/ul/table[1]/tbody/tr[2]/td[2]/b/a

这里full xpath获取的地址太长,我们再观察一下,发在它是在class为co_content8的div下面的:

xpath地址可以缩减为:
(1)电影名称

//div[@class="co_content8"]//td[2]//a[1]/text()

(2)详情地址

//div[@class="co_content8"]//td[2]//a[1]/@href

所以爬虫代码可以编写为:

import scrapy


class MoviesSpider(scrapy.Spider):
    name = "movies"
    allowed_domains = ["www.dy2018.com"]
    start_urls = ["https://www.dy2018.com/html/gndy/dyzz/index.html"]

    def parse(self, response):
        # 抓取电影名称以及详情页的封面
        a_list = response.xpath('//div[@class="co_content8"]//td[2]//a[1]')

        for a in a_list:
            # 获取第一页的name和要点击的详情链接地址
            name = a.xpath('./text()').extract_first()
            href = a.xpath('./@href').extract_first()

            print(name,href)

执行一下爬虫,可以看到能拿到相应结果:

然后完善详情界面的地址,进入详情地址,然后获取详情页的图片:

import scrapy

class MoviesSpider(scrapy.Spider):
    name = "movies"
    allowed_domains = ["www.dy2018.com"]
    start_urls = ["https://www.dy2018.com/html/gndy/dyzz/index.html"]

    def parse(self, response):
        # 抓取电影名称以及详情页的封面
        a_list = response.xpath('//div[@class="co_content8"]//td[2]//a[1]')

        for a in a_list:
            # 获取第一页的name和要点击的详情链接地址
            name = a.xpath('./text()').extract_first()
            href = a.xpath('./@href').extract_first()

            # 拼接得到详情页地址
            url = 'https://www.dy2018.com'+href
            # 对第二页的链接发起访问
            yield scrapy.Request(url=url, callback=self.parse_second, meta={'name': name})

    def parse_second(self, response):
        print("第二个解析方法")

这里我们执行了第二个解析方法,并在下面定义了这个方法“parse_second”,并在上一个函数中,将name作为meta参数带入进去。
此时我们去电影天堂网站打开第一个电影的详情页,右键或F12查看电影封面:

可以大致推断出封面路径的xpath地址为:

//div[@id="Zoom"]//img[1]/@src

所以解析详情图片的代码为(ScrapyMovieItem需要import一下):

def parse_second(self, response):
    src = response.xpath('//div[@id="Zoom"]//img[1]/@src').extract_first()
    # 获取上一步得到的meta参数中的name
    name = response.meta['name']

    movie = ScrapyMovieItem(name=name, src=src)
    yield movie

最后将封装好的movie对象返回给管道。完整代码:

import scrapy

from scrapy_movie.items import ScrapyMovieItem


class MoviesSpider(scrapy.Spider):
    name = "movies"
    allowed_domains = ["www.dy2018.com"]
    start_urls = ["https://www.dy2018.com/html/gndy/dyzz/index.html"]

    def parse(self, response):
        # 抓取电影名称以及详情页的封面
        a_list = response.xpath('//div[@class="co_content8"]//td[2]//a[1]')

        for a in a_list:
            # 获取第一页的name和要点击的详情链接地址
            name = a.xpath('./text()').extract_first()
            href = a.xpath('./@href').extract_first()

            # 拼接得到详情页地址
            url = 'https://www.dy2018.com' + href
            # 对第二页的链接发起访问
            yield scrapy.Request(url=url, callback=self.parse_second, meta={'name': name})

    def parse_second(self, response):
        src = response.xpath('//div[@id="Zoom"]//img[1]/@src').extract_first()
        # 获取上一步得到的meta参数中的name
        name = response.meta['name']
        print(name, src)
        movie = ScrapyMovieItem(name=name, src=src)

        yield movie

四、开启并定义管道

此时我们前往settings.py开启管道(将ITEM_PIPELINES注释取消即可):

ITEM_PIPELINES = {
   "scrapy_movie.pipelines.ScrapyMoviePipeline": 300,
}

然后打开pipelines.py,编写一段逻辑,将获取的电影名字和封面地址写入一个json文件中:

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

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

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

五、执行测试

编写完item、spider、pipeline之后,我们运行爬虫,查看输出的json文件:

可以看到完整获取电影的名称以及封面图片的下载地址。

以上就是电影天堂网站多页面下载的实战内容。下一篇我们来讲解scrapy中链接提取器的使用。

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Ubuntu Desktop 更改默认应用程序 (Videos -> SMPlayer)

Ubuntu Desktop 更改默认应用程序 [Videos -> SMPlayer] References System Settings -> Details -> Default Applications 概况、默认应用程序、可移动介质、法律声明 默认应用程序,窗口右侧列出了网络、邮件、日历、音乐、视频、照片操作的默认应用程序…

OCR如何解决字体多样性难题?

OCR(Optical Character Recognition,光学字符识别)技术的确是一项非常实用的技术,能够将图像中的文字转化为可编辑的文本,大大提高了工作效率。然而,你所遇到的问题——字体多样性导致的模型泛化能力不足&a…

AtCoder Regular Contest 175(A~B)

补题:A - Spoon Taking Problem 阅读理解就能劝退好多人,先看B题可能收益会更高。 N个人都是这么坐的,勺子标号也给你标好了。 如果 s[1]L,那么1这个人就要拿左边的勺子,如果左边没有就拿右边的,右边也没…

[AutoSar]BSW_ OS CORE, Physical core,EcuC core,EcuC partition,OSApplication的关系

目录 关键词平台说明一、总体依赖关系二、相关概念三、在配置中的实现3.1 EcucPartition3.2 OsApplication3.3 Ecu core 关键词 嵌入式、C语言、autosar、OS、BSW 平台说明 项目ValueOSautosar OSautosar厂商vector , EB芯片厂商TI 英飞凌编程语言C,C…

Centos7 防火墙iptables?

Centos7 防火墙iptables? 文章目录 Centos7 防火墙iptables?1. 介绍2. firewalld 和 iptables区别3. 区域管理概念区域管理有如下几种不同的初始化区域: 4.iptables的配置1.简述2.基本原理3.iptables传输数据包的过程4. iptables规则表和链5.…

C++初阶:STL容器list的使用与初版自实现

目录 1. list的接口与使用1.1 默认成员函数1.2 迭代器与容量相关成员函数1.3 存储数据操作相关成员函数1.4 其他list操作成员函数 2. list的自实现2.1 list的自实现功能2.2 list的结点结构2.3 list的迭代器2.3 list的结构2.4 list迭代器的运算符重载2.5 list的成员函数 3. cons…

python绘图matplotlib——使用记录2

本博文来自于网络收集,如有侵权请联系删除 三维图绘制 1 三维散点图2 三维柱状图三维曲面 1 三维散点图 import matplotlib.pyplot as plt import numpy as npfrom mpl_toolkits.mplot3d import Axes3Dfig plt.figure() # ax fig.gca(projection"3d")…

javase day11笔记

第十一天课堂笔记 构造代码块 { } 给 所有对象 共性特点 进行初始化操作 创建对象时在堆区对象中存放实例变量,同时执行构造代码块 执行顺序:静态代码块—>非静态代码块—>构造方法 继承★★★ 将多个类中相同的实例变量和实例方法 , 单独存放到一个类中,成为父类…

【Linux】写个日志和再谈线程池

欢迎来到Cefler的博客😁 🕌博客主页:折纸花满衣 🏠个人专栏:信号量和线程池 目录 👉🏻日志代码Log.cppMain.cc 👉🏻线程池代码LockGuard.hpp(自定义互斥锁,进…

网易web安全工程师进阶版课程

课程介绍 《Web安全工程师(进阶)》是由“ i春秋学院联合网易安全部”出品,资深讲师团队通过精炼的教学内容、丰富的实际场景及综合项目实战,帮助学员纵向提升技能,横向拓宽视野,牢靠掌握Web安全工程师核心…

Python6:Socket编程初步学习笔记

Socket协议概要 创建socket的时候,需要一些选项来说明本次使用协议具体是什么,常用的两个: 由此产生的不同组合: 但目前TCP(IPV4)是主流,SOCK_STREAMAF_INET 创建和使用Socket socket模块中有socket类&#xff1a…

51单片机学习笔记——LED闪烁和流水灯

任务分析 首先要知道LED闪烁主要是怎么工作的,闪烁亮灭自然是一下为高一下为低,亮灭的频率则需要延时来进行控制。 上节已经知道了如何点亮那延时如何做呢首先先编写主框架 这样是否可以通过循环将LED灯一直循环闪烁。 以为while一直在循环所以其实是可…

向开发板上移植ip工具:交叉编译 ip工具

一. 简介 前面几篇文章学习了 CAN设备节点的创建,以及如何使能 CAN驱动。 本文学习向开发板上移植ip工具。 二. 向开发板上移植ip工具:交叉编译 ip工具 注意:在移植 ip 命令的时候必须先对根文件系统做个备份!防止操作失误导…

力扣74---搜索二维矩阵

目录 题目描述: 思路: 代码: 题目描述: 给你一个满足下述两条属性的 m x n 整数矩阵: 每行中的整数从左到右按非严格递增顺序排列。 每行的第一个整数大于前一行的最后一个整数。 给你一个整数 targ…

c#绘制图形

窗体工具控件 如果选纹理 ,需要在ImageList中选择图像(点击添加选择图片路径) using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Drawing.Drawing2D; using System.Linq; using System.…

【Redis教程0x03】详解Redis的基本数据类型

引言 根据【Redis教程0x02】中介绍的,Redis的数据类型可分为5种基本数据类型(String、Hash、List、Set、Zset)和4种高级数据类型(BitMap、HyperLogLog、GEO、Stream)。在本篇博客中,我们将详解这9种数据类…

分类预测 | Matlab实现CNN-LSTM-Mutilhead-Attention卷积神经网络-长短期记忆网络融合多头注意力机制多特征分类预测

分类预测 | Matlab实现CNN-LSTM-Mutilhead-Attention卷积神经网络-长短期记忆网络融合多头注意力机制多特征分类预测 目录 分类预测 | Matlab实现CNN-LSTM-Mutilhead-Attention卷积神经网络-长短期记忆网络融合多头注意力机制多特征分类预测分类效果基本介绍模型描述程序设计参…

Springboot做分组校验

目录 分组校验 Insert分组 Upload分组 测试接口 测试结果 添加测试 更新测试 顺序校验GroupSequence 自定义分组校验 自定义分组表单 CustomSequenceProvider 测试接口 测试结果 Type类型为A Type类型为B 总结: 前文提到了做自定义的校验注解&#xff…

牛客NC170 最长不含重复字符的子字符串【高频 中等 map、滑动窗口 Java,Go,PHP】

题目 题目链接: https://www.nowcoder.com/practice/48d2ff79b8564c40a50fa79f9d5fa9c7 思路 用一个hashmap记录每个字母的index如果这个字母已经在map里了说明已经有重复了这样就更新看这个字母上次出现的index需要注意的是这种情况:“bacbca”这里的a…

初识kafka-数据存储篇1

目录 背景 1 kafka总体体系结构 2 疑问解答 2.1 高吞吐低延迟 2.2 实现分布式存储和数据读取 2.3 如何保证数据不丢失 背景 最近在和产品过项目审批的时候,深刻感受到业务方对系统的时时响应提出了更高的要求。目前手上大部分的业务都是基础定时任务去实现的&…