Wie Text aus einer Datei mit Python auslesen?

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.
mocca
User
Beiträge: 84
Registriert: Mittwoch 4. März 2009, 16:44

Sonntag 19. April 2009, 13:24

Hi,

Ich würde ganz gerne ein Python Skript erzeugen, dass aus einer textdatei "information.txt" sämtlichen text zwischen zwei strings ausliest.

in diesem fall soll aus der datei "information.txt" alles ausgelesen werden, was zwischen "<origins>" und "</origins>" steht.

leider komm ich nicht recht drauf wie man das macht.


p.s.: damit ich keinen eigenen thread aufmachen muss: weiss jemand, ob man ein python programm prüfen lassen kann, ob ein bild mit dem namen "profile.jpg" im aktuellen ordner vorhanden ist und dieses dann anzeigen lassen?
lunar

Sonntag 19. April 2009, 13:55

Ist das ein XML-Format?

Was deine zweite Frage betrifft: Die Doku nennt os.path.exists(), os.path.join() und os.getcwd().
mocca
User
Beiträge: 84
Registriert: Mittwoch 4. März 2009, 16:44

Sonntag 19. April 2009, 14:04

hi,

ja, das ist ein xml format. sorry, hab ich vergessen anzugeben. aber falls es eine rolle spielt, wäre es toll, wenn die lösung nicht auf xml dateien begrenzt wäre, falls man das skript mal mit non-xml benutzen will.

zum zweiten teil:
os.path.exists und os.getcwd sind mir bekannt. für was brauche ich path.join für meinen fall? oder war das nur als alternative gemeint?

Code: Alles auswählen

path = os.getcwd()
file = path + 'profile.jpg'
if os.path.exists(file)
Zuletzt geändert von mocca am Sonntag 19. April 2009, 14:11, insgesamt 1-mal geändert.
lunar

Sonntag 19. April 2009, 14:09

Für XML gibt es in der Standardbibliothek neben SAX und Minidom (die beide nicht unbedingt empfehlenswert sind) noch ElementTree. Zudem gibt es lxml, ein wirklich hervorragendes Modul zum Umgang mit XML.

Was den zweiten Teil angeht: "os.getcwd()" ist eine Funktion, also solltest du sie auch aufrufen. Und was das Zusammensetzen der Pfade angeht: Dreimal darfst du raten, wofür ich dich auf "os.path.join()" verwiesen habe :)
mocca
User
Beiträge: 84
Registriert: Mittwoch 4. März 2009, 16:44

Sonntag 19. April 2009, 14:15

ah, dafür war os.path.join.

habs grade, während ich gewartet habe, mal gespielt und habe es wie oben gelöst. einfach zwei variablen erzeugt und kombiniert.
meins ist wohl eher die unschöne lösung....aber es hat geklappt :)

weisst du nun noch, wie ich dieses bild anzeigen lassen kann, wenn ich geprüft habe, ob es vorhanden ist?
oder wie funktioniert das in python, wenn man etwas weitergeben will?
ich hab ja jetzt geprüft, ob das bild vorhanden ist.

p.s.: würde ich in die if-abfrage dann einfach ein "fileexists = file" eintragen und dann könnte der nächste aufruf das "fileexists" aufrufen? und falls es nicht existiert wird einfach das default-bild benutzt.


EDIT: hab mir lxml mal angeschaut. was ich immer wieder feststellen muss, ist dass ich nie weiss, wie ich den ganzen befehlen sage, auf welche datei sie das ganze anwenden sollen.

also ich möchte ja jetzt alles im tag <plot> der datei "information.nfo" ausgeben lassen. nur wie kriegt man das hin?


EDIT2: und so klappts auch schön mit deinem schickeren ansatz

Code: Alles auswählen

if os.path.exists(os.path.join(os.getcwd(),'profile.jpg')):
    print 'yes'
else:
    print 'no'
Zuletzt geändert von mocca am Sonntag 19. April 2009, 14:29, insgesamt 1-mal geändert.
lunar

Sonntag 19. April 2009, 14:29

mocca hat geschrieben:weisst du nun noch, wie ich dieses bild anzeigen lassen kann, wenn ich geprüft habe, ob es vorhanden ist?
Dafür benötigst du ein GUI-Toolkit. Python bringt Tkinter mit. Die Frage, wie man Tkinter ein Bild anzeigen kann, wurde schon oft beantwortet. Ein Blick in das Tkinter-Unterforum hier oder eine Suche bei Google sollten dir weiterhelfen.
p.s.: würde ich in die if-abfrage dann einfach ein "fileexists = file" eintragen und dann könnte der nächste aufruf das "fileexists" aufrufen? und falls es nicht existiert wird einfach das default-bild benutzt.
Ich bin mir nicht sicher, ob ich dich richtig verstehe: "os.path.exists()" bzw. "os.path.isfile()" (was für deinen Zweck besser wäre) geben Wahrheitswerte zurück, so dass du diese Funktionen direkt in einer "if"-Anweisung einsetzen kannst.
also ich möchte ja jetzt alles im tag <plot> der datei "information.nfo" ausgeben lassen. nur wie kriegt man das hin?
Das lässt sich ohne lxml mit dem Mitteln der Standardbibliothek lösen:

Code: Alles auswählen

from xml.etree import ElementTree as etree

tree = etree.parse('information.nfo')
for plot in tree.findall('//plot'):
    print plot.text
mocca
User
Beiträge: 84
Registriert: Mittwoch 4. März 2009, 16:44

Sonntag 19. April 2009, 14:39

super, danke!!!

das funktioniert schonmal super!

ist auch folgendes irgendwie möglich?:

es gibt einen tag namens "<actor>" in dem dann mehrere untertags zu finden sind.
wenn ich nun deinen code statt auf plot auf actor anwende, dann spuckt er nur leerzeilen aus, weil alle infos eben in untertags drin sind.
ist es möglich all diese untertags anzeigen zu lassen, ohne alle einzeln aufzurufen und eventuell dabei nicht nur den inhalt des tags, sondern auch den tagnamen?

sprich, wenn sowas vorliegt:

Code: Alles auswählen

<actor><name>Dennis Hopper</name><age>150</age><born>Yesterday</born>
dann als
Name: Dennis Hopper
Age: 150
Born: Yesterday
ausgeben zu lassen?

vielleicht sowas wie getchildren?
Benutzeravatar
HerrHagen
User
Beiträge: 430
Registriert: Freitag 6. Juni 2008, 19:07

Sonntag 19. April 2009, 14:46

Hier mal eine Lösung die unabhängig von XML ist:

Code: Alles auswählen

>>> data = 'was zwischen "<origins>" und "</origins>" steht. '
>>> start_str = "<origins>"
>>> stop_str = "</origins>"
>>> data[data.index(start_str)+len(start_str):data.index(stop_str)]
'" und "'
Wenn es dir genügt die Bilder von einem Standardprogramm anzeigen zu lassen dann reicht auch das:

Code: Alles auswählen

from PIL import Image
im = Image.open("test.png")
im.show()
MFG HerrHagen
lunar

Sonntag 19. April 2009, 14:48

Code: Alles auswählen

from xml.etree import ElementTree as etree

tree = etree.parse('information.nfo')
for actor in tree.findall('//actor'):
    for child in actor.getchildren():
        print '%s: %s' % (child.tag.capitalize(), child.text)
Das hättest du mit ein bisschen Suchen in der Dokumentation und ein bisschen Ausprobieren in der Dokumentation aber auch selbst herausfinden können.

@HerrHagen:
Markup sollte man mit entsprechenden Parsern lesen, String-Manipulation ist fehleranfällig und wenig robust.

"Image.show()" nutzt übrigens nicht das Standardprogramm für das geladene Bild. Unter Windows konvertiert es die Datei in das BMP-Format und öffnet dann das Standardprogramm für eine BMP-Datei, was sich durchaus vom Standardprogramm für das eigentliche Bildformat unterscheiden kann.
Unter Unix-Derivaten konvertiert es die Datei in das PPM-Format und ruft anschließend "xv" auf. Das ist aber keine freie Software und daher bei den meisten Distributionen normalerweise nicht installiert. "Image.show()" taugt daher für wenig mehr als fürs Debugging. Die Dokumentation sagt ja auch:
This method is mainly intended for debugging purposes.
Unter Windows verwendet man besser "os.startfile()", unter Linux/Unix "subprocess" in Verbindung mit "xdg-open" und "display" aus dem ImageMagick-Paket als Fallback.
Zuletzt geändert von lunar am Sonntag 19. April 2009, 15:05, insgesamt 1-mal geändert.
mocca
User
Beiträge: 84
Registriert: Mittwoch 4. März 2009, 16:44

Sonntag 19. April 2009, 14:59

@HerrHagen:
Danke, werde ich auch gleich mal austesten für die zukunft :D

lunar's xml-lösung ist aber ne super sache!

@lunar:
sorry, ich hab die ganze zeit versucht sowas wie Element.getchildren. hab nicht gerafft, dass Element ein platzhalter für den tag ist :oops:

dann hab ich aber noch zwei fragen zu der sache:
- wenn ich nun z.b. actor = child.text machen will, dann merkt er sich nicht alle daten, sondern nur die letzte zeile.
- kann ich bei diesem verfahren auch einen ganz bestimmten tag ausblenden?

letzteres habe ich mit getiterator machen wollen, aber das blendet natürlich alles aus auusser dem, was ich nicht haben will :D
lunar

Sonntag 19. April 2009, 15:02

mocca hat geschrieben:dann hab ich aber noch zwei fragen zu der sache:
- wenn ich nun z.b. actor = child.text machen will, dann merkt er sich nicht alle daten, sondern nur die letzte zeile.
Ohne Quellcode und detaillierte Fehlermeldung bzw. Fehlerbeschreibung lässt sich dazu nichts sagen. Gewöhne dir bitte an, deine Fragen präzise zu stellen, wenn du eine vernünftige Antwort haben möchtest.
- kann ich bei diesem verfahren auch einen ganz bestimmten tag ausblenden?
Du kannst die Attribute eines Tags natürlich abfragen und mit bestimmten Werten vergleichen, und die Ausgabe nur durchführen, wenn die Attribute den Bedingungen entsprechen.
mocca
User
Beiträge: 84
Registriert: Mittwoch 4. März 2009, 16:44

Sonntag 19. April 2009, 15:05

tut mir leid.

hier mal ein beispieltext:
<plot>This drama, developed by Lionsgate for Starz, is a small screen version of the Paul Haggis helmed feature about race relations in LA.</plot>
<thumb />
<mpaa />
<watched />
<id>tt1178636</id>
<tvdbid>83266</tvdbid>
<genre>Drama</genre>
<premiered>2008-10-17</premiered>
<studio>Starz</studio>
<actor>
<name>Dennis Hopper</name>
<role>Ben Cendars</role>
<thumb>http://www.thetvdb.com/banners/actors/79276.jpg</thumb>
</actor>
<actor>
<name>Clare Carey</name>
<role>Christine Emory</role>
<thumb>http://www.thetvdb.com/banners/actors/79275.jpg</thumb>
</actor>
<actor>
<name>Ross McCall</name>
<role>Kenny Battaglia</role>
<thumb>http://www.thetvdb.com/banners/actors/79274.jpg</thumb>
</actor>
<actor>
<name>Brian Tee</name>
<role>Eddie Choi</role>
<thumb>http://www.thetvdb.com/banners/actors/79273.jpg</thumb>
</actor>
<actor>
<name>Arlene Tur</name>
<role>Bebe Arcel</role>
<thumb>http://www.thetvdb.com/banners/actors/79272.jpg</thumb>
</actor>
<actor>
<name>Jocko Sims</name>
<role>Anthony Adams</role>
<thumb>http://www.thetvdb.com/banners/actors/79271.jpg</thumb>
</actor>
<actor>
<name>Luis Chavez</name>
<role>Cesar Uman</role>
<thumb>http://www.thetvdb.com/banners/actors/79270.jpg</thumb>
</actor>
<actor>
<name>Nick E. Tarabay</name>
<role>Axel Finet</role>
<thumb>http://www.thetvdb.com/banners/actors/79269.jpg</thumb>
</actor>
<actor>
<name>Moran Atias</name>
<role>Inez</role>
<thumb>http://www.thetvdb.com/banners/actors/79268.jpg</thumb>
</actor>
so, wenn ich nun

Code: Alles auswählen

tree = etree.parse(tvshownfo) 
for actor in tree.findall('//actor'): 
    for child in actor.getchildren(): 
        print '%s: %s' % (child.tag.capitalize(), child.text)

Actors = child.text
ausführe und dann print Actors, dann ist der output
sprich der inhalt des allerletzten tags.
lunar

Sonntag 19. April 2009, 15:11

Was hast du denn erwartet? Nichts anders bewirkt deine Anweisung doch.

Wenn du die Werte von Tags speichern möchtest, muss du dafür eine entsprechende Datenstruktur wie dict() oder list() nutzen.
mocca
User
Beiträge: 84
Registriert: Mittwoch 4. März 2009, 16:44

Sonntag 19. April 2009, 15:12

- kann ich bei diesem verfahren auch einen ganz bestimmten tag ausblenden?
Du kannst die Attribute eines Tags natürlich abfragen und mit bestimmten Werten vergleichen, und die Ausgabe nur durchführen, wenn die Attribute den Bedingungen entsprechen.
kann man also nicht mit einem einfach "tag != 'thumb'" oder ähnlichem machen, sondern ich müsste alle erlaubten tags definieren?
Zuletzt geändert von mocca am Sonntag 19. April 2009, 15:16, insgesamt 1-mal geändert.
mocca
User
Beiträge: 84
Registriert: Mittwoch 4. März 2009, 16:44

Sonntag 19. April 2009, 15:15

lunar hat geschrieben:Was hast du denn erwartet? Nichts anders bewirkt deine Anweisung doch.

Wenn du die Werte von Tags speichern möchtest, muss du dafür eine entsprechende Datenstruktur wie dict() oder list() nutzen.
ich hatte gehofft, dass ich diese ganzen ausgelesenen daten dann zur verfügung habe.

sprich ich den plot auslesen lasse und dann jederzeigt den text aus plot weiterreichen kann und gleiches eben für sowas wie actor.
damit ich den inhalt dieser tags dann eben für andere anwendungen zur verfügung stehen habe und diese dann damit weiterarbeiten können.

dazu hätte ich eben gerne die schicke liste child.text in einer variablen wie "Actor" gespeichert.

sprich ich dachte, wenn ich

Code: Alles auswählen

Actors = child.text
print Actors

mache, er das gleiche ausgibt wie bei [/code]print child.text[/code]

Code: Alles auswählen


[quote]Name: Dennis Hopper
Role: Ben Cendars
Thumb: http://www.thetvdb.com/banners/actors/79276.jpg
Name: Clare Carey
Role: Christine Emory
Thumb: http://www.thetvdb.com/banners/actors/79275.jpg
Name: Ross McCall
Role: Kenny Battaglia
Thumb: http://www.thetvdb.com/banners/actors/79274.jpg
Name: Brian Tee
Role: Eddie Choi
Thumb: http://www.thetvdb.com/banners/actors/79273.jpg
Name: Arlene Tur
Role: Bebe Arcel
Thumb: http://www.thetvdb.com/banners/actors/79272.jpg
Name: Jocko Sims
Role: Anthony Adams
Thumb: http://www.thetvdb.com/banners/actors/79271.jpg
Name: Luis Chavez
Role: Cesar Uman
Thumb: http://www.thetvdb.com/banners/actors/79270.jpg
Name: Nick E. Tarabay
Role: Axel Finet
Thumb: http://www.thetvdb.com/banners/actors/79269.jpg
Name: Moran Atias
Role: Inez
Thumb: http://www.thetvdb.com/banners/actors/79268.jpg[/quote]
Zuletzt geändert von mocca am Sonntag 19. April 2009, 15:22, insgesamt 2-mal geändert.
Antworten