Получить размер файла перед загрузкой в ​​Python

голоса
34

Я загружаю весь каталог с веб-сервера. Он работает нормально, но я не могу понять, как получить размер файла перед загрузкой для сравнения, если она была обновлена ​​на сервере или нет. Можно ли это сделать, как если бы я был загрузив файл с FTP-сервера?

import urllib
import re

url = http://www.someurl.com

# Download the page locally
f = urllib.urlopen(url)
html = f.read()
f.close()

f = open (temp.htm, w)
f.write (html)
f.close()

# List only the .TXT / .ZIP files
fnames = re.findall('^.*<a href=(\w+(?:\.txt|.zip)?).*$', html, re.MULTILINE)

for fname in fnames:
    print fname, ...

    f = urllib.urlopen(url + / + fname)

    #### Here I want to check the filesize to download or not #### 
    file = f.read()
    f.close()

    f = open (fname, w)
    f.write (file)
    f.close()

@ Джон: спасибо за быстрый ответ. Он работает, но размер файла на веб-сервере несколько меньше, чем размер файла загруженного файла.

Примеры:

Local Size  Server Size
 2.223.533  2.115.516
   664.603    662.121

Он не имеет ничего общего с преобразованием CR / LF?

Задан 08/08/2008 в 12:35
источник пользователем
На других языках...                            


8 ответов

голоса
7

Размер файла передается в качестве заголовка Content-Length. Вот как получить его с URLLIB:

>>> site = urllib.urlopen("http://python.org")
>>> meta = site.info()
>>> print meta.getheaders("Content-Length")
['16535']
>>>
Ответил 08/08/2008 в 12:41
источник пользователем

голоса
19

Используя метод возвращал-URLLIB-объект info(), вы можете получить различную информацию о retrived документе. Пример захвата текущего логотипа Google:

>>> import urllib
>>> d = urllib.urlopen("http://www.google.co.uk/logos/olympics08_opening.gif")
>>> print d.info()

Content-Type: image/gif
Last-Modified: Thu, 07 Aug 2008 16:20:19 GMT  
Expires: Sun, 17 Jan 2038 19:14:07 GMT 
Cache-Control: public 
Date: Fri, 08 Aug 2008 13:40:41 GMT 
Server: gws 
Content-Length: 20172 
Connection: Close

Это ДИКТ, так, чтобы получить размер файла, вы urllibobject.info()['Content-Length']

print f.info()['Content-Length']

А чтобы получить размер локального файла (для сравнения), вы можете использовать команду os.stat ():

os.stat("/the/local/file.zip").st_size
Ответил 08/08/2008 в 12:47
источник пользователем

голоса
5

Кроме того, если сервер вы подключаетесь поддерживает его, посмотрите на ETags и If-Modified-Since и If-None-Match заголовки.

Используя эти будет использовать правила кэширования веб - сервера и вернет 304 Not Modified кода состояния , если содержание не изменилось.

Ответил 08/08/2008 в 12:51
источник пользователем

голоса
22

Я воспроизвел то, что вы видите:

import urllib, os
link = "http://python.org"
print "opening url:", link
site = urllib.urlopen(link)
meta = site.info()
print "Content-Length:", meta.getheaders("Content-Length")[0]

f = open("out.txt", "r")
print "File on disk:",len(f.read())
f.close()


f = open("out.txt", "w")
f.write(site.read())
site.close()
f.close()

f = open("out.txt", "r")
print "File on disk after download:",len(f.read())
f.close()

print "os.stat().st_size returns:", os.stat("out.txt").st_size

Выходы это:

opening url: http://python.org
Content-Length: 16535
File on disk: 16535
File on disk after download: 16535
os.stat().st_size returns: 16861

Что я делаю неправильно здесь? Является ли os.stat (). St_size не возвращает правильный размер?


Edit: Хорошо, я понял, что проблема была:

import urllib, os
link = "http://python.org"
print "opening url:", link
site = urllib.urlopen(link)
meta = site.info()
print "Content-Length:", meta.getheaders("Content-Length")[0]

f = open("out.txt", "rb")
print "File on disk:",len(f.read())
f.close()


f = open("out.txt", "wb")
f.write(site.read())
site.close()
f.close()

f = open("out.txt", "rb")
print "File on disk after download:",len(f.read())
f.close()

print "os.stat().st_size returns:", os.stat("out.txt").st_size

это выходы:

$ python test.py
opening url: http://python.org
Content-Length: 16535
File on disk: 16535
File on disk after download: 16535
os.stat().st_size returns: 16535

Убедитесь, что вы открываете оба файла для бинарного чтения / записи.

// open for binary write
open(filename, "wb")
// open for binary read
open(filename, "rb")
Ответил 08/08/2008 в 13:21
источник пользователем

голоса
2

В Python3:

>>> import urllib.request
>>> site = urllib.request.urlopen("http://python.org")
>>> print("FileSize: ", site.length)
Ответил 26/08/2014 в 08:31
источник пользователем

голоса
1

A запрашивает основанное решение , использующее ГОЛОВКА вместо GET (также печатает HTTP - заголовки):

#!/usr/bin/python
# display size of a remote file without downloading

from __future__ import print_function
import sys
import requests

# number of bytes in a megabyte
MBFACTOR = float(1 << 20)

response = requests.head(sys.argv[1], allow_redirects=True)

print("\n".join([('{:<40}: {}'.format(k, v)) for k, v in response.headers.items()]))
size = response.headers.get('content-length', 0)
print('{:<40}: {:.2f} MB'.format('FILE SIZE', int(size) / MBFACTOR))

Применение

$ python filesize-remote-url.py https://httpbin.org/image/jpeg
...
Content-Length                          : 35588
FILE SIZE (MB)                          : 0.03 MB
Ответил 04/12/2016 в 08:21
источник пользователем

голоса
1

Для Python3 (проверено на 3.5) подход я бы рекомендовал:

with urlopen(file_url) as in_file, open(local_file_address, 'wb') as out_file:
    print(in_file.getheader('Content-Length'))
    out_file.write(response.read())
Ответил 27/09/2017 в 04:33
источник пользователем

голоса
0

@PabloG Что касается разницы в локальном размере файла / сервере

Ниже высокого уровня иллюстративный объяснение того, почему это может произойти:

Размер на диске иногда отличается от фактического размера данных. Это зависит от базовой файловой системы и как она работает на данных. Как вы, возможно, видели в Windows, при форматировании флэш-накопителя вы попросили Provice «размер блока / кластера» и изменяется [512b - 8kb]. Когда файл записывается на диск, он storled в «рода-связного списка» дисковых блоков. Когда определенный блок используются для хранения части файла, никаких других содержимого файла будет храниться в том же Блоке, так что даже если порция не occupuing всего блок пространства, блок непригодный других файлами.

Пример: Когда файловая система разделена на 512b блоков, и мы должны хранить 600B файл, два блока будет занят. Первый блок будет полностью использован, в то время как второй блок будет иметь только 88b используются, а остальные (512-88) б будет непригодным для использования в результате чего «размер файла-на-диске» быть 1024b валиков. Поэтому для Windows имеет различные обозначения для «размер файла» и «размер на диске».

Примечание: Существуют различные плюсы и минусы, которые приходят с меньшим / большим блоком FS, так что лучше исследований, прежде чем играть с вашей файловой системой.

Ответил 28/01/2020 в 21:45
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more