Python - 使用请求将文件直接下载到内存

Python - Download File Using Requests, Directly to Memory

提问人:Anon 提问时间:3/12/2014 最后编辑:Anon 更新时间:10/23/2015 访问量:41692

问:

目标是从 Internet 下载文件,并从中创建文件对象或类似文件的对象,而无需接触硬盘驱动器。这只是我的知识,想知道它是否可行或实用,特别是因为我想看看我是否可以规避必须编写文件删除行。

这就是我通常从网络上下载内容并将其映射到内存的方式:

import requests
import mmap

u = requests.get("http://www.pythonchallenge.com/pc/def/channel.zip")

with open("channel.zip", "wb") as f: # I want to eliminate this, as this writes to disk
    f.write(u.content)

with open("channel.zip", "r+b") as f: # and his as well, because it reads from disk
    mm = mmap.mmap(f.fileno(), 0)
    mm.seek(0)
    print mm.readline()
    mm.close() # question: if I do not include this, does this become a memory leak?
蟒蛇 python 请求 mmap

评论

0赞 Karl Knechtel 3/12/2014
docs.python-requests.org/en/latest/user/quickstart/......

答:

11赞 poke 3/12/2014 #1

你的答案是。内容内存中。除非将其写入文件,否则它不会存储在磁盘上。u.content

评论

1赞 Anon 3/12/2014
你如何获取u.content,并创建一个像对象一样的文件(mmap 所做的),而不把它写到磁盘上?
50赞 jfs 3/14/2014 #2

r.raw (HTTPResponse) 已经是一个类似文件的对象(只需传递):stream=True

#!/usr/bin/env python
import sys
import requests # $ pip install requests
from PIL import Image # $ pip install pillow

url = sys.argv[1]
r = requests.get(url, stream=True)
r.raw.decode_content = True # Content-Encoding
im = Image.open(r.raw) #NOTE: it requires pillow 2.8+
print(im.format, im.mode, im.size)

一般来说,如果你有字节字符串;你可以把它包装成 ,在不接触磁盘的情况下得到一个类似文件的对象:f = io.BytesIO(r.content)

#!/usr/bin/env python
import io
import zipfile
from contextlib import closing
import requests # $ pip install requests

r = requests.get("http://www.pythonchallenge.com/pc/def/channel.zip")
with closing(r), zipfile.ZipFile(io.BytesIO(r.content)) as archive:
    print({member.filename: archive.read(member) for member in archive.infolist()})

您不能直接传递到,因为前者是不可查找的文件。r.rawZipFile()

我想看看我是否可以规避必须编写文件删除行

tempfile可以自动删除文件 f = tempfile。后台处理TemporaryFile();f.write(u.content)。直到调用方法(如果某些 api 需要真实文件)或到达;数据保存在内存中。即使数据写入磁盘;文件关闭后立即删除。.fileno()maxsize

13赞 Anon 3/14/2014 #3

这就是我最终所做的。

import zipfile 
import requests
import StringIO

u = requests.get("http://www.pythonchallenge.com/pc/def/channel.zip")
f = StringIO.StringIO() 
f.write(u.content)

def extract_zip(input_zip):
    input_zip = zipfile.ZipFile(input_zip)
    return {i: input_zip.read(i) for i in input_zip.namelist()}
extracted = extract_zip(f)