2015-05-05 27 views
7

Chcę pobrać plik bezpośrednio do pamięci za pomocą requests, aby przekazać go bezpośrednio do czytnika PyPDF2, unikając zapisu na dysku, ale Nie mogę wymyślić, jak przekazać go jako file object. Oto, co starałem:ZAPYTANIA: Zwróć obiekt pliku z adresu URL (tak jak przy otwartym ('', '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) 

Odpowiedz

13

bez konieczności wiedzieć nic o requests, zawsze można dokonać obiekt plikopodobny z czymkolwiek masz w pamięci jako ciąg znaków z wykorzystaniem StringIO.

W szczególności:

  • Python 2 StringIO.StringIO(s) jest plik binarny.
  • Python 2 cStringIO.StringIO(s) jest taki sam, ale prawdopodobnie bardziej wydajny.
  • Python 3 io.BytesIO(b) to plik binarny (zbudowany z bytes).
  • Python 3 io.StringIO(s) to plik tekstowy w formacie Unicode.
  • Python 2 io.BytesIO(s) to plik binarny.
  • Python 2 io.StringIO(u) to plik tekstowy w formacie Unicode (zbudowany z unicode).

(Pierwsze dwa to "binarne" w sensie Python 2 - brak konwersji końca wiersza, pozostałe to "binarny" kontra "tekst" w sensie Pythona 3 - bajty kontra Unicode.)

Tak, io.BytesIO(response.content) daje prawidłowy plik binarny podobny do pliku zarówno w Pythonie 2, jak iw Pythonie 3. Jeśli interesuje Cię tylko Python 2, cStringIO.StringIO(response.content) może być bardziej wydajny.

Oczywiście "plikopodobny" posuwa się tak daleko; jeśli biblioteka spróbuje, na przykład, wywołać metodę fileno i rozpocząć wykonywanie wywołań C w stosunku do deskryptora pliku, to nie zadziała. Ale 99% czasu to działa.

+0

Działa świetnie. Dzięki. – TimY

+0

Wpadając w tę miłą, zwięzłą odpowiedź. Zastanawiam się, @abarnert, czy istnieje zasób, który może nakreślić, jakie metody obiektów podobnych do plików nie są dostępne w obiektach StringIO? – ghukill