请求:从url返回文件对象(与open('','rb')一样)

Tim*_*imY 10 python file download pypdf python-requests

我想直接将文件下载到内存中requests,以便将其直接传递给PyPDF2阅读器,避免将其写入磁盘,但我无法弄清楚如何将其作为传递给它file object.这是我尝试过的:

import requests as req
from PyPDF2 import PdfFileReader

r_file = req.get('http://www.location.come/somefile.pdf')
rs_file = req.get('http://www.location.come/somefile.pdf', stream=True)

with open('/location/somefile.pdf', 'wb') as f:
    for chunk in r_file.iter_content():
        f.write(chunk)

local_file = open('/location/somefile.pdf', 'rb')

#Works:
pdf = PdfFileReader(local_file)

#As expected, these don't work:
pdf = PdfFileReader(rs_file)
pdf = PdfFileReader(r_file)
pdf = PdfFileReader(rs_file.content)
pdf = PdfFileReader(r_file.content)
pdf = PdfFileReader(rs_file.raw)
pdf = PdfFileReader(r_file.raw)
Run Code Online (Sandbox Code Playgroud)

aba*_*ert 22

无需了解任何内容requests,您始终可以使用内存中的任何内容创建类似文件的对象StringIO.

特别是:

  • Python 2 StringIO.StringIO(s)是一个二进制文件.
  • Python 2 cStringIO.StringIO(s)是相同的,但可能更有效.
  • Python 3 io.BytesIO(b)是一个二进制文件(由...构造bytes).
  • Python 3 io.StringIO(s)是一个Unicode文本文件.
  • Python 2 io.BytesIO(s)是一个二进制文件.
  • Python 2 io.StringIO(u)是一个Unicode文本文件(由...构造unicode).

(前两个是Python 2意义上的"二进制" - 没有行结束转换.其他的是Python 3意义上的"二进制"与"文本" - 字节与Unicode.)

因此,io.BytesIO(response.content)在Python 2和Python 3中为您提供了一个有效的二进制文件对象.如果您只关心Python 2,cStringIO.StringIO(response.content)可能会更高效.

当然,"文件式"只是到目前为止; 如果库试图,例如,调用该fileno方法并开始对文件描述符进行C调用,它将无法工作.但99%的时间,这是有效的.