簡體   English   中英

Python - 使用請求直接下載文件到內存

[英]Python - Download File Using Requests, Directly to Memory

目標是從互聯網上下載文件,並從中創建一個文件對象,或者像對象這樣的文件,而不必觸摸硬盤。 這只是為了我的知識,想知道它是否可行或實用,特別是因為我想看看我是否可以避免編寫文件刪除行。

這就是我通常從網上下載內容並將其映射到內存的方式:

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?

r.rawHTTPResponse )已經是一個類似文件的對象(只是傳遞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)

通常,如果你有一個bytestring; 您可以將其包裝為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.raw傳遞給ZipFile() ,因為前者是不可搜索的文件。

我想看看我是否可以規避必須編寫文件刪除行的代碼

tempfile可以自動刪除文件f = tempfile.SpooledTemporaryFile(); f.write(u.content) f = tempfile.SpooledTemporaryFile(); f.write(u.content) 直到.fileno()方法(如果某些api需要真實文件)或達到maxsize ; 數據保存在內存中。 即使數據寫在磁盤上; 文件一關閉就會被刪除。

你的回答是u.content 內容在內存中。 除非您將其寫入文件,否則它不會存儲在磁盤上。

這就是我最終做的事情。

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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM