Frage

Ich lade ein ganzes Verzeichnis von einem Webserver herunter.Es funktioniert einwandfrei, aber ich weiß nicht, wie ich die Dateigröße vor dem Download ermitteln kann, um zu vergleichen, ob sie auf dem Server aktualisiert wurde oder nicht.Kann dies so erfolgen, als würde ich die Datei von einem FTP-Server herunterladen?

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:danke für deine schnelle Antwort.Es funktioniert, aber die Dateigröße auf dem Webserver ist etwas kleiner als die Dateigröße der heruntergeladenen Datei.

Beispiele:

Local Size  Server Size
 2.223.533  2.115.516
   664.603    662.121

Hat es etwas mit der CR/LF-Umwandlung zu tun?

War es hilfreich?

Lösung

Ich habe reproduziert, was Sie sehen:

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

Gibt Folgendes aus:

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

Was mache ich hier falsch?Gibt os.stat().st_size nicht die richtige Größe zurück?


Bearbeiten:OK, ich habe herausgefunden, was das Problem war:

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

Dies gibt aus:

$ 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

Stellen Sie sicher, dass Sie beide Dateien zum binären Lesen/Schreiben öffnen.

// open for binary write
open(filename, "wb")
// open for binary read
open(filename, "rb")

Andere Tipps

Verwendung der Methode „returned-urllib-object“. info(), können Sie verschiedene Informationen zum abgerufenen Dokument abrufen.Beispiel für das Ergreifen des aktuellen Google-Logos:

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

Es ist ein Diktat. Um die Größe der Datei zu ermitteln, müssen Sie dies tun urllibobject.info()['Content-Length']

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

Und um die Größe der lokalen Datei (zum Vergleich) zu ermitteln, können Sie den Befehl os.stat() verwenden:

os.stat("/the/local/file.zip").st_size

Die Größe der Datei wird als Content-Length-Header gesendet.So erhalten Sie es mit urllib:

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

Sehen Sie sich auch an, ob der Server, zu dem Sie eine Verbindung herstellen, dies unterstützt Etags und das Wenn-geändert-seit Und Wenn-Keine-Übereinstimmung Kopfzeilen.

Wenn Sie diese verwenden, werden die Caching-Regeln des Webservers ausgenutzt und ein zurückgegeben 304 Nicht geändert Statuscode, wenn sich der Inhalt nicht geändert hat.

In Python3:

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

Für einen Python3-Ansatz (getestet auf 3.5) würde ich Folgendes empfehlen:

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

A Anfragen-basierte Lösung mit HEAD statt GET (druckt auch HTTP-Header):

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

Verwendung

$ python filesize-remote-url.py https://httpbin.org/image/jpeg
...
Content-Length                          : 35588
FILE SIZE (MB)                          : 0.03 MB
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top