【问题标题】:Error 302 Downloading File in Scrapy在 Scrapy 中下载文件时出现错误 302
【发布时间】:2016-05-21 21:07:30
【问题描述】:

为什么我会收到这个错误?

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

该 URL 似乎在我的浏览器中下载没有任何问题,并且 302 只是一个重定向。为什么 scrapy 不直接按照重定向下载文件?

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

【问题讨论】:

  • 尝试不同的用户代理,这里是我的浏览器:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36
  • 用户代理不工作。我怀疑 donwloader 中间件有问题,因为我能够使用 scrapy.Request 下载文件。我正在进一步调查。
  • 好的,到目前为止我发现request.meta.get('handle_httpstatus_all', False)在下载器中间件中返回true。

标签: python scrapy


【解决方案1】:

我的解决方案是先使用requests发送一个http请求,根据status_code选择下载哪个url,现在你可以把url放在file_urls或者你的自定义名称中。

import requests

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

或者你可以使用自定义文件管道

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

我在这里使用了其他解决方案Scrapy i/o block when downloading files

【讨论】:

    【解决方案2】:

    问题的根源似乎是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
    

    具体来说,将handle_httpstatus_all 设置为True 的行禁用了用于下载的重定向中间件,这会触发错误。具体原因我会在scrapy github上问。

    【讨论】:

    • 嗨,感谢您解决这个问题!关于这个问题的任何更新?
    【解决方案3】:

    如果重定向是问题,您应该在 settings.py 中添加以下内容:

    MEDIA_ALLOW_REDIRECTS = True
    

    来源:Allowing redirections in Scrapy

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多