2015-05-05 20 views
7

Tôi muốn tải xuống tệp thẳng vào bộ nhớ bằng cách sử dụng requests để chuyển trực tiếp tới trình đọc PyPDF2 để tránh ghi vào đĩa, nhưng Tôi không thể tìm ra cách để vượt qua nó như là một file object. Đây là những gì tôi đã cố gắng:YÊU CẦU: Trả về đối tượng tệp từ url (giống như mở ('', 'rb'))

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) 

Trả lời

13

Mà không cần phải biết gì về requests, bạn luôn có thể làm cho một đối tượng tập tin giống như ra khỏi bất cứ điều gì bạn có trong bộ nhớ như là một chuỗi sử dụng StringIO.

Đặc biệt:

  • Python 2 StringIO.StringIO(s) là một tập tin nhị phân.
  • Python 2 cStringIO.StringIO(s) giống nhau, nhưng có thể hiệu quả hơn.
  • Python 3 io.BytesIO(b) là tệp nhị phân (được xây dựng từ bytes).
  • Python 3 io.StringIO(s) là tệp văn bản Unicode.
  • Python 2 io.BytesIO(s) là tệp nhị phân.
  • Python 2 io.StringIO(u) là tệp văn bản Unicode (được xây dựng từ unicode).

(Hai chữ cái đầu tiên là "nhị phân" trong ý nghĩa Python 2 - không có chuyển đổi kết thúc dòng. Các chữ cái khác là "nhị phân" so với "văn bản" theo nghĩa Python 3 - byte so với Unicode.)

Vì vậy, io.BytesIO(response.content) cung cấp cho bạn đối tượng giống như tệp nhị phân hợp lệ trong cả Python 2 và Python 3. Nếu bạn chỉ quan tâm đến Python 2, cStringIO.StringIO(response.content) có thể hiệu quả hơn.

Tất nhiên "giống như tệp" chỉ diễn ra cho đến thời điểm này; nếu thư viện cố gắng, ví dụ: hãy gọi phương thức fileno và bắt đầu thực hiện cuộc gọi C với trình mô tả tệp sẽ không hoạt động. Nhưng 99% thời gian, điều này hoạt động.

+0

Hoạt động tuyệt vời. Cảm ơn. – TimY

+0

Bumping câu trả lời tốt đẹp, súc tích này. Tôi tự hỏi, @abarnert, là có một nguồn tài nguyên có thể phác thảo những phương pháp đối tượng tập tin giống như không có sẵn trong các đối tượng StringIO? – ghukill

Các vấn đề liên quan