Загрузите и сохраните файл 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)
...:
Я знаю, что это проблема кодека, но я не могу заставить ее работать.
Ответы
Ответ 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
байты, записывать их в файл и делать это снова, снова и снова, если только это не закончится.
Таким образом, это может сэкономить ваше ОЗУ. Но я предпочел бы использовать response.content
вместо этого в этом случае, так как ваш файл невелик. Как видите, использование response.raw
является сложным.
Относится:
Ответ 2
В Python 3 я считаю, что pathlib - это самый простой способ сделать это. Запрос response.content прекрасно сочетается с pathlib _write_bytes_.
from pathlib import Path
import requests
filename = Path('metadata.pdf')
url = 'http://www.hrecos.org//images/Data/forweb/HRTVBSH.Metadata.pdf'
response = requests.get(url)
filename.write_bytes(response.content)
Ответ 3
Пожалуйста, обратите внимание, что я новичок. Если мое решение неверно, пожалуйста, исправьте и/или дайте мне знать. Я тоже могу узнать что-то новое.
Мое решение:
Измените путь загрузки в соответствии с тем, где вы хотите сохранить файл. Не стесняйтесь использовать абсолютный путь тоже для вашего использования.
Сохраните ниже как downloadFile.py.
Использование: python downloadFile.py url-of-the-file-to-download new-file-name.extension
Не забудьте добавить расширение!
Пример использования: python downloadFile.py http://www.google.co.uk google.html
import requests
import sys
import os
def downloadFile(url, fileName):
with open(fileName, "wb") as file:
response = requests.get(url)
file.write(response.content)
scriptPath = sys.path[0]
downloadPath = os.path.join(scriptPath, '../Downloads/')
url = sys.argv[1]
fileName = sys.argv[2]
print('path of the script: ' + scriptPath)
print('downloading file to: ' + downloadPath)
downloadFile(url, downloadPath + fileName)
print('file downloaded...')
print('exiting program...')
Ответ 4
относительно ответа Кевина на запись в папку tmp
, это должно быть примерно так:
with open('./tmp/metadata.pdf', 'wb') as f:
f.write(response.content)
он забыл .
перед адресом и, конечно, ваша папка tmp
должна была быть уже создана