2022-09-16 01:38:42 +03:00
|
|
|
|
---
|
2022-11-19 03:36:06 +03:00
|
|
|
|
title: "📄 Получаем размер загружаемого файла на Python"
|
2022-09-16 01:38:42 +03:00
|
|
|
|
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)
|
|
|
|
|
```
|