關(guān)于scrapy下載文件重命名的辦法以及對應(yīng)url沒有文件后綴的辦法

scrapy中負責(zé)下載文件的是class MyFilesPipeline(FilesPipeline)

  • 其中負責(zé)下載文件的方法是
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)

我們可以很清楚地看到 因為是下載的是文件,所以默認的response參數(shù)是為None的,因為一般來講,文件的response就是我們下載的。我們待會說明response為None的壞處。
所以,修改文件名的辦法就很顯然了。在return處做文章:return 的文件路徑,用了兩個變量media_guidmedia_ext

  1. 其中media_guid是一個將url進行哈希加密的文件,可以修改。
  2. 另一個media_ext是什么呢: os.path.splitext(url)[1]這個函數(shù)是將url作切割,不同于py里的split函數(shù),這個函數(shù)只返回兩部分,示例如下

import os
path_01='D:/User/wgy/workplace/data/notMNIST_large.tar.gar'
path_02='D:/User/wgy/workplace/data/notMNIST_large'
root_01=os.path.splitext(path_01)
root_02=os.path.splitext(path_02)
print(root_01)
print(root_02)
結(jié)果:
('D:/User/wgy/workplace/data/notMNIST_large.tar', '.gar')
('D:/User/wgy/workplace/data/notMNIST_large', '')

可以看到,就是在scrapy里這個函數(shù)就是獲取后綴的。
綜上,文件名可以在這邊修改。

但是有一個問題,如果想要下載的文件的url是經(jīng)過重定向,或者對應(yīng)的url沒有后綴呢。
由于網(wǎng)頁一般會將想要請求的文件類型放在response的頭部信息 content-type里,我們可以通過獲取content-type信息,在進行相應(yīng)的操作。這樣我們就需要找到調(diào)用file_path的函數(shù)

    def file_downloaded(self, response, request, info):
        path = self.file_path(request, response=response, info=info)
        buf = BytesIO(response.body)
        checksum = md5sum(buf)
        buf.seek(0)
        self.store.persist_file(path, buf, info)
        return checksum
  • file_downloaded里,第一行就是調(diào)用了file_path函數(shù),而且根據(jù)命名規(guī)則,十分清晰。 我們只要對上述path 做一定的修改即可。
  • 因為file_downloaded是對文件進行下載,而file_path是對文件進行存儲路徑的安排的,所以file_downloaded這里的response我們是可以獲取相關(guān)信息的。
    獲取重定向后文件后綴的方法為:
    response.headers.get('Content-Disposition') 或者 response.headers.get('Content-Type') ,如果獲取不到,可以改成content-disposition 或者 content-type,舉個例子
    content-disposition可能得到的是這個:
    Content-Disposition: inline;filename=Vet%20Contract%20for%20Services.pdf,直接正則獲取最后的文件路徑

\color{red}{Content-Disposition} 是一個擴展協(xié)議,對得到的內(nèi)容進行正則處理后,可以得到后綴,一般建議先用這個。但有的并不支持這種協(xié)議
\color{red}{Content-Type}一般網(wǎng)站都是支持的,但是它返回的文件類型可能沒法直接使用,所以建議先使用上面的那個

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評論 19 139
  • 本文包括:1、文件上傳概述2、利用 Commons-fileupload 組件實現(xiàn)文件上傳3、核心API——Dis...
    廖少少閱讀 12,742評論 5 91
  • Spring Web MVC Spring Web MVC 是包含在 Spring 框架中的 Web 框架,建立于...
    Hsinwong閱讀 22,931評論 1 92
  • 我的第一任領(lǐng)導(dǎo),非常犀利。他的思路敏捷而清晰,做事務(wù)實而高效,永遠沒有廢話,永遠雷厲風(fēng)行。和他共事,絕對不會輕松。...
    幸福堂閱讀 275評論 0 0
  • 前段時間在“阿文來了”看到這本書----《顛覆平庸》。在一疊書籍中一眼挑中了它,淺嘗了一下,發(fā)現(xiàn)它是我的菜...
    小丸682閱讀 330評論 2 3

友情鏈接更多精彩內(nèi)容