scrapy自带文件下载器,实现多层级目录结构的存储

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: 概scrapy既然是一款强大的爬虫框架,自然也实现了图片和文件的下载,FilesPipeline、ImagesPipeline分别是图片和文件的下载器,image也是文件的一种为什么还要单独提供一个image下载器?这是因为图片下载器还提供了一些额外方法:缩略图生成、图片过滤;今天就来介绍这两款特殊的下载器。
  概

scrapy既然是一款强大的爬虫框架,自然也实现了图片和文件的下载,FilesPipeline、ImagesPipeline分别是图片和文件的下载器,image也是文件的一种为什么还要单独提供一个image下载器?这是因为图片下载器还提供了一些额外方法:缩略图生成、图片过滤;今天就来介绍这两款特殊的下载器。


使用方法

1.常规的使用方法是首先在item中定义关键字,images和files关键字段如下:

当然其中字段还可以增加可以加title、Word等自定义字段


2.在setting.py中启用下载管道

ITEM_PIPELINES = {    'scrapy.pipelines.files.FilesPipeline': 1,    'scrapy.pipelines.images.ImagesPipeline': 2}


上面启用的是内部的下载器,如果实现了自定义需要将路径替换为自定义的下载器


3.在爬虫主程序中传递url,yield item{'file_urls':[url1, url2,`````````]}



下面将从源码和案例来分析具体如何使用

注:file下载和image下载的原理是一样的,只是images下载图片可以配置,所以我们分析file的源码,讲image的实例


FilesPipeline源码

FilesPipeline文件位于:

scrapy.pipelines.files

源码有点多,我们只需要关注两个地方,一个是下载的实现一个是下载的文件命名

class FilesPipeline(MediaPipeline):
    """Abstract pipeline that implement the file downloading

    This pipeline tries to minimize network transfers and file processing,
    doing stat of the files and determining if file is new, uptodate or
    expired.

    `new` files are those that pipeline never processed and needs to be
        downloaded from supplier site the first time.

    `uptodate` files are the ones that the pipeline processed and are still
        valid files.

    `expired` files are those that pipeline already processed but the last
        modification was made long time ago, so a reprocessing is recommended to
        refresh it in case of change.

    """



    ### Overridable Interface
    def get_media_requests(self, item, info):
        return [Request(x) for x in item.get(self.files_urls_field, [])]



    def file_path(self, request, response=None, info=None):
        ## start of deprecation warning block (can be removed in the future)
        def _warn():
            from scrapy.exceptions import ScrapyDeprecationWarning
            import warnings
            warnings.warn('FilesPipeline.file_key(url) method is deprecated, please use '
                          'file_path(request, response=None, info=None) instead',
                          category=ScrapyDeprecationWarning, stacklevel=1)

        # check if called from file_key with url as first argument
        if not isinstance(request, Request):
            _warn()
            url = request
        else:
            url = request.url

        # detect if file_key() method has been overridden
        if not hasattr(self.file_key, '_base'):
            _warn()
            return self.file_key(url)
        ## end of deprecation warning block

        media_guid = hashlib.sha1(to_bytes(url)).hexdigest()  # change to request.url after deprecation
        media_ext = os.path.splitext(url)[1]  # change to request.url after deprecation
        return 'full/%s%s' % (media_guid, media_ext)

其中get_media_requests用于解析item中的file_urls字段里的url列表,并构造成请求

file_path是给文件命名,使用的url的sha1散列值也我们只需要让return返回我们想要的文件名即可。

图片下载的关键源码同上。

image自定义下载路径及文件名实例

目标:下载图片按照原网站的文件目录组织结构、文件名按照原网站命名,本地生成缩略图,小于200*200以下的文件。

目标明确就开工,先创建一个项目模板,然后开始做我们的案例。

案例图片是类似于妹子图的组图网站,不过内容不宜展示,并且网站也被封了,就不在其中展示敏感内容,这是以前的案例。

items.py 定义字段

import scrapy


class RgspoiderItem(scrapy.Item):
    image_urls = scrapy.Field()
    images = scrapy.Field()
    title = scrapy.Field()
    word = scrapy.Field()


title是分类名字,Word是组图的专题名字, 组图下载后将按照分类-专题-组图的目录结构存储,是三层结构。

Spider.py 爬虫主程序

# -*- coding: utf-8 -*-
import scrapy
from ..items import RgspoiderItem


class PicturnSpider(scrapy.Spider):

    name = 'picturn'
    allowed_domains = ['xxxxxx.com']
    start_urls = ['http://xxxxxx/index.html']

    def parse(self, response):
        select = response.xpath('//*[@id="body"]/div[2]/ul//li')
        for i in select:
            URL = i.xpath('a/@href').extract()[0]
            title = i.xpath('a/text()').extract()[0# 获取分类名字并专递给解析函数
            yield scrapy.Request(
                response.urljoin(URL), callback=self.parse_ml, meta={'title': title})

    def parse_ml(self, response):
        mulu = response.xpath('//li[@class="zxsyt"]/a')
        title = response.meta['title']
        for i in mulu:
            urls = i.xpath('@href').extract()[0]
            word = i.xpath('text()').extract()[0]
            yield scrapy.Request(
                response.urljoin(urls), callback=self.parse_pict,
                meta={'word': word, 'title': title}) # 将分类名字及其组图标题在传递给解析函数

        next_url = response.xpath('//font[@class="PageCss"]/..//a/@href').extract()
        for nuel in next_url:
            title = response.meta['title']
            yield scrapy.Request(response.urljoin(nuel), callback=self.parse_ml,
                                 meta={'title': title})  

    def parse_pict(self, response):
        items = RgspoiderItem()
        items['title'] = response.meta['title']
        items['word'] = response.meta['word']
        pict = response.xpath('//div[@class="temp23"]//a/@href').extract()
        items['image_urls'] = pict  # 构造item数据传递给下载器,item包含了单张图片,并附带该图片所在分类和组图标题,后面自动归类
        yield items

主程序实现了三层解析,第一层获取所有分类连接及其分类名字,第二层获取所有分类下的组图连接及其组图标题,第三层获取组图下的所有图片连接并将连接、分类、标题传递给下载器


pipeline.py 复写imagespipeline

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

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


class RgspoiderPipeline(ImagesPipeline):

    def get_media_requests(self, items, info):
        print(items)
        title = items['title']
        word = items['word']
        for image_url in items['image_urls']:
            yield scrapy.Request(image_url, meta={'title': title, 'word': word}) # 继续传递分类、标题

    def file_path(self, request, response=None, info=None):
        # 按照full\分类\标题\图片合集命名
        filename = r'full\%s\%s\%s' % (request.meta['title'], request.meta['word'], request.url[-6:])
        return filename


现在get_media_requests狗仔request请求,然后在file_path中解析构造的request请求中的meta字段来构建文件名字,并取url的后几个字符串作为组图中单张图片的名字。


setting.py

ITEM_PIPELNES={
    'rgSpoider.pipelines.RgspoiderPipeline': 1,
}

IMAGES_STORE = 'D://A' # 问价存放的根目录
IMAGES_THUMBS = {
'thumbnail': (50, 50) # 生成缩略图标签及其尺寸
}
IMAGES_MIN_WIDTH = 200 # 过滤宽度小于200
IMAGES_MIN_HEIGHT = 300 # 过滤高度小于300


END
相关文章
|
6月前
|
数据采集 NoSQL 中间件
python-scrapy框架(四)settings.py文件的用法详解实例
python-scrapy框架(四)settings.py文件的用法详解实例
62 0
|
6月前
|
存储 数据采集 数据库
python-scrapy框架(三)Pipeline文件的用法讲解
python-scrapy框架(三)Pipeline文件的用法讲解
131 0
|
6月前
|
存储 数据采集 JSON
Scrapy爬虫数据存储为JSON文件的解决方案
Scrapy爬虫数据存储为JSON文件的解决方案
|
数据采集 搜索推荐 前端开发
23、 Python快速开发分布式搜索引擎Scrapy精讲—craw母版l创建自动爬虫文件—以及 scrapy item loader机制
转: http://www.bdyss.cn http://www.swpan.cn 用命令创建自动爬虫文件 创建爬虫文件是根据scrapy的母版来创建爬虫文件的 scrapy genspider -l  查看scrapy创建爬虫文件可用的母版 Available templates:母版说明  ...
1176 0
|
数据采集 前端开发 搜索推荐
20、 Python快速开发分布式搜索引擎Scrapy精讲—编写spiders爬虫文件循环抓取内容—meta属性返回指定值给回调函数—Scrapy内置图片下载器
编写spiders爬虫文件循环抓取内容 Request()方法,将指定的url地址添加到下载器下载页面,两个必须参数,  参数:  url='url'  callback=页面处理函数  使用时需要yield Request() parse.
1322 0
|
数据采集 搜索推荐 Python
18、 Python快速开发分布式搜索引擎Scrapy精讲—Scrapy启动文件的配置—xpath表达式
【百度云搜索:http://www.bdyss.cn】 【搜网盘:http://www.swpan.cn】 我们自定义一个main.py来作为启动文件 main.py #!/usr/bin/env python # -*- coding:utf8 -*- from scrapy.
904 0
|
存储 JSON 数据格式
scrapy框架-将数据写入json文件
使用背景 有时候为了做测试,不想去数据库设置字段,设置musql字段实在是太麻烦了,这种情况下可以先把存储到json文件中,并观察数据的正确性,如果数据没问题了,再改成mysql存储即可。
1441 0
|
存储 关系型数据库 数据库
scrapy爬取免费代理IP存储到数据库构建自有IP池
以抓取西刺代理网站的高匿IP并存储到mysql数据库为例 西刺网:http://www.xicidaili.com/nn/ 运行环境:scrapy1.0.3 python2.7.10 需要安装MySQLdb模块  pip install mysql-python spider的编写步骤:.
3052 0
|
20天前
|
数据采集 存储 JSON
Python网络爬虫:Scrapy框架的实战应用与技巧分享
【10月更文挑战第27天】本文介绍了Python网络爬虫Scrapy框架的实战应用与技巧。首先讲解了如何创建Scrapy项目、定义爬虫、处理JSON响应、设置User-Agent和代理,以及存储爬取的数据。通过具体示例,帮助读者掌握Scrapy的核心功能和使用方法,提升数据采集效率。
63 6