Ladezeiten bei urllib messen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
bankkind
User
Beiträge: 106
Registriert: Freitag 14. September 2007, 23:02
Wohnort: Teltow
Kontaktdaten:

Hallo leute,

Kann man irgendwie die Ladezeiten von urllib messen? Um eine art Mini-Monitoring zu basteln? bzw. wird auch etwas zurückgegeben, wenn das Laden der Seite fehlschlägt? Kann mir jemand helfen?

bankkind
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

[mod]timeit[/mod]
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

``timeit`` ist eher zum Benchmarken von Code-Snippseln, also etwas was der Programmierer bei Profiling tut. Zum Überwachen der Dauer die Produktivcode benötigt würde man eher zu ``time`` greifen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Naja, mein Ansatz wäre halt dieser:

Code: Alles auswählen

In [30]: setup = 'import urllib'

In [31]: cmd = 'urllib.urlopen("http://www.ebay.de/")'

In [32]: timer = timeit.Timer(cmd, setup)

In [33]: print '%.2f seconds' % timer.timeit(number=1)
0.51 seconds
bankkind
User
Beiträge: 106
Registriert: Freitag 14. September 2007, 23:02
Wohnort: Teltow
Kontaktdaten:

Dieses Script hilft schon mal sehr! Danke.

Aber wie baue ich mir da jetzt mal nen TimeOut rein?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Du kannst dem Socket über ``settimeout`` einen Timeout angeben.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
bankkind
User
Beiträge: 106
Registriert: Freitag 14. September 2007, 23:02
Wohnort: Teltow
Kontaktdaten:

snafu hat geschrieben:Naja, mein Ansatz wäre halt dieser:

Code: Alles auswählen

In [30]: setup = 'import urllib'

In [31]: cmd = 'urllib.urlopen("http://www.ebay.de/")'

In [32]: timer = timeit.Timer(cmd, setup)

In [33]: print '%.2f seconds' % timer.timeit(number=1)
0.51 seconds
Hey nochmal... ich habe doch noch einige probleme mit dem Script, bei mir bricht es teilweise noch ab ausserdem habe ich ein Verständnisproblem mit Zeile 6 aus unten stehendem Code

Code: Alles auswählen

setup = 'import urllib'
cmd = 'urllib.urlopen("' + url + '")'

for i in range(3):
    timer = timeit.Timer(cmd, setup)
    print '%.2f' % timer.timeit(number=1)

Code: Alles auswählen

Traceback (most recent call last):
  File "urltime.py", line 11, in <module>
    print '%.2f' % timer.timeit(number=1)
  File "C:\Python26\lib\timeit.py", line 193, in timeit
    timing = self.inner(it, self.timer)
  File "<timeit-src>", line 6, in inner
  File "C:\Python26\lib\urllib.py", line 87, in urlopen
    return opener.open(url)
  File "C:\Python26\lib\urllib.py", line 203, in open
    return getattr(self, name)(url)
  File "C:\Python26\lib\urllib.py", line 358, in open_http
    return self.http_error(url, fp, errcode, errmsg, headers)
  File "C:\Python26\lib\urllib.py", line 371, in http_error
    result = method(url, fp, errcode, errmsg, headers)
  File "C:\Python26\lib\urllib.py", line 636, in http_error_302
    data)
  File "C:\Python26\lib\urllib.py", line 651, in redirect_internal
    return self.open(newurl)
  File "C:\Python26\lib\urllib.py", line 203, in open
    return getattr(self, name)(url)
  File "C:\Python26\lib\urllib.py", line 358, in open_http
    return self.http_error(url, fp, errcode, errmsg, headers)
  File "C:\Python26\lib\urllib.py", line 371, in http_error
    result = method(url, fp, errcode, errmsg, headers)
  File "C:\Python26\lib\urllib.py", line 636, in http_error_302
    data)
  File "C:\Python26\lib\urllib.py", line 651, in redirect_internal
    return self.open(newurl)
  File "C:\Python26\lib\urllib.py", line 203, in open
    return getattr(self, name)(url)
  File "C:\Python26\lib\urllib.py", line 358, in open_http
    return self.http_error(url, fp, errcode, errmsg, headers)
  File "C:\Python26\lib\urllib.py", line 371, in http_error
    result = method(url, fp, errcode, errmsg, headers)
  File "C:\Python26\lib\urllib.py", line 636, in http_error_302
    data)
  File "C:\Python26\lib\urllib.py", line 651, in redirect_internal
    return self.open(newurl)
  File "C:\Python26\lib\urllib.py", line 203, in open
    return getattr(self, name)(url)
  File "C:\Python26\lib\urllib.py", line 345, in open_http
    errcode, errmsg, headers = h.getreply()
  File "C:\Python26\lib\httplib.py", line 1024, in getreply
    response = self._conn.getresponse()
  File "C:\Python26\lib\httplib.py", line 950, in getresponse
    response.begin()
  File "C:\Python26\lib\httplib.py", line 390, in begin
    version, status, reason = self._read_status()
  File "C:\Python26\lib\httplib.py", line 348, in _read_status
    line = self.fp.readline()
  File "C:\Python26\lib\socket.py", line 395, in readline
    data = recv(1)
IOError: [Errno socket error] [Errno 10054] Eine vorhandene Verbindung wurde vom Remotehost geschlossen[quote]

Die letzte zeile deutet ja eher auf ein problem mit dem Zielrechner hin, aber wie kann ich sowas in dem Skript abfangen? Ist mir irgendwie zu hoch...[/quote]
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Code: Alles auswählen

from timeit import Timer


def measure(url, times):
    """
    Do an urlopen() with `url`, where `times` specifies how often it is done
    
    Return (total time, average time)
    """
    setup = 'from urllib import urlopen'
    cmd = 'urlopen("%s")' % url
    timer = Timer(cmd, setup)
    time = timer.timeit(number=times)
    return time, time/times


if __name__ == '__main__':
    url = 'http://www.ebay.de/'
    times = 3
    total, average = measure(url, times)
    print "Result after opening %d x %s:\n" \
          "Total: %.2f seconds\n" \
          "Average: %.2f seconds" \
          % (times, url, total, average)
bankkind
User
Beiträge: 106
Registriert: Freitag 14. September 2007, 23:02
Wohnort: Teltow
Kontaktdaten:

Danke danke.

ich habe es mal mit time probiert. Ist das Theoretisch auch richtig? Evtl. aber schlecht gelöst?

Code: Alles auswählen

start = time.clock() 
f = urllib.urlopen(url)
ende = time.clock() 
print "Die Funktion lief %2f Sekunden" % (ende - start)
Ist Grundsätzlich sinnvoll das import erst in der timeit Funktion mit durchzuführen? Bremst das nicht auch?

Code: Alles auswählen

setup = 'from urllib import urlopen'
cmd = 'urlopen("%s")' % url
timer = Timer(cmd, setup)
Ich bin etwas verwirrt über die Vielfalt ;-)
Benutzeravatar
HerrHagen
User
Beiträge: 430
Registriert: Freitag 6. Juni 2008, 19:07

ich habe es mal mit time probiert. Ist das Theoretisch auch richtig? Evtl. aber schlecht gelöst?
Für die Messung von Ereignissen wie du sie mit urlib vor hast, ist das vollkommen in Ordnung.
Ist Grundsätzlich sinnvoll das import erst in der timeit Funktion mit durchzuführen? Bremst das nicht auch?
Der import wird nicht mit in die Zeitmessung einbezogen, da er über den setup parameter übergeben wurde. Die Zeitmessung erfolgt nur über das was im stmt Parameter (hier cmd) steht.

MFG HerrHagen
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

HerrHagen hat geschrieben:
ich habe es mal mit time probiert. Ist das Theoretisch auch richtig? Evtl. aber schlecht gelöst?
Für die Messung von Ereignissen wie du sie mit urlib vor hast, ist das vollkommen in Ordnung.
Im vorleigenden Fall finde ich es sogar besser. Code in Strings ist irgendwie... *bäh*.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
bankkind
User
Beiträge: 106
Registriert: Freitag 14. September 2007, 23:02
Wohnort: Teltow
Kontaktdaten:

OK, aber nun bin ich wieder bei einem anderen Problem... wie kann ich hier ein timeout einbauen? EIne Idee von mir wäre hier

Code: Alles auswählen

start = time.clock()
f = urllib.urlopen(url)
ende = time.clock()
print "Die Funktion lief %2f Sekunden" % (ende - start)
zum Beispiel so eine Art Checkpoint einzubauen, aber nur wie???

Ich würde dann diesen Checkpoint vergleichen und wenn er über einem bestimmten Wert ist, danngibt es einen TimeOut...

EDIT:

Auch noch lustig: auf meinem XP Rechner kommt ein vernünftiges Ergebnis raus:

Code: Alles auswählen

http://www.ebay.de: 0.65 Sekunden
http://www.ebay.de: 0.56 Sekunden
http://www.ebay.de: 0.54 Sekunden
http://www.ebay.de: 0.58 Sekunden
http://www.ebay.de: 0.53 Sekunden
Auf nem Linux vServer:

Code: Alles auswählen

http://www.ebay.de: 0.00 Sekunden
http://www.ebay.de: 0.00 Sekunden
http://www.ebay.de: 0.00 Sekunden
http://www.ebay.de: 0.00 Sekunden
http://www.ebay.de: 0.00 Sekunden
Ist das hier die bessere Anbindung oder einfach nur Fehlerhaft? ich hab keine erklärung...
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Für Linux solltest du besser mit `time.time()` messen. Den Grund kannst du bspw. dem Docstring des `timeit`-Moduls entnehmen. :)
bankkind
User
Beiträge: 106
Registriert: Freitag 14. September 2007, 23:02
Wohnort: Teltow
Kontaktdaten:

Ja, da shabe ich jetzt auch schon mitbekommen, mit time.time() bekomme ich bessere Ergebnisse.

Jetzt habe ich aber neben meinem noch immer ungelöstem TimeOut, das Problem das ich MySQL nicht zum laufen bekomme in Python.

Gibt es hier ein verständliches Tutorial? Bzw. denke ich das ich schon ein Kompatibilitätsproblem habe, denn es gibt keine MySQL Libfür Python 2.6...
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Wo ist das Problem, MySQLdb gegen Python 2.6 zu kompilieren?
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
bankkind
User
Beiträge: 106
Registriert: Freitag 14. September 2007, 23:02
Wohnort: Teltow
Kontaktdaten:

Leider ist das schon ein Problem. Weil für mich, der das noch nicht gemacht hat, ist das gefrickel und mir fehlt da leider eine vernünftige Anleitung.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

bankkind hat geschrieben:Weil für mich, der das noch nicht gemacht hat, ist das gefrickel und mir fehlt da leider eine vernünftige Anleitung.
Dann gibt es zwei Möglichkeiten: Python 2.5 nehmen oder MySQLdb-Quellen runterladen, MySQL herunterladen (und hoffen dass die Include-Dateien dabei sind) und einen Compiler herunterladen (Visual C++ Express sollte reichen, oder MinGW. Je nach Software ist der eine oder der andere Compiler brauchbarer).

Wenn du das hast machst du im MySQLdb-Ordner ein ``python setup.py build_ext`` und korrigierst solange an den Sachen rum (fehlende Include-Dateien etc) bis es dann kompiliert. Ich kann dir da auch keine genaue Anleitung geben, weil die genauen Schritte immer etwas unterschiedlich sind, je nach Compiler und Software die man kompilieren will.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo Leonidas

In der Doku zu 'timeit'
http://docs.python.org/dev/library/timeit
sind weiter unten Beispiele vorhanden. Weisst du was beim folgenden Code-Schnippsel genau abläuft:

Code: Alles auswählen

def test():
    "Stupid test function"
    L = []
    for i in range(100):
        L.append(i)

if __name__=='__main__':
    from timeit import Timer
    t = Timer("test()", "from __main__ import test")
    print t.timeit()
Bei mir wird der Printbefehl:

Code: Alles auswählen

print t.timeit()
nie ausgeführt oder es dauert eine Ewigkeit bis dies der Fall sein wird?

Gruss wuf :wink:
Take it easy Mates!
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Doch, der wird ausgeführt, nur muss der Code erstmal 1000000 durchlaufen werden, was schon ziemlich lange dauert. Das kannst du ausprobieren indem du dem Aufruf ``number=1`` als Argument mitgibst.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

@Leonidas: Danke! Alles klar.

Eine weitere Frage:

Kann eine Zeitmessung mittels 'timeit' als genau bezeichnet werden da scheinbar mit Nanosekunden-Auflösung gemessen wird?

Gruss wuf :wink:
Take it easy Mates!
Antworten