Hallo Euch!!!!!!!!!!!
Weißt vielleicht jemand wie man HTML-Dateien in reine Textdatei verwandelt?
HTML in reine Textdatei umwandeln?Wie?
Code: Alles auswählen
import urllib2,htmllib,formatter
h = htmllib.HTMLParser(formatter.AbstractFormatter(formatter.DumbWriter()))
h.feed(open("deineDatei.html").read())
HTH
Grüße fs111
Hallo fs111,
das stimmt, es tut genau das von mir gewünscht! Aber warum? Was passiert da genau? Und das ganze nur in einer Zeile.
Wenn ich nun eine html table habe, kann ich dann die entspechende Elemente erkennen und mit TAB, CR oder vielleicht auch XML versehen?
Bsp:
<table>
<tr>
<td>19.08.2006</td><td>15:00</td><td>Hamburg</td>
<td>20.08.2006</td><td>15:00</td><td>München</td
</tr>
</table>
Zur Zeit ist alles in einer Zeile allerdings schon mit einem Leerzeichen getrennt.
19.08.2006 15:00 Hamburg 20.08.2006 15:00 München.
Könnte ich zum Beispiel nach dem dritten Element ein CR einfügen? Wo findet eigentlich die Ausgabe auf der Konsole statt?
Oder in XML
<event>
<date>19.08.2006</date>
<time>15:00</time>
<location>Hamburg</location>
</event>
<event>
<date>20.08.2006</date>
<time>15:00</time>
<location>München</location>
</event>
Danke im Voraus
Lord Hong
das stimmt, es tut genau das von mir gewünscht! Aber warum? Was passiert da genau? Und das ganze nur in einer Zeile.
Wenn ich nun eine html table habe, kann ich dann die entspechende Elemente erkennen und mit TAB, CR oder vielleicht auch XML versehen?
Bsp:
<table>
<tr>
<td>19.08.2006</td><td>15:00</td><td>Hamburg</td>
<td>20.08.2006</td><td>15:00</td><td>München</td
</tr>
</table>
Zur Zeit ist alles in einer Zeile allerdings schon mit einem Leerzeichen getrennt.
19.08.2006 15:00 Hamburg 20.08.2006 15:00 München.
Könnte ich zum Beispiel nach dem dritten Element ein CR einfügen? Wo findet eigentlich die Ausgabe auf der Konsole statt?
Oder in XML
<event>
<date>19.08.2006</date>
<time>15:00</time>
<location>Hamburg</location>
</event>
<event>
<date>20.08.2006</date>
<time>15:00</time>
<location>München</location>
</event>
Danke im Voraus
Lord Hong
Zum lesen von HTML bietet sich BeautifulSoup an und zum schreiben von XML ElementTree.
Code: Alles auswählen
import sys
from itertools import cycle, izip
from BeautifulSoup import BeautifulSoup
from elementtree.SimpleXMLWriter import XMLWriter
source = '''\
<table>
<tr>
<td>19.08.2006</td><td>15:00</td><td>Hamburg</td>
<td>20.08.2006</td><td>15:00</td><td>München</td
</tr>
</table>
'''
def convert(source, out_file):
soup = BeautifulSoup(source)
writer = XMLWriter(out_file)
writer.start('events')
table = soup.find('table')
table_row = table.find('tr')
for tagname, cell in izip(cycle(('date', 'time', 'location')),
table_row.findAll('td')):
if tagname == 'date':
writer.start('event')
writer.start(tagname)
writer.data(cell.contents[0])
writer.end(tagname)
if tagname == 'location':
writer.end('event')
writer.end('events')
if __name__ == '__main__':
convert(source, sys.stdout)
Hallo BlackJack,
klappt wunderbar! Denke das ich mit dem XML File besser arbeiten kann. Allerdings noch eine Frage: Die Ausgabe sieht zur Zeit so aus:
<events><event><date>19.08.2006</date><time>15:00</time><location>Hamburg</locat
ion></event><event><date>20.08.2006</date><time>15:00</time><location>Muenchen</
location></event></events>
Damit ich es besser lesen könnte, müsste ich mit Zeilenumbrüche und Einrückungen arbeiten. Wie könnte ich nach <events> ein Zeilenumbruch einfügen und <event> um ein Tab einrücken?
Gruß
Lord Hong
klappt wunderbar! Denke das ich mit dem XML File besser arbeiten kann. Allerdings noch eine Frage: Die Ausgabe sieht zur Zeit so aus:
<events><event><date>19.08.2006</date><time>15:00</time><location>Hamburg</locat
ion></event><event><date>20.08.2006</date><time>15:00</time><location>Muenchen</
location></event></events>
Damit ich es besser lesen könnte, müsste ich mit Zeilenumbrüche und Einrückungen arbeiten. Wie könnte ich nach <events> ein Zeilenumbruch einfügen und <event> um ein Tab einrücken?
Gruß
Lord Hong
An den entsprechenden Stellen die Zeichen mit `writer.data()` einfügen:
Aber wer will schon XML lesen.
Code: Alles auswählen
def convert(source, out_file):
soup = BeautifulSoup(source)
writer = XMLWriter(out_file)
writer.start('events')
writer.data('\n')
table = soup.find('table')
table_row = table.find('tr')
for tagname, cell in izip(cycle(('date', 'time', 'location')),
table_row.findAll('td')):
if tagname == 'date':
writer.start('event')
writer.data('\n')
writer.data(' ')
writer.start(tagname)
writer.data(cell.contents[0])
writer.end(tagname)
writer.data('\n')
if tagname == 'location':
writer.end('event')
writer.data('\n')
writer.end('events')
writer.data('\n')
Also nein, es ist einfach zu verzweifeln. In meinem Beispiel ist ein kleiner Fehler.
Nun dachte ich, es ist wohl kein Problem ein while oder for Schleife darum zu legen. Alles was ich versucht habe, ist gescheitert.
funktioniert nicht. Mir gelingt es noch nicht mal counter ausgeben lassen.
endet in einer Endlosschleife, obwohl mir nicht ganz klar ist wieso.
Wie debuggt ich eigentlich unter Python? Ist so was möglich?
Gruß
Lord Hong
Drei TD Elemente werden von einem TR Element umgeben.<table>
<tr>
<td>19.08.2006</td><td>15:00</td><td>Hamburg</td>
</tr>
<tr>
<td>20.08.2006</td><td>15:00</td><td>München</td>
</tr>
</table>
Nun dachte ich, es ist wohl kein Problem ein while oder for Schleife darum zu legen. Alles was ich versucht habe, ist gescheitert.
Code: Alles auswählen
counter = table.find('tr') / 2
while counter:
Code: Alles auswählen
while table.find('tr'):
[...]
table.find('tr')
Wie debuggt ich eigentlich unter Python? Ist so was möglich?
Gruß
Lord Hong
Na das macht die Sache etwas regelmässiger und damit einfacher.lord.hong hat geschrieben:Also nein, es ist einfach zu verzweifeln. In meinem Beispiel ist ein kleiner Fehler.
Drei TD Elemente werden von einem TR Element umgeben.<table>
<tr>
<td>19.08.2006</td><td>15:00</td><td>Hamburg</td>
</tr>
<tr>
<td>20.08.2006</td><td>15:00</td><td>München</td>
</tr>
</table>
`table.find()` ist ja auch nicht durch zwei Teilbar. Das Ergebnis ist ein `Tag` Objekt das die erste Tabellenzeile in der Tabelle repräsentiert.funktioniert nicht. Mir gelingt es noch nicht mal counter ausgeben lassen.Code: Alles auswählen
counter = table.find('tr') / 2 while counter:
Weil der Ausdruck in der ``while`` Schleife jedesmal das erste <tr>-Element in der Tabelle findet. Das ist ein "wahres" Objekt, also wird die Schleife ewig ausgeführt.endet in einer Endlosschleife, obwohl mir nicht ganz klar ist wieso.Code: Alles auswählen
while table.find('tr'): [...] table.find('tr')
Es gibt auch IDEs mit "richtigem" Debugger, aber ich benutze meistens ``print``-Anweisungen und probiere im interaktiven Interpretierer aus. Dein Beispiel interaktiv untersucht:Wie debuggt ich eigentlich unter Python? Ist so was möglich?
Code: Alles auswählen
In [145]: source = '''\
.....: <table>
.....: <tr><td>19.08.2006</td><td>15:00</td><td>Hamburg</td></tr>
.....: <tr><td>20.08.2006</td><td>15:00</td><td>München</td></tr>
.....: </table>
.....: '''
In [146]: table = BeautifulSoup.BeautifulSoup(source)
In [147]: rows = table.findAll('tr')
In [148]: rows
Out[148]:
[<tr><td>19.08.2006</td><td>15:00</td><td>Hamburg</td></tr>,
<tr><td>20.08.2006</td><td>15:00</td><td>München</td></tr>]
In [149]: rows[0].findAll('td')
Out[149]: [<td>19.08.2006</td>, <td>15:00</td>, <td>Hamburg</td>]
Code: Alles auswählen
import sys
from BeautifulSoup import BeautifulSoup
from elementtree.SimpleXMLWriter import XMLWriter
source = '''\
<table>
<tr><td>19.08.2006</td><td>15:00</td><td>Hamburg</td></tr>
<tr><td>20.08.2006</td><td>15:00</td><td>München</td></tr>
</table>
'''
def convert(source, out_file):
soup = BeautifulSoup(source)
writer = XMLWriter(out_file)
writer.start('events')
writer.data('\n')
table = soup.find('table')
for table_row in table.findAll('tr'):
writer.start('event')
writer.data('\n')
for tagname, cell in zip(('date', 'time', 'location'),
table_row.findAll('td')):
writer.data(' ')
writer.start(tagname)
writer.data(cell.contents[0])
writer.end(tagname)
writer.data('\n')
writer.end('event')
writer.data('\n')
writer.end('events')
writer.data('\n')
if __name__ == '__main__':
convert(source, sys.stdout)
Vielen Dank BlackJack,
ich war inzwischen auch dicht davor, dass Problem zu lösen. Immerhin ist mir klar geworden voran ich gescheitert bin. Ich dachte die ganze Zeit table_row wäre ein String Objekt. Mit dieser Annahme lag ich total falsch. Nun verstehe ich auch warum sich der Interpreter die ganze Zeit drüber beschwert hat, dass er es sich um keinen Integer handelt, wenn ich find aufgerufen hatte. Da mit dem Tupel sollte auch Klick gemacht haben.
Das Ganze verhält sich wie ein XML Baum.
Ich höre für heute auf, bin aber schon auf das nächste Problem gestossen. Es gibt ein Element, welches leer ist, dann bekomme ich eine Exception.
<locationTraceback (most recent call last):
File "test1.py", line 62, in ?
convert(source, sys.stdout)
File "test1.py", line 53, in convert
writer.data(cell.contents[0])
IndexError: list index out of range
Vermutlich habe ich zwei Möglichkeiten, die Exception fangen und dafür zu sorgen, das der XML Tag leer bleibt oder schon vorher das leere HTML Tag ausfiltern. Aber wie gesagt, für heute bin ich mit meinem Einstand in Python zufrieden, obwohl mir das 900 Seiten Buch neben mir gar nicht weiterhelfen konnte.
Das geschützte Leerzeichen muss ich auch noch rausfiltern, sieht etwas kryptisch aus im XML File. Deutsche Sonderzeichen sind auch noch nicht ok.
ich war inzwischen auch dicht davor, dass Problem zu lösen. Immerhin ist mir klar geworden voran ich gescheitert bin. Ich dachte die ganze Zeit table_row wäre ein String Objekt. Mit dieser Annahme lag ich total falsch. Nun verstehe ich auch warum sich der Interpreter die ganze Zeit drüber beschwert hat, dass er es sich um keinen Integer handelt, wenn ich find aufgerufen hatte. Da mit dem Tupel sollte auch Klick gemacht haben.
Das Ganze verhält sich wie ein XML Baum.
Ich höre für heute auf, bin aber schon auf das nächste Problem gestossen. Es gibt ein Element, welches leer ist, dann bekomme ich eine Exception.
<locationTraceback (most recent call last):
File "test1.py", line 62, in ?
convert(source, sys.stdout)
File "test1.py", line 53, in convert
writer.data(cell.contents[0])
IndexError: list index out of range
Vermutlich habe ich zwei Möglichkeiten, die Exception fangen und dafür zu sorgen, das der XML Tag leer bleibt oder schon vorher das leere HTML Tag ausfiltern. Aber wie gesagt, für heute bin ich mit meinem Einstand in Python zufrieden, obwohl mir das 900 Seiten Buch neben mir gar nicht weiterhelfen konnte.
Das geschützte Leerzeichen muss ich auch noch rausfiltern, sieht etwas kryptisch aus im XML File. Deutsche Sonderzeichen sind auch noch nicht ok.
Du kannst testen ob es einen Inhalt in `tag.contents` gibt.lord.hong hat geschrieben:Vermutlich habe ich zwei Möglichkeiten, die Exception fangen und dafür zu sorgen, das der XML Tag leer bleibt oder schon vorher das leere HTML Tag ausfiltern.
Das `` `` ist in XML im allgemeinen auch gar nicht gültig. Man kann dem `BeautifulSoup` Objekt mit auf den Weg geben welche Kodierung der HTML-Quelltext verwendet und das HTML-Entities dekodiert werden sollen:Das geschützte Leerzeichen muss ich auch noch rausfiltern, sieht etwas kryptisch aus im XML File. Deutsche Sonderzeichen sind auch noch nicht ok.
Code: Alles auswählen
import sys
from BeautifulSoup import BeautifulSoup
from elementtree.SimpleXMLWriter import XMLWriter
source = '''\
<table>
<tr><td>19.08.2006</td><td>15:00</td><td>Hamburg</td></tr>
<tr><td>20.08.2006</td><td>15:00</td><td>München</td></tr>
<tr><td>No break</td><td></td><td></td></tr>
</table>
'''
def convert(source, out_file):
soup = BeautifulSoup(source,
fromEncoding='utf-8',
convertEntities=BeautifulSoup.HTML_ENTITIES)
writer = XMLWriter(out_file)
writer.start('events')
writer.data('\n')
table = soup.find('table')
for table_row in table.findAll('tr'):
writer.start('event')
writer.data('\n')
for tagname, cell in zip(('date', 'time', 'location'),
table_row.findAll('td')):
writer.data(' ')
writer.start(tagname)
if len(cell) > 0:
writer.data(cell.contents[0])
writer.end(tagname)
writer.data('\n')
writer.end('event')
writer.data('\n')
writer.end('events')
writer.data('\n')
if __name__ == '__main__':
convert(source, sys.stdout)
Code: Alles auswählen
<events>
<event>
<date>19.08.2006</date>
<time>15:00</time>
<location>Hamburg</location>
</event>
<event>
<date>20.08.2006</date>
<time>15:00</time>
<location>München</location>
</event>
<event>
<date>No break</date>
<time />
<location />
</event>
</events>
Hallo BlackJack,
nach dem mein Beispielprogramm ohne Problem läuft, habe ich es mit der eigentlichen Homepageseite versucht, mit der es laufen soll.
Nun hatte jedes <td> Element noch ein <font> Element. Das Problem hatte ich mit relativ schnell gelöst.
Dummerweise hat aber ein Element noch einen geschlossenes Image Tag.
sehen, dass der font Tag-Name ausgedruckt wird. Mit wird mir der img Tag-Name ausgegeben. Aber ich komme nicht an den Inhalt (München).
Sowohl als auch führen zu "IndexError: list index out of range". Ich hatte dann auch mit [1] und [2] versucht, weil ich [0] wäre das Image Element und [1] dann der Inhalt.
Kannst du mir nochmal helfen?
Gruß
Lord Hong
nach dem mein Beispielprogramm ohne Problem läuft, habe ich es mit der eigentlichen Homepageseite versucht, mit der es laufen soll.
Nun hatte jedes <td> Element noch ein <font> Element. Das Problem hatte ich mit
Code: Alles auswählen
writer.data(cell.next.contents[0])
Dummerweise hat aber ein Element noch einen geschlossenes Image Tag.
Nun kann ich mir mit<location><font><img/>München</font><location>
Code: Alles auswählen
print cell.next.name
Code: Alles auswählen
print cell.next.next.name
Sowohl
Code: Alles auswählen
cell.next.contents[0]
Code: Alles auswählen
cell.next.next.contents[0]
Kannst du mir nochmal helfen?
Gruß
Lord Hong
Hier kann auch wieder das rumspielen mit dem interaktiven Interpretierer helfen. Damit kann man den `BeatifulSoup` Baum einfach untersuchen und einiges ausprobieren.
Wie man sieht enthält das <font> Tag zwei Kinder. Ein Image-Tag und einen Text-Knoten. Die letzte Variante ist ein bischen sicherer, weil sich die Anzahl der Elemente ändert, wenn zusätzliche Zeilenumbrüche zwischen den Tags vorkommen können.
Code: Alles auswählen
In [24]: soup
Out[24]: <td><font><img />München</font></td>
In [25]: soup.td.font
Out[25]: <font><img />München</font>
In [26]: soup.td.font.contents
Out[26]: [<img />, u'M\xfcnchen']
In [27]: soup.td.font.contents[1]
Out[27]: u'M\xfcnchen'
In [28]: soup.td.font.img.next
Out[28]: u'M\xfcnchen'
Hallo BlackJack,
ein herzliches Dankeschön an dich. Ich kann jetzt die Daten aus dem Internet lesen und sie in ein XML Datei schreiben. Es ist viel weniger Code als ich dachte. Das mit dem interaktiven Mode hat leider nicht geklappt. Sowohl mit python -i test1.py oder zeilenweise Eingabe in >>> gaben nicht mehr Ergebnis aus als ich gebraucht hätte.
Allerdings bin ich nun zufrieden mit dem was ich habe und denke, dass es nun leichter sein sollte ein XML File auszuwerten.
Nochmals Vielen Dank und sollte ich für die statische Auswertung Fragen haben, dann werde ich sie hier im Forum posten.
Gruß
Lord Hong
ein herzliches Dankeschön an dich. Ich kann jetzt die Daten aus dem Internet lesen und sie in ein XML Datei schreiben. Es ist viel weniger Code als ich dachte. Das mit dem interaktiven Mode hat leider nicht geklappt. Sowohl mit python -i test1.py oder zeilenweise Eingabe in >>> gaben nicht mehr Ergebnis aus als ich gebraucht hätte.
Allerdings bin ich nun zufrieden mit dem was ich habe und denke, dass es nun leichter sein sollte ein XML File auszuwerten.
Nochmals Vielen Dank und sollte ich für die statische Auswertung Fragen haben, dann werde ich sie hier im Forum posten.
Gruß
Lord Hong