爬虫实战——scrapy框架爬取多张图片

scrapy框架的基本使用,请参考我的另一篇文章:scrapy框架的基本使用

起始爬取的网页如下:

点击每张图片,可以进入图片的详情页,如下:

 代码实现:

项目文件结构如下

img_download.py文件代码

import scrapy
# 这里导包的时候会显示报错,但其实不影响运行,如果想去掉,可以百度一下方法
from caixin591.items import Caixin591Item


class ImgDownloadSpider(scrapy.Spider):
    name = "img_download"
    allowed_domains = ["m.mms591.com"]
    # 修改默认的爬虫入口
    # start_urls = ["https://m.mms591.com"]
    start_urls = ["https://m.mms591.com/filter.php?q=dongwu_zhiwu-0-0-755-2"]

    def parse(self, response, **kwargs):
        # print(response.text)  # 打印页面源代码
        # 从页面源代码中拿到图片详情网址
        # 这里有多种方法进行解析,大家可以按照自己的思路来
        # 我这里先拿到每个图片所在li
        lis = response.xpath('//div[@class="am-list-news-bd"]/ul/li')
        for li in lis:
            href = li.xpath('./div/a/@href').extract_first()
            # 这里拿到的地址是不完整的,需要拼接完整的URL
            # print(href)  # '/dongwu-zhiwu/1015_he-ma.html'
            # 之前我们是用from urllib.parse import urljoin进行拼接
            # 但是scrapy中的response对象有相应的URL拼接方法
            detail_img = response.urljoin(href)
            # print(detail_img)  # https://m.mms591.com/dongwu-zhiwu/1023_qi-e.html

            # 向图片的详情地址发送请求
            # 之前我们说爬虫程序要么解析出具体的数据,传递给引擎,然后通过引擎传递给通道
            # 要么解析出新的URL,然后传递给引擎,引擎封装成request对象,再给调度器
            # 所以这里我们解析出了一个新的URL,那么就封装成request对象,
            # 至于引擎是怎么给调度器、怎么发送这个请求得到数据的不用我们关心
            req = scrapy.Request(
                url=detail_img,  # 要请求的地址
                method='get',  # 请求的方式
                # 这里是自定义一个解析函数
                # 请求返回的内容交给谁进行数据解析
                callback=self.parse_detail_page
            )
            # 把请求返回给引擎
            yield req
            break

        # 上面的过程只下载了一页图片,如果我们想下载多页图片,可以在这里进行
        # 可以一次性拿到所有分页的URL,然后协程或者for循环进行下载
        # 这里采取拿到“下一页”这个按钮的URL,然后一页一页的下载
        # 相当于不断地手动点击下一页这个按钮
        # 从页面中获取下一页按钮的URL
        # 这里的URL也是不完整的,需要拼接
        next_page_url = response.xpath(
            # a[contains(text(), "下一页")] 表示获取文本内容包含“下一页”的a标签
            '//ul[@data-am-widget="pagination"]/li/a[contains(text(), "下一页")]/@href'
        ).extract_first()
        print(next_page_url)
        if next_page_url:  # 如果有下一页
            yield scrapy.Request(
                url=response.urljoin(next_page_url),
                method='get',
                # 请求返回的又是一页新的有多个图片的页面,解析逻辑桶上面,所以调用parse方法
                callback=self.parse
            )

    def parse_detail_page(self, response):
        """
        在这个函数里对图片的详情页进行解析,这个方法是自定义的
        :param response: 请求详情页网址时返回的内容
        :return:
        """
        # print(response.text)
        # 拿到图片真正的下载地址
        img_url = response.xpath('//img[@class="mainimg"]/@src').extract_first()
        # print(img_url)
        title = response.xpath('//h3/text()').extract_first()
        # print(title)
        item = Caixin591Item()
        item['img_url'] = img_url
        item['title'] = title

        yield item  # 把具体的数据传递给管道

settings.py文件代码(删掉了没有用到的注释代码)

BOT_NAME = "caixin591"

SPIDER_MODULES = ["caixin591.spiders"]
NEWSPIDER_MODULE = "caixin591.spiders"

# Obey robots.txt rules
ROBOTSTXT_OBEY = True

ITEM_PIPELINES = {
   "caixin591.pipelines.Caixin591Pipeline": 300,
   "caixin591.pipelines.DownloadImgPipeline": 299
}

# 配置日志界别
LOG_LEVEL = 'WARNING'

# 配置保存图片的文件夹
IMAGES_STORE = './images'

# 要配置这个,否则图片管道下载图片的时候会报错:
# File (code: 301): Error downloading file from <GET http:...> referred in <None>
MEDIA_ALLOW_REDIRECTS = True

REQUEST_FINGERPRINTER_IMPLEMENTATION = "2.7"
TWISTED_REACTOR = "twisted.internet.asyncioreactor.AsyncioSelectorReactor"
FEED_EXPORT_ENCODING = "utf-8"

pipelines.py文件代码

import scrapy
from scrapy.pipelines.images import ImagesPipeline

class Caixin591Pipeline:
    def process_item(self, item, spider):
        return item


# 下载图片
# 这里利用图片管道完成图片下载操作
# 注意要在settings文件中配置保存文件的文件夹
class DownloadImgPipeline(ImagesPipeline):
    # 下面三个方法都是重写ImagesPipeline类中的

    def get_media_requests(self, item, info):
        # 本方法负责发送请求进行下载
        # item 就是爬虫程序传递过来的数据
        # img_url是图片真正的下载地址,发送请求后会返回图片的字节信息
        # 而把图片的字节存储起来这一操作我们不需要关心
        # 只需要实现这三个方法就可以完成下载图片到本地这一需求
        req = scrapy.Request(url=item['img_url'], method='get')
        return req  # 把请求返回给引擎

        # 上面是封装一个请求然后下载一次,应该也可以先封装好所有请求然后一起下载
        # 但是我没尝试过,感兴趣的可以试一试

    def file_path(self, request, response=None, info=None, *, item=None):
        # 本方法负责提供图片文件的存储路径
        # request这里对应着上面方法get_media_requests中的req
        # 一个图片对应一个req
        # 和以前一样,我们以URL的最后一部分命名图片
        # 请求的URL可以通过request.url获取
        file_name = request.url.split('/')[-1]
        return f'img/{file_name}'  # 返回图片文件的存储路径

    def item_completed(self, results, item, info):
        # 本方法可以拿到文件的详细信息
        # 可以自己打印出来看看具体有什么东西
        # print(results)
        # print(item)
        # print(info)
        pass

items.py文件代码

import scrapy


class Caixin591Item(scrapy.Item):
    img_url = scrapy.Field()
    title = scrapy.Field()

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

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

相关文章

微信小程序开发系列(八)·微信小程序页面的划分以及轮播图区域的绘制和图片的添加

目录 1. 划分页面结构 2. 轮播图区域绘制 3. 轮播图图片添加 1. 划分页面结构 最终我们想达到如下效果&#xff1a; 其页面分为四层结构&#xff0c;因此我们需要配置四块view&#xff0c;代码如下&#xff1a; <!-- view 小程序提供的容器组件&#xff0c;可以当成…

算法沉淀——动态规划之其它背包问题与卡特兰数(leetcode真题剖析)

算法沉淀——动态规划之其它背包问题与卡特兰数 二维费用的背包问题01.一和零02.盈利计划 似包非包组合总和 Ⅳ 卡特兰数不同的二叉搜索树 二维费用的背包问题 01.一和零 题目链接&#xff1a;https://leetcode.cn/problems/ones-and-zeroes/ 给你一个二进制字符串数组 strs…

Springboot自动装配的原理

Springboot自动装配 1.前言2.EnableAutoConfiguration3.AutoConfigurationImportSelector4.spring.factories5.总结 1.前言 为什么springboot能够开箱即用&#xff0c;就是由于Springboot的自动装配。我们知道项目启动的方法上面都有一个注解SpringBootApplication&#xff0c…

武汉灰京文化:游戏市场推广与用户增长的成功典范

作为游戏行业的明星企业&#xff0c;武汉灰京文化在市场推广和用户增长方面的成功经验备受瞩目。他们以创造性和独特性的市场营销策略&#xff0c;成功吸引了大量用户。这不仅提高了其游戏的知名度&#xff0c;还为公司带来了持续的增长。这一成功模式不仅对公司自身有益&#…

计算机中msvcp140.dll,丢失怎么修复与解决

一、msvcp140.dll20个软件环境 msvcp140.dll文件是许多软件运行环境的组成部分&#xff0c;通常与Microsoft Visual C Redistributable关联。以下是可能使用该文件的软件环境&#xff1a; 微软办公软件&#xff1a;如Microsoft Office套件&#xff0c;包括Word、Excel、Power…

仓库福音!三防工业手机:远程RFID和条形码扫描仪的优势

在仓库中&#xff0c;由于堆货量众多&#xff0c;仓库管理员想要细分货物的种类十分困难&#xff0c;因此保持准确的库存记录至关重要&#xff0c;这样公司就不会导致货物积压。资产跟踪也可能是繁琐的任务之一&#xff0c;会对公司产生重大影响。没有为特定部件记录准确或错误…

[Echart]图谱中的富文本标签

[Echart]图谱中的富文本标签 series-graph.links.label.rich option {title: {text: Basic Graph},tooltip: {},animationDurationUpdate: 1500,animationEasingUpdate: quinticInOut,series: [{type: graph,// layout: force,symbolSize: 50,roam: true,label: {show: tru…

C及C++每日练习(2)

1.选择&#xff1a; 1.使用printf函数打印一个double类型的数据&#xff0c;要求&#xff1a;输出为10进制&#xff0c;输出左对齐30个字符&#xff0c;4位精度。以下哪个选项是正确的&#xff1f; A.%-30.4e B.%4.30e C.%-30.4f D.%-4.30 在上一篇文章中&#xff0c;提到了…

社科院与杜兰大学金融管理硕士——精心准备,只为那一刻的刚刚好

我们每个人都是夜空中独一无二的那颗星&#xff0c;静静地照耀&#xff0c;期待着照亮自己的宇宙。我们的每一步前行&#xff0c;都像是星尘累积&#xff0c;汇聚成璀璨的光轨&#xff0c;照亮未来的道路。正如我们现在努力申请的社科院与杜兰大学金融管理硕士项目&#xff0c;…

深圳/广州/厦门/上海/宁波/义乌2024最新跨境电商展计划表发布!

全国各城市2024年跨境电商年度效果好的跨境展会排期表来了&#xff0c;具体展会活动议程根据组委会实际公示结果为准。 励佳展览(上海)有限公司是一家专业组织、代理国内跨境电商行业展会会展公司&#xff0c;励佳展览拥有高素质的员工队伍&#xff0c;广泛的客户资源&#xf…

香港媒体发稿:【超值1元港媒发稿套餐】推广技巧-华媒舍

在当今竞争激烈的市场中&#xff0c;品牌的推广是企业取得成功的关键。众多的宣传渠道中&#xff0c;香港媒体发稿无疑是一种高效的品牌推广方式。本文将为您介绍《超值1元港媒发稿套餐》的各个组成部分&#xff0c;以及它如何帮助您实现品牌的腾飞。 1. 1元套餐的优势 1元港媒…

田宏斌:以人为本的听力健康管理实践经验 | 演讲嘉宾公布

一、助辅听器材Ⅲ分论坛 助辅听器材Ⅲ分论坛将于3月28日同期举办&#xff01; 听力贯穿人的一生&#xff0c;听觉在生命的各个阶段都是至关重要的功能&#xff0c;听力问题一旦出现&#xff0c;会严重影响生活质量。助辅听器材能有效提高生活品质。在这里&#xff0c;我们将分享…

逆变器专题(15)-弱电网下的LCL逆变器控制以及谐振峰问题(2)

相应仿真原件请移步资源下载 LCL滤波器 LCL滤波器因其本身为一个二阶系统&#xff0c;其本身就会引发谐振&#xff0c;导致相应谐振频率处的增益得到放大&#xff0c;进而产生谐波等问题&#xff1b;另一方面&#xff0c;在弱电网下&#xff0c;逆变器会与电网阻抗发生耦合&am…

IP劫持的危害及应对策略

随着互联网的发展&#xff0c;网络安全问题日益凸显&#xff0c;其中IP劫持作为一种常见的网络攻击手段&#xff0c;对个人和企业的信息安全造成了严重的威胁。IP数据云将分析IP劫持的危害&#xff0c;并提出相应的应对策略。 IP地址查询&#xff1a;IP数据云 - 免费IP地址查询…

多张gif怎么拼接?三步教你在线拼接gif

GIF拼图常用于制作表情包、动态海报、广告宣传等场景。它可以将多个图像或动画元素组合在一起&#xff0c;形成一个有趣、生动的动画效果&#xff0c;吸引观众的注意力&#xff0c;并传达特定的信息或情感。要将多个GIF动图拼接在一张图像上&#xff0c;要使用适合的gif动画图片…

奥壹科技推出婚恋相亲系统免费软件,旨在扶持创业者降低行业入门门槛

(广州, 2024年3月6日星期三) - 随着婚恋市场的日益增长&#xff0c;奥壹科技宣布推出其旗下奥壹云相亲系统的全新免费版(OEyun Free V1.0)。该公司表示&#xff0c;该举措旨在通过降低创业门槛&#xff0c;为有意进入婚恋行业的创业者及小型企业提供支持&#xff0c;从而进一步…

Java继承与多态:深入理解继承、组合和多态的精髓!

Java继承与多态&#xff1a;深入理解继承、组合和多态的精髓&#xff01; 引言 欢迎来到这篇关于Java继承与多态的博客&#xff01;在Java编程中&#xff0c;继承与多态是两个非常重要的概念&#xff0c;它们为我们构建灵活而高效的代码提供了强大的支持。本文将深入探讨Java继…

2024年冲刺年薪40w,Android岗面试

一个程序员&#xff0c;如果不想35 岁被淘汰&#xff0c;请把它当成一种信仰&#xff01; 25岁&#xff0c;一个北漂程序员&#xff0c;入职三年&#xff0c;Android中级工程师&#xff0c;月薪15k&#xff0c;965的工作经常干成996&#xff0c;比起老家的同龄人&#xff0c;我…

校招中的“熟悉linux操作系统”一般是指达到什么程度?

校招中的“熟悉linux操作系统”一般是指达到什么程度&#xff1f; 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「Linux的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&am…

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:PanGesture)

拖动手势事件&#xff0c;当滑动的最小距离超过设定的最小值时触发拖动手势事件。 说明&#xff1a; 从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 接口 PanGesture(value?: { fingers?: number; direction?: PanDir…
最新文章