一尘不染

使用Python请求模块下载并保存PDF文件

python

我正在尝试从网站下载PDF文件并将其保存到磁盘。我的尝试因编码错误而失败,或者导致PDF空白。

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)
   ...:

我知道这是某种编解码器问题,但我似乎无法使其正常工作。


阅读 237

收藏
2020-12-20

共1个答案

一尘不染

response.content在这种情况下,您应该使用:

with open('/tmp/metadata.pdf', 'wb') as f:
    f.write(response.content)

文件

对于非文本请求,您还可以字节形式访问响应主体:

>>> r.content
b'[{"repository":{"open_issues":0,"url":"https://github.com/...

因此,这意味着:response.text将输出作为字符串对象返回,在下载 文本文件 时使用它。如HTML文件等

response.content以字节对象返回输出,在下载 二进制文件 时使用它。如PDF文件,音频文件,图像等。


您还可以使用response.raw代替。但是,当您要下载的文件很大时,请使用它。以下是一个基本示例,您也可以在文档中找到该示例:

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是您要使用的块大小。如果将其设置为2000,则请求将下载该文件的第一个2000字节,将其写入文件,然后一次又一次地执行,除非完成。

这样可以节省您的RAM。但是response.content在这种情况下,我宁愿使用它,因为您的文件很小。如您所见,使用response.raw非常复杂。


关联:

2020-12-20