Stringverarbeitung

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.
Antworten
sledgehammer
User
Beiträge: 7
Registriert: Donnerstag 31. August 2006, 00:57

Samstag 2. September 2006, 23:14

Hallo zusammen,

bin recht neu bezüglich (Python) Programmierung. Hab mit einem Buch schon das ein oder andere Beispiel nachgestellt.

Aber jetzt naht der Herbst und es soll ans "Eingemachte" gehen. Vermutlich hab ich noch ein Verständnisproblem.

Diese Datei möchte ich einlesen:

Code: Alles auswählen

option1 = wert
option2 = 1234
option3 = wert2, 54321, \
   wert3, 3456, 3214, wert4
In dieser Datei möchte ich je nach Bedarf zeilenweise ein "#" setzen/entfernen und der Wert hinter "option1-3" soll in Strings bzw. Variablen zum weiterverarbeiten gespeichert werden. Falls eine Option mehrere Zeilen lang ist, soll dass einlesen weiterhin funktionieren.

Gibt es zum Verarbeiten von solchen "Standardkonfigdateien" (Option = Wert) eine Funktion in Python oder muss ich das weitgehend selber programmieren?
Ein paar Übungen in einer Pythonshell waren schon erfolgreich (mit string.replace), aber dann weiß ich irgendwie nicht mehr weiter wie ich das Zeichen "#" an erste Stelle hinzufüge bzw. entferne.

Das war jetzt das leichte Problem.

Was mir mehr Kopfzerbrechen bereitet ist folgendes:
1. eine HTML-Datei einlesen
2. die Zeile mit Inhalt "serviceverkehr" suchen
3. ausgehend von dieser Zeile in die 3.te Zeile danach "springen"
4. und den Inhalt zwischen <li> und </li> ohne den HTML Code, aber Zeile für Zeile ausgeben (in der Zeile sind mehrere <li></li> möglich, je nach Verkehrsmeldungen)

Hier ein Ausschnitt der HTML-Datei:

Code: Alles auswählen

...
      <div id="serviceverkehr">
	    <h1>Die Verkehrsredaktion meldet Staus...</h1>
	    <ul>
<li>Augsburg-Lechhausen: Sperrung am Knotenpunkt</li><li>Augsburg-Oberhausen: wg. des Marktsonntags</li>	    </ul>
	  </div>
	  <div id="serviceblitz">
	    <h1>Geblitzt wird aktuell </h1>
	    <ul>
<LI>Keine Meldungen</LI>
...
Punkt 3 bereitet mir Kopfzerbrechen. Ich kann (in einer Python-Shell) suchen und finde etwas, aber erhalte nur den Rückgabewert 0 oder 1. Ich benötige eigentlich eine Zeilennummer als Rückgabewert und zu diesem Wert kann ich +3 addieren und die eigentliche Zeile weiter verarbeiten.

Hab ich noch zu wenig Python-Doku gelesen?

Bitte nicht lachen, jeder Einstieg ist schwer. Ich weiß selber, daß ich mich wahrscheinlich selten blöd anstelle.

Danke und Grüße,

Helmut
bot
User
Beiträge: 20
Registriert: Montag 22. Mai 2006, 19:47

Sonntag 3. September 2006, 08:31

Also dein erstes Problem wirst du mit einem ini oder config parser lösen können.

http://docs.python.org/lib/module-ConfigParser.html

Dort musst du halt zusätzlich zu deinen options

key = value

immer noch eine section angeben

sprich

[MeineOptions]
option1 = wert
option2 = 1234
option3 = wert2, 54321, \
wert3, 3456, 3214, wert4

ich denke das du bei option3 das "\" weg lassen kannst, ausser es handelt sich wirklich im ein zeichen. wenn du die werte von option3 "einzeln" brauchst, dann speicherst du deinen langen string "wert2, 54321, wert3, 3456, 3214, wert4" einfach in eine liste.

Code: Alles auswählen


string = "wert2, 54321, wert3, 3456, 3214, wert4"

liste = string.split(",")



Für dein 2tes Problem würd ich einen html parser nehmen

http://docs.python.org/lib/module-htmllib.html

bzw.

http://docs.python.org/lib/module-HTMLParser.html

es gbit auch selbstgemachte freie ( wie mächtig der ist, ka )

http://vsbabu.org/mt/archives/2002/04/2 ... ython.html


viel spass mit python :)
sledgehammer
User
Beiträge: 7
Registriert: Donnerstag 31. August 2006, 00:57

Sonntag 3. September 2006, 09:51

bot hat geschrieben:Also dein erstes Problem wirst du mit einem ini oder config parser lösen können.

http://docs.python.org/lib/module-ConfigParser.html

Dort musst du halt zusätzlich zu deinen options

key = value

immer noch eine section angeben
Hallo Bot,

Danke! Hab dieses Modul nach meinem Posting entdeckt. Nachdem ich aber nicht nur meine eigene Konfigdatei verwalten möchte, sondern mitunter ein paar Serverdienste unter Linux (Postfix, Openvpn, Iptables), fällt das vermutlich weg?
Für dein 2tes Problem würd ich einen html parser nehmen

http://docs.python.org/lib/module-htmllib.html
Kann dieser als Ergebniss die Zeilennummer ausgeben, wenn ich nach einem Wert suche, so daß ich ausgehend von dieser Zeilennummer die eigentliche Zeile verarbeiten kann?

Mit diesem kleinen Beispiel möchte ich erstmal in Python einsteigen. Ein Configtool für die oben genannten Serverdienste ist mir noch zu heftig.

Irgendwie hab ich Probleme, die Zeilennummer als ("Rückgabe")wert zu erhalten, weil ich die entsprechende Funktion in Python nicht finde.
viel spass mit python :)
Danke :) Ich bin recht zuversichtlich, muss aber meine persönlichen Hürden noch überwinden. Wenn man etwas mehr drinnen ist, flutscht das sicher fast wie von selbst. Ich weiß momentan noch nicht wie ich es programmieren soll und wenn etwas klappt, ob ich es richtig programmiere, also ob ich schon "in Python denke", oder das nur irgendwie hingemurkst habe.
Und ich weiß nicht aus dem stegreif, was mir Python an Modulen schon serienmässig anbietet.

Grüße, Helmut
Zuletzt geändert von sledgehammer am Sonntag 3. September 2006, 11:02, insgesamt 1-mal geändert.
bot
User
Beiträge: 20
Registriert: Montag 22. Mai 2006, 19:47

Sonntag 3. September 2006, 10:41

sorry den html parser hab ich noch nicht benutzt, vielleicht hilft dir die doku oder ein tutorial oder ein nettes boardmember hier weiter.

wieso solltest du nicht mit dem configparser mehrere configs "verwalten"?

wieso ist dir dies zu "heftig"?

Für einfache sachen, verwende ich gerne den configparser, um programmeinstellungen usw. einzulesen, ect.

xml finde ich da ein wenig "overrulez".

Den configparser kannste ja unter win/linux ect. verwenden. Ist sehr einfach zu verstehen, einfach zu bedienen, und per texteditor sehr leicht zu editieren.
sledgehammer
User
Beiträge: 7
Registriert: Donnerstag 31. August 2006, 00:57

Sonntag 3. September 2006, 11:07

bot hat geschrieben:sorry den html parser hab ich noch nicht benutzt, vielleicht hilft wieso solltest du nicht mit dem configparser mehrere configs "verwalten"?
Configdateien von z.b. Postfix und OpenVPN haben keine Sections. Wenn der configparser von Python sections voraussetzt, geht es wohl nicht? Oder doch?
bot
User
Beiträge: 20
Registriert: Montag 22. Mai 2006, 19:47

Sonntag 3. September 2006, 11:37

hmmm und was würde dagensprechen eine eine section einzufügen?

z.b.

Postfix.ini

[Postfix]
key1 = value1
key2 = value2

Wenn du mit deinem configparser öffnest, kannst du einfach auf die key und values zugreifen, und die line mit der section "[Postfix]" dürfte ja wohl auch nicht anderen programme durcheinanderbringen, oder?
sledgehammer
User
Beiträge: 7
Registriert: Donnerstag 31. August 2006, 00:57

Sonntag 3. September 2006, 12:40

bot hat geschrieben:hmmm und was würde dagensprechen eine eine section einzufügen?

z.b.

Postfix.ini

[Postfix]
key1 = value1
key2 = value2

Wenn du mit deinem configparser öffnest, kannst du einfach auf die key und values zugreifen, und die line mit der section "[Postfix]" dürfte ja wohl auch nicht anderen programme durcheinanderbringen, oder?
Die main.cf von Postfix (ein Mailserver) besitzt keine Section(s) und es gibt eine Fehlermeldung beim starten.
Wahrscheinlich läufts dabei hinaus, einen eigenen Parser zu programmieren. Es gibt noch mehr Configdateien in Postfix, die jeweils eine andere Syntax aufweisen.

Was mir kein Kopfzerbrechen bereitet ist der Rückgabewert der Zeilennummer nach einer Suche. Bin in meiner Suche bei dem Modul 'fileinput' angelangt :)

Code: Alles auswählen

for line in fileinput.input('verkehr__blitzer.html'):
   match = string.count(line, 'serviceverkehr')
   if match:
      zeile = fileinput.filelineno()
      print zeile
:) :)
Aber jetzt muss ich genau die 3.te Zeile danach in einen String einlesen. Der eigentlich Ausgabe könnte mit regulären Ausdrücken funktionieren.

Hoffentlich muss ich keine betriebssystemspezifische Funktionen verwenden, nachdem das Programm später auf meinem Symbian-Handy funktionieren soll (E61). Möchte aktuelle Staumeldungen und Blitzer von meinem lokalen Lieblingsradiosender auf dem Display anzeigen lassen, wenn ich mal die Nachrichten verpasst habe mit Abfrage, ob er sich die Daten über WLAN (zu Hause) oder GPRS/UMTS (unterwegs) holen soll. Für ein erstes Programm/Übung in Python ist das schon recht sinnvoll :) ;)
BlackJack

Sonntag 3. September 2006, 14:57

Für das parsen von HTML ist BeautifulSoup zu empfehlen. Das ist ein viel robusterer Ansatz als mit den Zeilen zu operieren weil er auch noch funktioniert wenn sich das HTML in der Form ändert.

Code: Alles auswählen

from BeautifulSoup import BeautifulSoup

source = '''      <div id="serviceverkehr">
        <h1>Die Verkehrsredaktion meldet Staus...</h1>
        <ul>
          <li>Augsburg-Lechhausen: Sperrung am Knotenpunkt</li>
          <li>Augsburg-Oberhausen: wg. des Marktsonntags</li>
        </ul>
      </div>
      <div id="serviceblitz">
        <h1>Geblitzt wird aktuell </h1>
        <ul>
<LI>Keine Meldungen</LI>
'''

def main():
    soup = BeautifulSoup(source)
    traffic_div = soup.find('div', {'id': 'serviceverkehr'})
    for item in traffic_div.findAll('li'):
        print item.string

if __name__ == '__main__':
    main()
sledgehammer
User
Beiträge: 7
Registriert: Donnerstag 31. August 2006, 00:57

Sonntag 3. September 2006, 15:51

Hallo BlackJack,

Danke! Von BeautifulSoap hab ich mal gelesen, aber keinen Plan was ich damit anstellen kann. Vermutlich wird es BeautifulSoap nicht auf Python/Symbian60 geben? Konnte zumindest nichts entdecken.
Das ist letztendlich mein Ziel, dass das Script auf meinem Handy läuft. So kann ich jederzeit den Verkehr/Blitzer prüfen und muss nicht auf die halbstündlichen Nachrichten warten.

Ich hab inzwischen in mühevoller Arbeit meine Version fertig. Bin von fileinput wieder weg. Die Umlaute werden aber nicht dargestellt ... das ist zum Haare raufen :(

Code: Alles auswählen

#!/usr/bin/python

import string, urllib

#livedat = open('verkehr__blitzer.html', 'r')
livedat = urllib.urlopen('http://www.fantasy.de/verkehr__blitzer.html')
zeilen = livedat.readlines()
livedat.close()

zeilnum = zeilen.index('      <div id="serviceverkehr">\r\n')
zeilnum = zeilnum + 3
verkehr = zeilen[zeilnum]
verkehr = string.replace(verkehr, "</li>", "\n")
verkehr = string.replace(verkehr, "<li>", "")
verkehr = string.replace(verkehr, "</ul>", "")

zeilnum = zeilen.index('\t  <div id="serviceblitz">\r\n')
zeilnum = zeilnum + 3
blitzer = zeilen[zeilnum]
blitzer = string.replace(blitzer, "</li>", "\n")
blitzer = string.replace(blitzer, "<li>", "")

print "Staus:\n", verkehr, "Blitzer:\n", blitzer
Jetzt hab ich noch kurz einen Test mit Livedaten und BeautifulSoap gemacht. Aber das klappt bei mir noch nicht :( Wollte ausprobieren, wie die Umlaute dort ausgegeben werden. Jetzt brauch ich erst mal nen Pause... :shock:

Code: Alles auswählen

import string, urllib
from BeautifulSoup import BeautifulSoup


def main():
    livedat = urllib.urlopen('http://www.fantasy.de/verkehr__blitzer.html')
    source = livedat.read()
    livedat.close()

    soup = BeautifulSoup(source)
    traffic_div = soup.find('div', {'id': 'serviceverkehr'})
    for item in traffic_div.findAll('li'):
        print item.string

if __name__ == '__main__':
    main()
BlackJack

Sonntag 3. September 2006, 18:46

sledgehammer hat geschrieben:Von BeautifulSoap hab ich mal gelesen, aber keinen Plan was ich damit anstellen kann. Vermutlich wird es BeautifulSoap nicht auf Python/Symbian60 geben? Konnte zumindest nichts entdecken.
Das ist ein reines Pythonmodul das man von der Website auch als eine einzelne *.py Datei herunterladen kann. Wenn auf dem Mobiltelefon ein vollständiges Python drauf ist, dann sollte das kein Problem sein.
Ich hab inzwischen in mühevoller Arbeit meine Version fertig. Bin von fileinput wieder weg. Die Umlaute werden aber nicht dargestellt ... das ist zum Haare raufen :(
Die luschtige Welt der Zeichenkodierungen. Die Webseite kommt in ISO-8859-1 daher. Wenn das nicht dem "Ausgabemedium" entspricht, dann musst Du umkodieren. Also ``data.decode('iso-8859-1').encode('whatever')``. Wobei `whatever` natürlich die Zielkodierung sein muss.
Jetzt hab ich noch kurz einen Test mit Livedaten und BeautifulSoap gemacht. Aber das klappt bei mir noch nicht :(
Das ist eine Fehlerbeschreibung die es schwer macht weiter zu helfen. Bei mir klappt Dein BeautifulSoup-Skript jedenfalls.
Wollte ausprobieren, wie die Umlaute dort ausgegeben werden.
BeautifulSoup liefert Zeichenketten als `unicode` Objekte zurück. Wenn der Interpretierer also die Kodierung der Ausgabe nicht richtig ermittelt hat, dann musst Du die nur noch passend kodieren.
sledgehammer
User
Beiträge: 7
Registriert: Donnerstag 31. August 2006, 00:57

Sonntag 3. September 2006, 19:16

BlackJack hat geschrieben:
sledgehammer hat geschrieben:Jetzt hab ich noch kurz einen Test mit Livedaten und BeautifulSoap gemacht. Aber das klappt bei mir noch nicht :(
Das ist eine Fehlerbeschreibung die es schwer macht weiter zu helfen.
Du hast absolut recht! Es wird bei mir leider nichts ausgegeben, deshalb konnte ich nicht mehr schreiben. War auch nur ein schnelles copy/paste.
Werde das morgen in der Pythonshell nochmal nachprüfen. Die 5 Stunden heute reichen mir erstmal und ich hab festgestellt, dass bei mir noch absolut große Defizite existieren.

Danke!! :) viele Grüße und noch nen schönen Sonntag Abend!

Helmut
sledgehammer
User
Beiträge: 7
Registriert: Donnerstag 31. August 2006, 00:57

Freitag 8. September 2006, 00:15

Lag an der BeautifulSoap Version. Jetzt funktioniert es. Danke! :)
Antworten