diff --git a/content/posts/python/request-file-size.md b/content/posts/python/request-file-size.md new file mode 100644 index 0000000..d97e0e3 --- /dev/null +++ b/content/posts/python/request-file-size.md @@ -0,0 +1,116 @@ +--- +title: "Получаем размер загружаемого файла на Python" +date: 2022-09-16T01:08:53+03:00 +draft: false +tags: [python, tips] +--- + +### Введение + +Многие пишут грабберы сайтов на Python. +Я вот например [скачиваю](#) сиськи с [blog.stanis.ru](http://blog.stanis.ru/). + +Но иногда, требуется проверить, не загружен ли файл уже, до того как его скачать. + +Способов сравнения файлов существует достаточное количество, +но в рамках этого руководства я рассмотрю способ сравнения файлов по их размеру. + +### Получение размера локального файла + +В стандартной библиотеке Python, есть функция `getsize()` в модуле `os.path`. + +```python +import os.path + +if __name__ == '__main__': + file_size = os.path.getsize("./avatar.png") + + print("Size: {0} ({1})".format(file_size, type(file_size))) +``` + +Программа вернёт следующий результат: + +```text +Size: 14390 () +``` + +Однако не стоит забывать, что файла может и не быть. +По этому лучше проверять такие ситуации. + +```python +os.path.exists("./avatar/png") +``` + +### Получение размера удалённого файла + +Для работы с HTTP, +я использую модуль [requests](https://requests.readthedocs.io/en/latest/index.html). + +Каждый web-сервер, возвращает заголовки, в которых может быть полезная информация. +Для примера, получим заголовки файла [аватара](https://iiiypuk.me/avatar.png) на моём сайте. + +```python +import requests + +response = requests.get("https://iiiypuk.me/avatar.png") +print(response.headers) +``` + +Вывод будет следующий: + +```text +{ + 'Server': 'nginx/1.20.2', + 'Date': 'Thu, 15 Sep 2022 22:14:41 GMT', + 'Content-Type': 'image/png', + 'Content-Length': '14390', + 'Last-Modified': 'Fri, 08 Jul 2022 11:23:06 GMT', + 'Connection': 'keep-alive', + 'Accept-Ranges': 'bytes' +} +``` + +Нас интересует заголовок `Content-Length`. + +```python +print(response.headers['Content-Length']) +# Выхлоп: 14390 +``` + +Сравнение до боли простое: + +```python +import os.path +import requests + +if __name__ == '__main__': + local_size = os.path.getsize("./avatar.png") + + response = requests.get("https://iiiypuk.me/avatar.png") + remote_size = int(response.headers['Content-Length']) + + if local_size != remote_size: + print("Файлы разные") + print("Локальный размер: {0}\nУдалённый размер: {1}".format( + local_size, remote_size)) + else: + print("Файлы одинаковые") + +``` + +Обрати внимание, что `response.headers['Content-Length']` возвращает значение +строкой, а не целым числом. + +### ВСЁ! + +Можно скачивать файл. + +```python +import shutil +import requests + +response = requests.get("https://iiiypuk.me/avatar.png", stream=True) + +with open("./file.png", "wb") as out_image: + shutil.copyfileobj(response.raw, out_image) +```