Obțineți dimensiunea unui fișier înainte de a descărca în Python

Sunt descărcarea unui întreg director de pe un server web. Funcționează bine, dar nu-mi dau seama cum să obținem dimensiunea fișierului înainte de a descărca pentru a compara dacă a fost actualizat pe server sau nu. Se poate face acest lucru ca și cum aș fi descărcat fișierul de pe un server 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('^.*

@Jon: mulțumesc pentru răspunsul dvs. rapid. Funcționează, dar dimensiunea fișierului de pe serverul web este puțin mai mică decât dimensiunea fișierului descărcat.

Exemple:

Local Size  Server Size
 2.223.533  2.115.516
   664.603    662.121

Are ceva de a face cu conversia CR / LF?

0
fr hi bn
ai dreptate, nu foloseam "wb" la deschiderea fișierului local pentru scriere. Lucrează ca un farmec! Mersi
adăugat autor PabloG, sursa
Eventual. Puteți rula diff pe ea și a vedea o diferență? De asemenea, vedeți diferența de dimensiune a fișierului în fișierele binare (.zip)? Editare: Aici se află lucrurile cum ar fi Etags. Serverul vă va spune când ceva se schimbă, astfel încât să nu trebuiască să descărcați fișierul complet pentru a-l descoperi.
adăugat autor Jonathan Works, sursa

7 răspunsuri

Utilizând metoda info() returnată-urllib-obiect, puteți obține diverse informații despre documentul retrimis. Exemplu de apucare a logo-ului Google curent:

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

It's a dict, so to get the size of the file, you do urllibobject.info()['Content-Length']

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

Și pentru a obține dimensiunea fișierului local (pentru comparație), puteți folosi comanda os.stat ():

os.stat("/the/local/file.zip").st_size
0
adăugat
adăugat autor dbr, sursa
Am folosit această soluție, totuși am lovit un caz de margine unde uneori nu este definită antetul lungimii conținutului. Poate cineva să explice de ce nu ar fi returnat în mod consecvent?
adăugat autor wbeange, sursa

O soluție solicită bazată pe HEAD în loc de GET (imprimă și antete 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))

folosire

  $ python filesize-remote-url.py https://httpbin.org/image/jpeg
...
Durata conținutului: 35588
FILE SIZE (MB): 0,03 MB
 
0
adăugat

Pentru o abordare python3 (testat pe 3.5) aș recomanda:

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())
0
adăugat

Mărimea fișierului este trimis ca antet Content-Length. Iată cum se poate obține cu urllib:

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

De asemenea, dacă serverul pe care îl conectați îl acceptă, consultați Etags și Dacă-Modificat-Din și Anteturile" Dacă-Nu este potrivită .

Utilizarea acestora va profita de regulile de stocare ale serverelor web și va returna un cod de stare 304 Modified dacă conținutul nu sa schimbat.

0
adăugat

Am reprodus ceea ce vedeți:

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

Rezultă:

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

Ce fac greșit aici? Este os.stat (). St_size nu returnează dimensiunea corectă?


Editați | ×: OK, mi-am dat seama ce a fost problema:

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

aceste rezultate:

$ 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

Asigurați-vă că deschideți ambele fișiere pentru citirea / scrierea binară.

// open for binary write
open(filename, "wb")
// open for binary read
open(filename, "rb")
0
adăugat
atunci când faceți site = urllib.urlopen (link) ați realizat descărcarea unui fișier, deci nu este o dimensiune înainte de a descărca fișierele sale descărcate în tampon de unde recuperați lungimea conținutului
adăugat autor Ciasto piekarz, sursa
@Ciastopiekarz Cred că atunci când încercați să citiți() că fișierul este descărcat efectiv în tampon verificați acest răspuns
adăugat autor CaptainDaVinci, sursa

În Python3:

>>> import urllib.request
>>> site = urllib.request.urlopen("http://python.org")
>>> print("FileSize: ", site.length)
0
adăugat
Aceasta descarcă fișierul!
adăugat autor Joseph Victor Zammit, sursa
Python România
Python România
100 participanți

Comunitatea pasionaților de Python din România.