Python wget和requests.get在文件下载方面的差异

Python wget和requests.get在文件下载方面的差异,python,python-requests,wget,Python,Python Requests,Wget,我有一个奇怪的错误。dropbox上有一个文件,我正在用以下python代码下载该文件: 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

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

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)  
这将下载到
/tmp/data.dload-1

与wget
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$ 
任何人都知道为什么会发生这种情况,更重要的是,我如何用
Python
下载tar文件(最好是
requests

这是来自
r.headers
的结果:

(dl)x:x$python dload-test.py

{'Server':'nginx','Date':'Fri,2018年4月27日17:27:06 GMT','Content Type':'text/html;charset=utf-8','Transfer Encoding':'chunked','Connection':'keep alive','Vary':'Accept Encoding','Cache Control','no Cache','Content Security Policy':"脚本src“不安全评估”https://www.dropbox.com/static/compiled/js/ https://www.dropbox.com/static/javascript/ https://www.dropbox.com/static/api/ https://cfl.dropboxstatic.com/static/compiled/js/ https://www.dropboxstatic.com/static/compiled/js/ https://cfl.dropboxstatic.com/static/js/ https://www.dropboxstatic.com/static/js/ https://cfl.dropboxstatic.com/static/previews/https://www.dropboxstatic.com/static/previews/ https://cfl.dropboxstatic.com/static/api/ https://www.dropboxstatic.com/static/api/ https://cfl.dropboxstatic.com/static/cms/ https://www.dropboxstatic.com/static/cms/ https://www.google.com/recaptcha/ https://www.gstatic.com/recaptcha/ “不安全内联”;img src https://*data:blob:;帧祖先“自我”;默认src“无”;帧src https://*旋转木马://*dbapi-6://*dbapi-7://*dbapi-8://*itms应用程序://*itms应用程序://*工作者srchttps://www.dropbox.com/static/serviceworker/ blob:;样式src https://*“不安全内联”“不安全评估”;连接src https://*ws://127.0.0.1:///ws;对象src“self”https://cfl.dropboxstatic.com/static/https://www.dropboxstatic.com/static/ https://flash.dropboxstatic.com https://swf.dropboxstatic.com https://dbxlocal.dropboxstatic.com ;媒体src https://*blob:;字体src https://*数据:;子srchttps://www.dropbox.com/static/serviceworker/ blob:;形成动作“自我”https://www.dropbox.com/ https://dl-web.dropboxwww.com/https://photos.dropbox.com/ https://accounts.google.com/ https://api.login.yahoo.com/ https://login.yahoo.com/ ;基本uri“self”api-stream.dropbox.com showbox-tr.dropbox.com;报告urihttps://www.dropbox.com/csp_log"“,”Dropbox Streaming“:”V=1“,”Pragma“:”no cache“,”referer Policy“:”跨源时的源“,”Set Cookie“:”locale=en;Domain=Dropbox.com;expires=Wed,2023年4月26日17:27:06 GMT;Path=/;secure,gvc=otu0njexnjexnzuwnjc0njqnzmznzmzmzm3mzm5otyznzc%3D;expires=Wed,2023年4月26日17:27:06 GMT;httponly;Path=/;secure,flash=;Domain=Dropbox.com;expires=Fri,2018年4月27日17:27:06 GMT;Path=/;secure,puc=;expires=Fri,2018年4月27日17:27:06 GMT;httponly;Path=/;secure,bang=;Domain=dropbox.com;expires=Fri,2018年4月27日17:27:06 GMT;Path=/;secure,seen sl注册模式=VHJ1ZQ%3D%3D;expires=Sun,2018年5月27日17:27:06 GMT;httponly;Path=/;secure,t=t=HlsAKcFI(opbox.com;expires=Mon,2021年4月26日17:27:06 GMT;httponly;Path=/;secure,u Host-js_csrf=HlsAKcFI_HJWteio0_5ELyFf;expires=Mon,2021年4月26日17:27:06 GMT;Path=/;secure,'X-Content-Type-Options':'nosniff','X-Dropbox-Request-Id':'b028e94ce7b814c7f25fb753449b641a','X-Frame-Options':'DENY','X-Robots-Tag':'noindex','X-Xss-Protection':'1;mode=block','Strict Transport Security':'max age=15552000;includeSubDomains','Content Encoding':'gzip'}

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

对于
请求
wget
,您都在使用默认的请求头。默认情况下,它们都会发送类似于
'Accept-Encoding:gzip,deflate'
的内容。(如果您打印出
r.request.headers
,您可以看到这一点),这样服务器就可以轻松地gzip文件,并使用
“Content-Encoding:gzip”
头将其发送回去

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

因此,您最终保存了一个文件,它是一个gzip压缩的gzip压缩tarball。显然,
文件
会将其报告为
gzip压缩数据
,而
tar-z
会报告gzip
内的内容看起来不像tar存档
,因为它不是,它是gzip压缩的tar存档

这里的最小修复方法是手动将
头={'Accept-Encoding':'identity'}
添加到请求中


您可能想知道为什么服务器会因为您告诉它您可以接受gzip而费心压缩gzip文件并不意味着您需要gzip,对吗


如果您查看和,那么服务器应该选择客户机指定的、它可以支持的具有最高qvalue(权重)的编码(根据未指定的启发式打破联系)。如果你的用户代理明确要求
'gzip,deflate'
,给你
身份将是不正确的,除非实际上不可能这样做,这一点也不傻。

这很疯狂,但将URL末尾的
0
更改为
1
是可行的。受此启发。

看,您可能还想查看每个文件的hextumps的差异,看看是否有很多差异或一个微小的差异足以混淆
tar
。打印出
r.headers
(并在此处发布结果)。@abarnert