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

Я загружаю весь каталог с веб-сервера. Он работает нормально, но я не могу понять, как получить размер файла перед загрузкой для сравнения, если он был обновлен на сервере или нет. Можно ли это сделать, как если бы я загружал файл с 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() 

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

Примеры:

 Local Size Server Size 2.223.533 2.115.516 664.603 662.121 

Это как-то связано с преобразованием CR / LF?

7 Solutions collect form web for “Получите размер файла перед загрузкой в ​​Python”

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

 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 

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


Изменить: Хорошо, я понял, в чем проблема:

 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") 

Используя info-метод возвращаемого-urllib-объекта info() , вы можете получить различную информацию о возвращенном документе. Пример захвата текущего логотипа 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 

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

 >>> site = urllib.urlopen("http://python.org") >>> meta = site.info() >>> print meta.getheaders("Content-Length") ['16535'] >>> 

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

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

В Python3:

 >>> import urllib.request >>> site = urllib.request.urlopen("http://python.org") >>> print("FileSize: ", site.length) 

Решение на основе запросов, использующее HEAD вместо 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 

Для подхода 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()) 
  • Загрузить pdf с помощью urllib?
  • Библиотека запросов Python - определить конкретный DNS?
  • Многопоточный веб-скребок с использованием urlretrieve на сайте с поддержкой cookie
  • Как читать содержимое веб-сайта?
  • Content-Length должен быть указан для повторяющихся данных типа <class 'dict'>
  • Python: как получить продолжительность просмотра видео пользователем из журналов
  • Обработка тайм-аута urllib2? - Python
  • Изменить тип байта python на строку
  • Вопрос Python 3.2
  • Python: Войдите в систему, используя urllib
  • python считывает строки исходного кода веб-сайта по 100 строк за раз
  •  
    Interesting Posts for Van-Lav

    Может только zip с RDD, у которого одинаковое количество ошибок раздела

    Обнаружение, если объект с одного изображения находится на другом изображении с помощью OpenCV

    Как можно использовать raw_input () в Python Git hook?

    Использование Cython для связывания Python с общей библиотекой

    Django 1.8 загрузка файлов для определенного места

    Добавить столбец в базу данных pandas

    Эффективность Python: списки против кортежей

    Преобразование из строки IP в целое число и обратно в Python

    Сравнение вложенных списков Python

    Использование блокировки резьбы в функции обратного вызова ctypes

    Может ли приложение Heroku использовать разные / несколько портов?

    Импортировать ошибку импорта HTTP http.client с помощью Python 3.4.1

    Преобразование данных в словарь списка кортежей

    Ошибка импорта matplotlib.pyplot в jupyter (но не ipython)

    Сортировка и ограничение набора запросов по количеству комментариев и дате с помощью queryset.extra () (django)

    Python - лучший язык программирования в мире.