Scrapy框架实现文件下载功能

鳄鱼君

发表文章数:642

热门标签

, , , ,

Vieu四代商业主题

高扩展、安全、稳定、响应式布局多功能模板。

¥69 现在购买
首页 » Python » Scrapy框架实现文件下载功能

在使用Scrapy框架爬虫的时候,很多时候都是在爬取数据,但有的时候也需要爬取文件,例如图片、音视频、文本文件,虽然我们可以自定义代码搞定这些问题,但要知道Scrapy为我们提供了一个可重用的Item Pipelines,叫做Media Pipeline。Media Pipeline分为Files Pipeline和Images Pipeline。:

(1)能避免重新下载已下载过的数据。
(2)可以指定下载后保存的路径。
Images Pipeline为处理图片提供了额外的功能:
(1)将所有下载的图片格式转换成普通的JPEG并使用RGB颜色模式。
(2)生成缩略图。
(3)检查图片的宽度和高度,确保它们满足最小的尺寸限制。

Files Pipeline

Pipeline同时会在内部保存一个被调度下载的URL列表,然后将包含相同媒体的链接关联到这个队列上来,从而防止重复下载。这里随便找几个文件下载URL地址:

# zip压缩包
https://github.com/scrapy/scrapy/archive/master.zip
# MP3音乐


# jpg图片
https://icon.qiantucdn.com/20200527/01fc9da19898637c71a676cb53cc58d32

创建Scrapy项目,需要在settings.py文件进行配置:

# 设置保存路径
FILES_STORE='D:\\files\\'

# 设置请求头
DEFAULT_REQUEST_HEADERS = {
  'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
  'Accept-Language': 'en',
  'User-Agent': 'User-AgentMozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Firefox/78.0'

}

# 配置DownloadFile管道
ITEM_PIPELINES = {
   'file_down.pipelines.FileDownPipeline': 300,
   'file_down.pipelines.DownloadFile': 1,
}

其它配置按需添加,这里只配置重要的文件下载信息。接着定义items.py管道类:

import scrapy


class FileDownItem(scrapy.Item):
    file_url = scrapy.Field()
    file_name = scrapy.Field()
    pass

最后是spider.py爬虫文件:

import scrapy
from file_down.items import FileDownItem

class FileSpider(scrapy.Spider):
    name = 'file'
    # QQ音乐
    start_urls = [
        'http://isure.stream.qqmusic.qq.com/C400001VIcIs35VE9a.m4a?guid=1667117097&vkey=6273C1FCA41658AD85D888D4839BE654C7CB7AB60FB98AC4B3EA39202930090746A768A168A05F47FD67C28FDE12F1C392605A3483723732&uin=0&fromtag=66'
    ]

    def parse(self, response):
        # 下载方法一
        # with open(self.settings.get('FILES_STORE')+'.mp3', 'wb') as f:
        #     f.write(response.body)

        # 下载方法
        item = FileDownItem()
        item['file_name'] = ['file.zip', 'file.mp3', 'file.jpg']
        item['file_url'] = ['https://github.com/scrapy/scrapy/archive/master.zip',
                            'https://webfs.yun.kugou.com/202007120912/1ed2ca496f8f1a294dd2ee8d3be293b2/G233/M09/1B/1D/yZQEAF8HAZSAZCvyADpYeejGt2g394.mp3',
                            'https://icon.qiantucdn.com/20200527/01fc9da19898637c71a676cb53cc58d32']

        return item

方法一比较简单,方法二是将文件链接和文件名写入Items对象,然后将Items传到Item Pipeline实现文件下载。

from scrapy.pipelines.files import FilesPipeline
from scrapy.pipelines.images import ImagesPipeline
import scrapy
from scrapy.utils.project import get_project_settings
settings = get_project_settings()


class FileDownPipeline:
    # 自动生成的管道
    def process_item(self, item, spider):
        return item


class DownloadFile(FilesPipeline):
    # 重写get_media_requests
    def get_media_requests(self, item, info):
        # 遍历item['file_url']
        for index, url in enumerate(item['file_url']):
            yield scrapy.Request(url, meta={'name': item['file_name'][index]})

    # 重写file_path,设置下载文件名
    def file_path(self, request, response=None, info=None):
        # request.meta['name']来自get_media_requests方法的meta
        file_name = settings['FILES_STORE'] + request.meta['name']
        return file_name

实现流程如下:
(1)、 在Spider中爬取一个Item后,将相应的文件URL放入file_urls字段中。
(2)、 Item被返回之后就会转交给Item Pipeline。
(3)、 当这个Item到达FilesPipeline时,在file_urls字段中的URL列表会通过标准的Scrapy调度器和下载器来调度下载,并且优先级很高,在抓取其他页面前就被处理。而这个Item会一直在这个Pipeline中被锁定,直到所有的文件下载完成。
(4)、 当文件被下载完之后,结果会被赋值给另一个files字段。这个字段包含一个关于下载文件的新字典列表,比如下载路径、源地址、文件校验码。files里面的顺序和file_url的顺序是一致的。若下载出错,则不会出现在这个files中。

Images Pipeline

ImagesPipeline的使用跟FilesPipeline差不多,不过使用的字段名不一样,image_urls用于保存图片的URL地址,使用ImagesPipeline的好处是可以通过配置来提供额外的功能,比如生成文件缩略图、通过图片大小过滤需要下载的图片等。ImagesPipeline使用Pillow来生成缩略图以及转换成标准的JPEG/RGB格式。这里不再详细介绍了!

未经允许不得转载:作者:鳄鱼君, 转载或复制请以 超链接形式 并注明出处 鳄鱼君
原文地址:《Scrapy框架实现文件下载功能》 发布于2020-07-11

分享到:
赞(0) 赏杯咖啡

评论 抢沙发

7 + 8 =


文章对你有帮助可赏作者一杯咖啡

支付宝扫一扫打赏

微信扫一扫打赏

Vieu4.6主题
专业打造轻量级个人企业风格博客主题!专注于前端开发,全站响应式布局自适应模板。
切换注册

登录

忘记密码 ?

您也可以使用第三方帐号快捷登录

Q Q 登 录
微 博 登 录
切换登录

注册