Seite 1 von 1

Mit urllib nur bestimmten Teil auslesen?

Verfasst: Sonntag 23. Januar 2011, 15:10
von Schaf220
Hallo liebe Community,
ich weiß leider nicht mehr weiter. Also möchte ein Logfile auslesen. Das Log ist aber nur online zu bekommen. Deshalb lade ich es mit urllib2 versucht. Das geht ja noch gut, aber es ist meist 2 MB groß und ich möchte zum Beipsiel nur die letzten 100 KB auslesen, damit nur das neu hinzugekommende Material übernommen werden kann. Das Log ist keine HTML-Seite. Es ist eine *.log. Naja der Inhalt wird jedenfalls im Browser angezeigt, ist halt nur Text, deshalb kommt ein HTML-Parser nicht in Frage denke ich. Habt ihr vieleicht eine Idee, wie ich die letzten 100 KB aus dem Log downloaden kann?

Zurzeit lade ich noch alles runter und prüfe die Zeilen bis der neue Teil anfängt, das dauert schon einige Zeit.
PS: (Das ist alles nur Quick und Dirty)

Code: Alles auswählen

#! /usr/bin/env python
# -*- coding: utf-8 -*-

from urllib2 import urlopen 
from sqlite3 import dbapi2 as sqlite

class LogFileSaver(object):
    
    def __init__(self):
        self.logList = []
        self.dbNameNew = "BO_SKSB.sqlite"
        self.__conNewDB = sqlite.connect(self.dbNameNew)
        self.__curNewDB = self.__conNewDB.cursor()
        self.serverID = 1
        self.link = "http://logs.gameservers.com/173.199.108.158:3074/8d3be2c0-1a32-4ebd-9d1c-b387024f28cf" 
        self.lastGameDiff = 1000 # Differenz von der maximalen Anzahl der Spiele
                     
    def getLog(self):
        f = urlopen(self.link)
        self.__curNewDB.execute('SELECT SLastGame FROM bous_server WHERE ID=' + str(self.serverID))
        lastGame = self.__curNewDB.fetchone()[0]
        line = f.readline()
        while line:
            pos1 = line.find(":")                    
            gameCounter = int(line[:pos1]) # gamecounter
            if gameCounter < (lastGame-self.lastGameDiff):
                print "ServerRestart"
                self.logList.append(line)
            elif gameCounter < lastGame:
                print "Warte bis an richtiger Stelle"
            elif gameCounter > lastGame:
                    print "Neue Daten!"
                    self.logList.append(line)
            elif gameCounter == lastGame:
                pass
            else:
                self.logList.append(line)
            
            self.__conNewDB.commit()
            line = f.readline()
        self.__curNewDB.execute('UPDATE bous_server SET SLastGame = ' + str(gameCounter) + 'WHERE ID =' + str(self.serverID))

if __name__ == "__main__":
    log = LogFileSaver()
    log.getLog() 

Re: Mit urllib nur bestimmten Teil auslesen?

Verfasst: Sonntag 23. Januar 2011, 16:04
von Barabbas
Hallo,

ich habe jetzt auch nur auf die Schnelle und aus Interesse nachgesehen. So wie es sich mir darstellt, musst du das explizit über den HTTP-Header machen:

Code: Alles auswählen

import urllib2

url = "http://logs.gameservers.com/173.199.108.158:3074/8d3be2c0-1a32-4ebd-9d1c-b387024f28cf"

req = urllib2.Request(url)
req.add_header("Range", 'bytes=-1025')
f = urllib2.urlopen(req)
print f.read(1024)
Allerdings war bei meiner Quelle dieser mögliche negative Wert für das Feld "Range" gar nicht dokumentiert. Es scheint aber zu funktionieren.

Besten Gruß,

brb

Re: Mit urllib nur bestimmten Teil auslesen?

Verfasst: Sonntag 23. Januar 2011, 16:15
von cofi
Barabbas hat geschrieben:Allerdings war bei meiner Quelle dieser mögliche negative Wert für das Feld "Range" gar nicht dokumentiert. Es scheint aber zu funktionieren.
Es handelt sich ja auch um "Range", nicht "Content-Range" (wie verlinkt). Gueltige Werte fuer Range sind "Byte Ranges" und die geben den Fall sogar explizit als Beispiel an:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35.1 hat geschrieben:Examples of byte-ranges-specifier values (assuming an entity-body of length 10000):
...
- The final 500 bytes (byte offsets 9500-9999, inclusive):
bytes=-500

Re: Mit urllib nur bestimmten Teil auslesen?

Verfasst: Sonntag 23. Januar 2011, 16:21
von Hyperion
Nebenbei: Man sollte niemals normale String-Konkatenierungstechniken bei SQL-Queries nutzen. Stichwort SQL Injection!

Code: Alles auswählen

# falsch
        self.__curNewDB.execute('SELECT SLastGame FROM bous_server WHERE ID=' + str(self.serverID))
# richtig
        self.__curNewDB.execute('SELECT SLastGame FROM bous_server WHERE ID=?', (self.serverID,))
Selbiges gilt natürlich auch für die "update"-Stelle ;-)

Re: Mit urllib nur bestimmten Teil auslesen?

Verfasst: Sonntag 23. Januar 2011, 16:47
von Schaf220
Vielen Dank für die Hilfe, es hat mir wirklich sehr geholfen!

Re: [gelöst]Mit urllib nur bestimmten Teil auslesen?

Verfasst: Montag 24. Januar 2011, 08:53
von BlackJack
@Schaf220: Warum ist das eigentlich eine ``while``-Schleife mit `readline()`-Aufrufen und keine ``for``-Schleife über `f`?

Und das mit dem `commit()` sieht komisch aus. Was Du da eventuell mehrfach "committest" ist das 'SELECT' von *vor* der Schleife. Das würde ich wenn es denn nötig sein sollte direkt vor der Schleife nach dem 'SELECT' machen und dann halt auch nur einmal.

Dafür fehlt augenscheinlich ein `commit()` nach dem 'UPDATE'.

Ansonsten sehen die Namensschreibweisen und die doppelten Unterstriche irgendwie so aus, als wenn da nicht in Python programmiert werden sollte. Die Namen sind auch nicht immer gut gewählt. `f` ist zum Beispiel zu kurz, `logList` enthält den Datentyp, und `__curNewDB` ist eine kryptische Abkürzung.