Blog/content/posts/2022/python/request-file-size.md

117 lines
3.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
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 (<class 'int'>)
```
Однако не стоит забывать, что файла может и не быть.
По этому лучше проверять такие ситуации.
```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)
```