我有一个奇怪的错误。 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
答案 0 :(得分:5)
该文件被gzip压缩的问题,即使它已经是一个gzip压缩文件(可以从'Content-Encoding': 'gzip'
中的r.headers
字段中看到)。
您正在使用requests
和wget
的默认请求标头。默认情况下,它们都会发送'Accept-Encoding: gzip, deflate'
之类的内容。 (如果打印出r.request.headers
,您可以看到这一点。)因此,服务器可以轻松地压缩文件并使用'Content-Encoding: gzip'
标头将其发回。
默认情况下,wget
和requests
都会检测到该标头并为您透明地解码数据 - 但您已明确告知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 2616和RFC 7231,服务器应该选择具有最高q值(权重)的编码,该编码由客户端指定它可以支持(根据某些启发式打破关系)没有指定)。如果您的用户代理明确要求'gzip, deflate'
,那么向您提供identity
将是不正确的,除非它实际上不可能做其他事情,而不是轻微的愚蠢。
答案 1 :(得分:0)
这很疯狂,但将网址末尾的0
更改为1
有效。动机来自SO post。