Error 302 descargando archivo en Scrapy

¿Por qué estoy recibiendo este error?

[scrapy] WARNING: File (code: 302): Error downloading file from <GET  referred in  

La URL parece descargar sin problemas en mi navegador y un 302 es simplemente una redirección. ¿Por qué no scrapy simplemente seguir la redirección para descargar el archivo?

 process = CrawlerProcess({ 'FILES_STORE': 'C:\\Users\\User\\Downloads\\Scrapy', 'USER_AGENT': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)', 'ITEM_PIPELINES': {'scrapy.pipelines.files.FilesPipeline': 1}, }) process.crawl(MySpider) process.start() # the script will block here until the crawling is finished 

Mi solución es usar solicitudes para enviar primero una solicitud http, basándome en el código de estado para elegir qué url descargar, ahora puede poner la url en file_urls o su nombre personalizado.

 import requests def check_redirect(url): response = requests.head(url) if response.status_code == 302: url = response.headers["Location"] return url 

o puede ser que puede utilizar archivos personalizados pipeline

 class MyFilesPipeline(FilesPipeline): def handle_redirect(self, file_url): response = requests.head(file_url) if response.status_code == 302: file_url = response.headers["Location"] return file_url def get_media_requests(self, item, info): redirect_url = self.handle_redirect(item["file_urls"][0]) yield scrapy.Request(redirect_url) def item_completed(self, results, item, info): file_paths = [x['path'] for ok, x in results if ok] if not file_paths: raise DropItem("Item contains no images") item['file_urls'] = file_paths return item 

Utilicé otra solución aquí Scrapy i / o block al descargar archivos

La raíz del problema parece ser este código en las pipelines/media.py :

  def _check_media_to_download(self, result, request, info): if result is not None: return result if self.download_func: # this ugly code was left only to support tests. TODO: remove dfd = mustbe_deferred(self.download_func, request, info.spider) dfd.addCallbacks( callback=self.media_downloaded, callbackArgs=(request, info), errback=self.media_failed, errbackArgs=(request, info)) else: request.meta['handle_httpstatus_all'] = True dfd = self.crawler.engine.download(request, info.spider) dfd.addCallbacks( callback=self.media_downloaded, callbackArgs=(request, info), errback=self.media_failed, errbackArgs=(request, info)) return dfd 

Específicamente, la línea que establece handle_httpstatus_all en True desactiva el middleware de redirección para la descarga, lo que desencadena el error. Voy a preguntar en el github scrapy por las razones de esto.

Si la redirección es el problema, debe agregar lo siguiente en su configuración.py :

 MEDIA_ALLOW_REDIRECTS = True 

Fuente: Permitir redirecciones en Scrapy.