Få størrelsen på en fil før nedlasting i Python

stemmer
36

Jeg laster ned en hel katalog fra en webserver. Det fungerer OK, men jeg kan ikke finne ut hvordan å få filstørrelsen før nedlasting for å sammenligne hvis den ble oppdatert på serveren eller ikke. Kan dette gjøres som om jeg var å laste ned filen fra en FTP-server?

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: Takk for raskt svar. Det fungerer, men filstørrelsen på webserveren er litt mindre enn filstørrelsen på den nedlastede filen.

eksempler:

Local Size  Server Size
 2.223.533  2.115.516
   664.603    662.121

Det har noe å gjøre med CR / LF konvertering?

Publisert på 08/08/2008 klokken 13:35
kilden bruker
På andre språk...                            


7 svar

stemmer
23

Jeg har gjengitt det du ser:

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

Utganger dette:

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

Hva gjør jeg galt her? Er os.stat (). St_size ikke tilbake riktig størrelse?


Edit: OK, jeg fant ut hva problemet var:

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

dette utganger:

$ 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

Pass på at du åpner begge filene for binær lese / skrive.

// open for binary write
open(filename, "wb")
// open for binary read
open(filename, "rb")
Svarte 08/08/2008 kl. 14:21
kilden bruker

stemmer
20

Bruke den returnerte-urllib-objekt-metoden info(), kan du få forskjellig informasjon på retrived dokumentet. Eksempel på å gripe den aktuelle Google-logoen:

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

Det er en dict, så å få størrelsen på filen, trenger du urllibobject.info()['Content-Length']

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

Og for å få størrelsen på lokal fil (for sammenligning), kan du bruke os.stat () kommandoen:

os.stat("/the/local/file.zip").st_size
Svarte 08/08/2008 kl. 13:47
kilden bruker

stemmer
7

Størrelsen på filen sendes som Content-Length spissen. Her er hvordan du får det med urllib:

>>> site = urllib.urlopen("http://python.org")
>>> meta = site.info()
>>> print meta.getheaders("Content-Length")
['16535']
>>>
Svarte 08/08/2008 kl. 13:41
kilden bruker

stemmer
5

Også hvis serveren du kobler deg til støtter det, se på ETags og If-Modified-Since og If-None-Match -hoder.

Ved hjelp av disse vil dra nytte av webserveren er caching regler og vil returnere en 304 Not Modified statuskoden hvis innholdet ikke er endret.

Svarte 08/08/2008 kl. 13:51
kilden bruker

stemmer
2

I Python3:

>>> import urllib.request
>>> site = urllib.request.urlopen("http://python.org")
>>> print("FileSize: ", site.length)
Svarte 26/08/2014 kl. 09:31
kilden bruker

stemmer
1

For en python3 (testet på 3,5) tilnærmingen jeg vil anbefale:

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())
Svarte 27/09/2017 kl. 05:33
kilden bruker

stemmer
1

En forespørsler baserte løsning med HEAD i stedet for GET (også skriver HTTP-hoder):

#!/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))

bruk

$ python filesize-remote-url.py https://httpbin.org/image/jpeg
...
Content-Length                          : 35588
FILE SIZE (MB)                          : 0.03 MB
Svarte 04/12/2016 kl. 10:21
kilden bruker

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