Elementtree & CSS

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
boostpy2005
User
Beiträge: 31
Registriert: Freitag 31. März 2006, 14:15

Hallo zusammen!

Hat jemand Erfahrung mit Elementtree?

Wenn ich table-tag mit CSS gestylt habe und durch Elementtree parsen will, gibt es Problem.

Ganz konkret ist, dass Elementtree zusätzlich ein Attribut für width versehen hat, sogar width als Key und None als Value, obwohl die HTML-Datei ein width hat, nur in einer Class gesetzt wurde.

Wer hat eine Idee oder ein Workaround Lösung?

Vielen Dank!
BlackJack

Bitte die Frage nochmal verständlicher formulieren. Vielleicht mit einem minimalen Beispiel aus Quelltext und Daten, was Du erwartest und was Du stattdessen bekommst.
boostpy2005
User
Beiträge: 31
Registriert: Freitag 31. März 2006, 14:15

BlackJack hat geschrieben:Bitte die Frage nochmal verständlicher formulieren. Vielleicht mit einem minimalen Beispiel aus Quelltext und Daten, was Du erwartest und was Du stattdessen bekommst.
DONE!

Ich habe mehrere HTML-Dateien, je mit einer Tabelle. So will ich alle als einer Datei zusammenfassen, und zwar in einer Tabelle mit allen Zeilen!

Wenn table-tag durch <table class="abc" width="1" cellspacing="0"> das originale ersetzt hat, funktioniert die Funktion!

(Sorry, die Funktion ist eignentlich aus einer Klasse, abgekürzt)
<html>
<head>
</head>
<body >
<table class="abc" cellspacing="0">
</table>
</body>
</html>

Code: Alles auswählen

 
def getHTMLFrame(self, fileName, saved)       
        newHtmlNode = ElementTree.Element("html")
        html = ElementTree.parse(fileName, HTMLTreeBuilder.TreeBuilder())
        htmlNode = html.getroot()
        headNode = self.getHeadContent(htmlNode)
        newHtmlNode.append(headNode)
        bodyNode = ElementTree.Element("body")
        bodyNode = self.setBodyAttributes(htmlNode,bodyNode)
        newHtmlNode.append(bodyNode)
        tableNode = ElementTree.Element("table")
        tableNode = self.setTableAttributes(htmlNode,tableNode)
        thead = self.getTableHeadContent(htmlNode)
        tableNode.append(thead)
        bodyNode.append(tableNode)
        tbodyNode = ElementTree.Element("tbody")
        tbody = self.getTBodyContent(htmlNode)
        if not saved:
            tbodyNode = self.manipulateTRAttributesOfTbody(tbodyNode, tbody)
        else:
            tbodyNode =tbody
        tbodyNode = self.setTBodyAttributes(htmlNode,tbodyNode)
        tableNode.append(tbodyNode)
        return (newHtmlNode, tableNode)

if __name__ == "__main__":
        strObj = StringIO()
        newHtml, tableElement = getHTMLFrame(myFile, False)
        strObj = StringIO()
        testTree =ElementTree.ElementTree(newHtml)
        testTree.write(strObj)
        print strObj.getvalue()

BlackJack

Das ist immer noch nicht viel verständlicher. Zumindest ich habe immer noch nicht verstanden wo das Problem liegt!? Irgend etwas mit Attributen vom `table`-Tag!? In Deinem Quelltext sieht man nirgends wo etwas mit denen gemacht wird.

Bist Du sicher das Du an der entsprechenden Stelle den richtigen Knoten verwendest und dass das HTML genügend nahe an XML ist, um mit einer XML-Bibliothek bearbeitet zu werden?
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Am Rande: Heutzutage sollte man CSS anstelle des width-Attributs für die Breitenangabe (d.h. etwa "width: 123px;") verwenden; vielleicht hilft dir das weiter.
boostpy2005
User
Beiträge: 31
Registriert: Freitag 31. März 2006, 14:15

Y0Gi hat geschrieben:Am Rande: Heutzutage sollte man CSS anstelle des width-Attributs für die Breitenangabe (d.h. etwa "width: 123px;") verwenden; vielleicht hilft dir das weiter.
Genau ist dies mein Problem. Als ich die Attribute in table-tag nach CSS verschoben hat, habe ich das oben genannte Problem mit Elementtree.

Wie gesagt, habe ich als Workaround einfach width="0" wieder bei table-tag hinzufügt.

Ich brauche Hinweis, wie man allegemein solche Workaround-Lösung vermeiden kann.
boostpy2005
User
Beiträge: 31
Registriert: Freitag 31. März 2006, 14:15

BlackJack hat geschrieben:Das ist immer noch nicht viel verständlicher. Zumindest ich habe immer noch nicht verstanden wo das Problem liegt!? Irgend etwas mit Attributen vom `table`-Tag!? In Deinem Quelltext sieht man nirgends wo etwas mit denen gemacht wird.

Bist Du sicher das Du an der entsprechenden Stelle den richtigen Knoten verwendest und dass das HTML genügend nahe an XML ist, um mit einer XML-Bibliothek bearbeitet zu werden?
Hi Blackjack,

Wenn du mit Elementtree beschäftigtest, dann kannst nachvollziehen. Der Fehler tritt (Exception!) auf, wenn man tree.write() aufruft.
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Du willst also zwei bestehende HTML-Tabellen verschmelzen? Kommst du nicht direkt an dessen Daten ran? Diese Lösung hier scheint mir alles andere als elegant zu sein.
boostpy2005
User
Beiträge: 31
Registriert: Freitag 31. März 2006, 14:15

Y0Gi hat geschrieben:Du willst also zwei bestehende HTML-Tabellen verschmelzen? Kommst du nicht direkt an dessen Daten ran? Diese Lösung hier scheint mir alles andere als elegant zu sein.
Richtig! Ich will aus mehreren HTML-Tabellen mit gleicher Struktur aus mehreren Dateien eine HTML-Datei erstellen.

Ja, mir sind die Dateien verfügbar, da ich auf der Server Seite arbeite. Wie kann man besser machen?
BlackJack

boostpy2005 hat geschrieben:Wenn du mit Elementtree beschäftigtest, dann kannst nachvollziehen. Der Fehler tritt (Exception!) auf, wenn man tree.write() aufruft.
Zum Nachvollziehen fehlen mir die nötigen Informationen. Und was ist das denn überhaupt für ein Fehler? Traceback bitte!
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

boostpy2005 hat geschrieben:Ja, mir sind die Dateien verfügbar, da ich auf der Server Seite arbeite. Wie kann man besser machen?
Welche Dateien? HTML-Dateien mit den Tabellen? Oder die richtigen Daten als Flat-/XML-/YAML-/CSV-/Text-/Sonstwas-Files? Oder in der Datenbank?
boostpy2005
User
Beiträge: 31
Registriert: Freitag 31. März 2006, 14:15

BlackJack hat geschrieben:
boostpy2005 hat geschrieben:Wenn du mit Elementtree beschäftigtest, dann kannst nachvollziehen. Der Fehler tritt (Exception!) auf, wenn man tree.write() aufruft.
Zum Nachvollziehen fehlen mir die nötigen Informationen. Und was ist das denn überhaupt für ein Fehler? Traceback bitte!
Danke Blackjack. Hier ist die Traceback:

Code: Alles auswählen

File "c:\dokume~1\xxx\lokale~1\temp\easy_install-_g_zvx\elementtree-1.2.6_20050316-py2.4-win32.egg.tmp\elementtree\ElementTree.py", line 660, in write
  File "c:\dokume~1\xxx\lokale~1\temp\easy_install-_g_zvx\elementtree-1.2.6_20050316-py2.4-win32.egg.tmp\elementtree\ElementTree.py", line 704, in _write
  File "c:\dokume~1\xxx\lokale~1\temp\easy_install-_g_zvx\elementtree-1.2.6_20050316-py2.4-win32.egg.tmp\elementtree\ElementTree.py", line 704, in _write
  File "c:\dokume~1\xxx\lokale~1\temp\easy_install-_g_zvx\elementtree-1.2.6_20050316-py2.4-win32.egg.tmp\elementtree\ElementTree.py", line 694, in _write
  File "c:\dokume~1\xxx\lokale~1\temp\easy_install-_g_zvx\elementtree-1.2.6_20050316-py2.4-win32.egg.tmp\elementtree\ElementTree.py", line 827, in _escape_attrib
  File "c:\dokume~1\xxx\lokale~1\temp\easy_install-_g_zvx\elementtree-1.2.6_20050316-py2.4-win32.egg.tmp\elementtree\ElementTree.py", line 773, in _raise_serialization_error
TypeError: cannot serialize None (type NoneType)
Der Typeerror wurde so verursacht, da Elementtree ein Attribut width=None generiert hat, aber das Attribut ist bei mir in CSS definiert
boostpy2005
User
Beiträge: 31
Registriert: Freitag 31. März 2006, 14:15

Y0Gi hat geschrieben:
boostpy2005 hat geschrieben:Ja, mir sind die Dateien verfügbar, da ich auf der Server Seite arbeite. Wie kann man besser machen?
Welche Dateien? HTML-Dateien mit den Tabellen? Oder die richtigen Daten als Flat-/XML-/YAML-/CSV-/Text-/Sonstwas-Files? Oder in der Datenbank?
HTML-Dateien, die im Server gespeichert sind (irgendwann wurde früher durch anderes Programm generiert. Ich kann nur solche HTML Dateien verwenden!)
BlackJack

boostpy2005 hat geschrieben:Der Typeerror wurde so verursacht, da Elementtree ein Attribut width=None generiert hat, aber das Attribut ist bei mir in CSS definiert
ElementTree erfindet nicht einfach so Attribute, d.h. das muss irgendwo von Dir gesetzt werden oder beim parsen von Deinen Eingabedateien kommen. Wobei immer noch eine interessante Frage ist, wie man ein `None` dorthin bekommt. Das dürfte eigentlich nicht möglich sein, es sei denn man greift direkt auf das `attrib`-Attribut eines Elements zu.
boostpy2005
User
Beiträge: 31
Registriert: Freitag 31. März 2006, 14:15

BlackJack hat geschrieben:
boostpy2005 hat geschrieben:Der Typeerror wurde so verursacht, da Elementtree ein Attribut width=None generiert hat, aber das Attribut ist bei mir in CSS definiert
ElementTree erfindet nicht einfach so Attribute, d.h. das muss irgendwo von Dir gesetzt werden oder beim parsen von Deinen Eingabedateien kommen. Wobei immer noch eine interessante Frage ist, wie man ein `None` dorthin bekommt. Das dürfte eigentlich nicht möglich sein, es sei denn man greift direkt auf das `attrib`-Attribut eines Elements zu.

Code: Alles auswählen

<html>
<head>
<title> Test me </title>
</head>
<body>
<table class="abc" cellspacing="0">
<thead><tr><td> nichts </td></tr></thead>
<tbody> <tr><td> nothing </td></tr></tbody>
</table>	  
</body> 
</html>
Hi Blackjack,

Danke noch einmal für deinen Beitrag.

Ich will nicht nur Fragen stellen, um die anderen zu ängern und mir selbst Spaß daran zu haben.

Wenn du mit dem Package ElementTree obige html Datei parsen und ausschreiben kann, bitte zeige mal deinen Code im Forum!
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Am Rande: Hast du dir mal die XPath-Fähigkeiten von ET angesehen? Damit kannst du einiges an Code sparen und bspw. direkt Tags mit bestimmten Namen beziehen, ohne "manuell" den Baum abzulaufen.
BlackJack

boostpy2005 hat geschrieben:Wenn du mit dem Package ElementTree obige html Datei parsen und ausschreiben kann, bitte zeige mal deinen Code im Forum!

Code: Alles auswählen

In [45]: source = """<html>
   ....:  <head>
   ....:  <title> Test me </title>
   ....:  </head>
   ....:  <body>
   ....:  <table class="abc" cellspacing="0">
   ....:  <thead><tr><td> nichts </td></tr></thead>
   ....:  <tbody> <tr><td> nothing </td></tr></tbody>
   ....:  </table>
   ....:  </body>
   ....:  </html>"""

In [46]: doc = etree.fromstring(source)

In [47]: etree.dump(doc)
<html>
 <head>
 <title> Test me </title>
 </head>
 <body>
 <table cellspacing="0" class="abc">
 <thead><tr><td> nichts </td></tr></thead>
 <tbody> <tr><td> nothing </td></tr></tbody>
 </table>
 </body>
 </html>
Und jetzt überleg mal bitte wie ElementTree hier auf die Idee kommen sollte ein `width`-Attribut einzufügen. ElementTree hat doch gar keine Ahnung von HTML und da soll zufällig ein Attribut aus dem Nichts eingefügt werden, welches in HTML eine Bedeutung hat!?

Falls Dir mein Test zu einfach gewesen sein sollte, dann zeig doch bitte mal selbständig lauffähigen Quelltext bei dem das Problem bei Dir auftritt, so das man das nachvollziehen kann.
boostpy2005
User
Beiträge: 31
Registriert: Freitag 31. März 2006, 14:15

Hi Blackjack,

vielen Dank!

Ich habe herausgefunden, dass ich doch im Code versteckt nach dem Attribut width abgefragt und ohne den Wert zu überprüfen verwendet habe.

Ich hatte noch überlegt, ob ich ein Bug gefunden hätte :roll:

Blackjack und Y0Gi, ich bedanke mich noch einmal bei euch!

Überigens, YoGi, ich werde wahrscheinlich Xpath & XSLT später verwenden, um aus verschachteltem Schema HTML Datei zu generieren.
Antworten