Descargue y guarde el archivo PDF con el módulo de solicitudes de Python
Estoy tratando de descargar un archivo PDF de un sitio web y guardarlo en el disco. Mis intentos fallan con errores de codificación o resultan en archivos PDF en blanco.
In [1]: import requests
In [2]: url = 'http://www.hrecos.org//images/Data/forweb/HRTVBSH.Metadata.pdf'
In [3]: response = requests.get(url)
In [4]: with open('/tmp/metadata.pdf', 'wb') as f:
...: f.write(response.text)
---------------------------------------------------------------------------
UnicodeEncodeError Traceback (most recent call last)
<ipython-input-4-4be915a4f032> in <module>()
1 with open('/tmp/metadata.pdf', 'wb') as f:
----> 2 f.write(response.text)
3
UnicodeEncodeError: 'ascii' codec can't encode characters in position 11-14: ordinal not in range(128)
In [5]: import codecs
In [6]: with codecs.open('/tmp/metadata.pdf', 'wb', encoding='utf8') as f:
...: f.write(response.text)
...:
Sé que es un problema de códec de algún tipo, pero parece que no puedo hacer que funcione.
2 answers
Debes usar response.content
en este caso:
with open('/tmp/metadata.pdf', 'wb') as f:
f.write(response.content)
De el documento:
También puede acceder al cuerpo de la respuesta como bytes, para solicitudes que no son de texto:
>>> r.content b'[{"repository":{"open_issues":0,"url":"https://github.com/...
Eso significa: response.text
devuelve la salida como un objeto de cadena, úsalo cuando estés descargando un archivo de texto . Como el archivo HTML, etc.
Y response.content
devuelven la salida como objeto bytes, úsalo cuando estés descargando un archivo binario . Como archivo PDF, archivo de audio, imagen, etc.
También puede usar response.raw
en su lugar. Sin embargo, úselo cuando el archivo que está a punto de descargar sea grande. A continuación se muestra un ejemplo básico que también puede encontrar en el documento:
import requests
url = 'http://www.hrecos.org//images/Data/forweb/HRTVBSH.Metadata.pdf'
r = requests.get(url, stream=True)
with open('/tmp/metadata.pdf', 'wb') as fd:
for chunk in r.iter_content(chunk_size):
fd.write(chunk)
chunk_size
es el tamaño del trozo que desea utilizar. Si lo configura como 2000
, las solicitudes descargarán ese archivo los primeros 2000
bytes, los escribirán en el archivo y lo harán de nuevo, una y otra vez, a menos que haya terminado.
Así que esto puede salvar su RAM. Pero yo prefiera usar response.content
en este caso ya que su archivo es pequeño. Como puede ver, use response.raw
es complejo.
Se relaciona:
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:18:20
Con respecto a la respuesta de Kevin para escribir en una carpeta tmp
, debería ser así:
with open('./tmp/metadata.pdf', 'wb') as f:
f.write(response.content)
Se olvidó .
antes de que la dirección y, por supuesto, su carpeta tmp
ya debería haber sido creada
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-25 12:30:21