2012-10-18 74 views
3

我有一個定義網站結構的鏈接數組。雖然從這些鏈接下載圖像,我希望同時放在一個文件夾結構,下載的圖片類似網站的結構,而不是僅僅將其重命名(如Scrapy image download how to use custom filename回答)Scrapy:根據下載圖像的URL從下載的圖像中創建文件夾結構

我對相同的代碼是這樣的:

class MyImagesPipeline(ImagesPipeline): 
    """Custom image pipeline to rename images as they are being downloaded""" 
    page_url=None 
    def image_key(self, url): 
     page_url=self.page_url 
     image_guid = url.split('/')[-1] 
     return '%s/%s/%s' % (page_url,image_guid.split('_')[0],image_guid) 

    def get_media_requests(self, item, info): 
     #http://store.abc.com/b/n/s/m 
     os.system('mkdir '+item['sku'][0].encode('ascii','ignore')) 
     self.page_url = urlparse(item['start_url']).path #I store the parent page's url in start_url Field 
     for image_url in item['image_urls']: 
      yield Request(image_url) 

它創建所需的文件夾結構,但是當我深入到文件夾中時,發現文件已放在文件夾中。

我懷疑是因爲「get_media_requests」和「image_key」函數可能異步執行,因此「page_url」的值會在「image_key」函數使用之前發生變化。

+0

將計算蜘蛛路徑和傳遞路徑作爲項目屬性更準確? – dm03514

+0

@ dm03514我有所需的路徑作爲項屬性,但是,我無法訪問「image_key」函數中的「item」對象 –

+0

@GauravToshniwal我有疑問。我看不到任何代碼顯示文件夾正在創建,任何想法如何內部工作? – igaurav

回答

1

異步項目處理通過管道內的self阻止使用類變量是絕對正確的。您將有您的路徑保存在每一個請求,並覆蓋了幾個方法(未經測試):

def image_key(self, url, page_url): 
    image_guid = url.split('/')[-1] 
    return '%s/%s/%s' % (page_url, image_guid.split('_')[0], image_guid) 

def get_media_requests(self, item, info): 
    for image_url in item['image_urls']: 
     yield Request(image_url, meta=dict(page_url=urlparse(item['start_url']).path)) 

def get_images(self, response, request, info): 
    key = self.image_key(request.url, request.meta.get('page_url')) 
    ... 

def media_to_download(self, request, info): 
    ... 
    key = self.image_key(request.url, request.meta.get('page_url')) 
    ... 

def media_downloaded(self, response, request, info): 
    ... 
    try: 
     key = self.image_key(request.url, request.meta.get('page_url')) 
    ... 
+0

感謝您的解決方案。我已經測試它迄今爲止很好!同一項目或同一請求中的所有圖像將存儲在相同路徑(文件夾)中。 – EeE

+0

@ steven-almeroth,代碼中顯示的創建文件夾在哪裏?你能解釋一下嗎? – igaurav

+0

'image_key()'返回文件夾名稱,它可以是任何你想要的。 –