关于文件下载的wget和requests.get之间的区别

时间:2018-04-27 17:15:38

标签: python python-requests wget

我有一个奇怪的错误。 Dropbox上有一个文件,我正在使用以下python代码下载:

random-names.php

这会下载到import requests import shutil url = 'https://www.dropbox.com/s/fgyso9fq40qp1vl/testfiles.tar.gz?dl=0' r = requests.get(url, stream=True) path_to_save = "/tmp/data.dload-1" with open(path_to_save, 'wb') as f: shutil.copyfileobj(r.raw, f)

使用wget /tmp/data.dload-1

下载的同一文件

这两个文件具有相同的类型:

wget https://www.dropbox.com/s/fgyso9fq40qp1vl/testfiles.tar.gz?dl=0 -O /tmp/data.dload-2

但是没有皮重会产生不同的结果:

(dl)x:x$ file /tmp/data.dload-1 
/tmp/data.dload-1: gzip compressed data, from Unix
(dl)x:x$ file /tmp/data.dload-2 
/tmp/data.dload-2: gzip compressed data, last modified: Thu Apr 26 23:05:15 2018, from Unix

任何人都知道为什么会发生这种情况,更重要的是我如何使用(dl)x:x$ tar -zxvf /tmp/data.dload-1 tar: This does not look like a tar archive tar: Skipping to next header tar: Exiting with failure status due to previous errors (dl) x:x$ tar -zxvf /tmp/data.dload-2 testfiles/a testfiles/b (dl)x:x$ 下载该tar文件(最好是Python

这是requests的结果: r.headers

2 个答案:

答案 0 :(得分:5)

该文件被gzip压缩的问题,即使它已经是一个gzip压缩文件(可以从'Content-Encoding': 'gzip'中的r.headers字段中看到)。

您正在使用requestswget的默认请求标头。默认情况下,它们都会发送'Accept-Encoding: gzip, deflate'之类的内容。 (如果打印出r.request.headers,您可以看到这一点。)因此,服务器可以轻松地压缩文件并使用'Content-Encoding: gzip'标头将其发回。

默认情况下,wgetrequests都会检测到该标头并为您透明地解码数据 - 但您已明确告知requests 不是这样做,并按原样读取原始数据。

所以你最终保存了一个gzip-compressed-gzip-compressed-tarball文件。显然,file会将此报告为gzip compressed data,而tar -z会报告gzip does not look like a tar archive中的内容,因为它不是&#t; t&#t} 39; sa gzipped tar archive。

此处最小的修复是手动将headers={'Accept-Encoding': 'identity'}添加到您的请求中。

您可能想知道为什么服务器正在为gzip压缩gzip压缩文件而烦恼 - 只是因为您告诉它可以接受gzip 并不意味着您要求要求 gzip,对吗?

如果查看RFC 2616RFC 7231,服务器应该选择具有最高q值(权重)的编码,该编码由客户端指定它可以支持(根据某些启发式打破关系)没有指定)。如果您的用户代理明确要求'gzip, deflate',那么向您提供identity将是不正确的,除非它实际上不可能做其他事情,而不是轻微的愚蠢。

答案 1 :(得分:0)

这很疯狂,但将网址末尾的0更改为1有效。动机来自SO post