use*_*072 7 python python-requests
我正在尝试读取我通过请求请求的gzip XML文件.我读过的所有内容都表明解压缩应该自动发生.
#!/usr/bin/python
from __future__ import unicode_literals
import requests
if __name__ == '__main__':
url = 'http://rdf.dmoz.org/rdf/content.rdf.u8.gz'
headers = {
'Accept-Encoding': "gzip,x-gzip,deflate,sdch,compress",
'Accept-Content': 'gzip',
'HTTP-Connection': 'keep-alive',
'Accept-Language': "en-US,en;q=0.8",
}
request_reply = requests.get(url, headers=headers)
print request_reply.headers
request_reply.encoding = 'utf-8'
print request_reply.text[:200]
print request_reply.content[:200]
Run Code Online (Sandbox Code Playgroud)
我的第一行输出中的标题如下所示:
{'content-length': '260071268', 'accept-ranges': 'bytes', 'keep-alive': 'timeout=5, max=100', 'server': 'Apache', 'connection': 'Keep-Alive', 'date': 'Tue, 08 Sep 2015 16:27:49 GMT', 'content-type': 'application/x-gzip'}
Run Code Online (Sandbox Code Playgroud)
接下来的两个输出行似乎是二进制的,我期待XML文本:
?I?(?????~?ool???u?r??J???io? a2R1???|?<????_??????????=?Z????onnz7?{JO???}h?????6??·??>,a?>??hZ6?u??x????y?_?.y?$??
?I?(?????~?ool???u?r??J???io? a2R1???|?<????_??????????=?Z????onnz7?{JO??}h?????6??·??>,a?>??hZ6?u??x???
Run Code Online (Sandbox Code Playgroud)
我认为部分问题是site-packages/requests/packages/urllib3/response.py除非标题有,否则无法识别gzip'content-encoding': 'gzip'
我能够通过在方法中添加4行来获得我想要的结果response.py:
def _init_decoder(self):
"""
Set-up the _decoder attribute if necessar.
"""
# Note: content-encoding value should be case-insensitive, per RFC 7230
# Section 3.2
content_encoding = self.headers.get('content-encoding', '').lower()
if self._decoder is None and content_encoding in self.CONTENT_DECODERS:
self._decoder = _get_decoder(content_encoding)
# My added code below this comment
return
content_type = self.headers.get('content-type', '').lower()
if self._decoder is None and content_type == 'application/x-gzip':
self._decoder = _get_decoder('gzip')
Run Code Online (Sandbox Code Playgroud)
但是,有更好的方法吗?
你误会了。仅传输级别的压缩会自动处理,因此压缩由HTTP服务器应用。
您已压缩内容。由于这不仅适用于HTTP传输阶段,因此requests也不会删除它。
requests通过Accept-Encoding: gzip, deflate与发送的每个请求一起发送,与服务器通信以表示它接受压缩的响应。然后,服务器可以通过压缩整个响应主体并添加Content-Encoding指示使用的压缩的标头来进行响应。
您的响应没有Content-Encoding标头,在这里再次应用压缩也没有意义。
多数情况下,无论如何,您都想以压缩形式下载已压缩的存档,例如DMOZ RDF数据集。您毕竟请求了压缩的存档。requests解码库不是库的工作。
在Python 3中,您可以通过使用gzip模块并流式传输响应来将解码处理为流:
import gzip
import requests
import shutil
r = requests.get(url, stream=True)
if r.status_code == 200:
with open(path, 'wb') as f:
r.raw.decode_content = True # just in case transport encoding was applied
gzip_file = gzip.GzipFile(fileobj=r.raw)
shutil.copyfileobj(gzip_file, f)
Run Code Online (Sandbox Code Playgroud)
当然,您可以在其中使用RDF解析器,而不是将解压缩的数据复制到磁盘。
不幸的是,该模块的Python 2实现需要一个可搜索的文件。您可以创建自己的流包装器,也可以将该_decoder属性添加到r.raw上面的对象中。
| 归档时间: |
|
| 查看次数: |
3825 次 |
| 最近记录: |