Scrapy ImagesPipeline 圖片下載中間件的BUG

中秋啦,不知道各位技術大佬們都在忙些什麼呢。不管怎樣,還是祝大家中秋快樂!

最近一週在學習scrapy框架,今天在使用ImagesPipeline圖片下載中間件的時候遇到了一個奇葩的BUG。這個BUG與可能與Scrapy的異常處理相關,由於沒有查看Scrapy的異常處理代碼,所以這裏說一下表面現象,其實是自己太菜了,不知道從哪裏開始看。。

這裏先貼上錯誤代碼:

class PicDownloadPipeline(ImagesPipeline):

    def get_media_requests(self, item, info):
        yield scrapy.Request(item['image'], meta={'name': item['name']})

    def file_path(self, request, response=None, info=None):
        print(response, type(response))
        print(response.meta)
        print(request.url, request.meta)
        name = request.meta['name']
        print('############### 2 ############################')
        cate = re.findall('(.+?)高清桌面壁紙.+', name)[0]
        path = os.path.abspath('.')
        path = ''.join((path, os.sep, 'image', os.sep, cate))
        if not os.path.exists(path):
            os.makedirs(path)
        path = ''.join((path, os.sep, name))
        print(path)
        return path

其實我想要做的很簡單,就是在下載圖片的時候希望能夠分類存放,而不是放在一個文件夾內。實現也很簡單,直接繼承PicDownloadPipeline類,然後重載裏面的兩個函數即可,如上面代碼所示,第一個函數是返回下載圖片的請求,並且把圖片的名字帶上。 第二個函數主要作用是返回每張圖片應該所在的路徑。

之前所說的BUG就是再這個file_path這個函數裏,不知道大家看什麼蹊蹺沒有,file_path函數需要用到get_media_requests函數返回的meta屬性,通過該屬性,我可以獲取圖片的名字。然而,file_path有三個參數,meta屬性放在request參數當中,我在寫程序的時候使用了Pycharm的自動補齊,但是卻錯誤的選擇了response這個參數。也就是說file_path會從response參數當中讀取meta屬性,然而,Scrapy在調用file_path函數的時候並沒有給resonse傳參進來,即response是NoneType類型,也就是說response沒有meta屬性。最最最精彩的部分就是這裏了,講道理我在運行程序的時候Python解釋器應該報錯纔對(因爲我訪問了一個不存在的屬性),需要注意的是scrapy的LOG_LEVEL我使用了默認的DEBUG等級,但是不管我使用什麼LOG等級,這裏是一個錯誤,都應該報錯纔對。  遺憾的是,python解釋器並沒有報出任何的錯誤。在Pythone解釋器執行到file_path方法的第二行,也就是print(response.meta)的時候直接退出了該函數,它悄悄了走了,不帶走一片雲彩~~~~~~~

這個錯誤我花了一個小時才排查到這裏,感覺非常的神奇,就記錄了下來。不知道大佬們什麼看法,講道理這個異常會向上傳遞,但是Scrapy這個框架不知道爲什麼沒有把這個錯誤報出來。 如果有大佬對Scrapy比較瞭解,能否賜教一下,不勝感激!

錯誤的log信息:可以看到,python解釋器執行到了第二行之後程序直接退出,後面的內容沒有打印。

正常的log信息:把response改爲request之後程序可以正常運行,圖片也可以正常保存。


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章