2016-07-30 17 views
0

Für die folgende Eingabe ändert lxml die div, als ob es versteht, dass div nicht innerhalb sein kann.lxml erkennt leeres div nicht wie erwartet

Kann mir jemand sagen, wie man nur die <div></div> für diese Art von Eingabe bekommen? Ich möchte den Eingabe-HTML-Code korrigieren.

Muss ich zu BeautifulSoup wechseln?

from lxml import etree 

html_string = """ 
<html> 
<head> 
    <title></title> 
</head> 
<body> 
    <p align="center"> 
    <div></div> 
    This line should be centered. 
    </p> 
    <table> 
    <tbody> 
     <tr> 
     <td> 
     <div></div> 
     </td> 
     </tr> 
    </tbody> 
    </table> 
</body> 
</html> 
""" 

html_element = etree.fromstring(html_string) 

page_break_elements = html_element.xpath("//div") 

(Pdb) etree.tostring(html_element[1][0][0]) 
b'<div/>\n This line should be centered.\n ' 

Ich möchte nur das untere Element, um es zu bewegen.

<div></div> 

Für alle neugierig sind dies page-break div s für die PDF-Erzeugung verwendet <div style="page-break-after:always"></div> die Seitenumbrüche angeben. Ich bekomme eine Eingabe von TinyMCE, die es nicht richtig positioniert, also versuche ich es auf das body Element zu verschieben.

Ausgabe

Wunsch
from lxml import etree 

html_string = """ 
<html> 
<head> 
    <title></title> 
</head> 
<body> 
    <div></div> 
    <p align="center"> 
    This line should be centered. 
    </p> 
    <div></div> 
    <table> 
    <tbody> 
     <tr> 
     <td> 
     </td> 
     </tr> 
    </tbody> 
    </table> 
</body> 
</html> 
""" 
+0

Ich benutzte BeautifulSoup und schrieb einen Code, um mein Ziel zu erreichen http://codereview.stackexchange.com/questions/136402/correcting-a-div-use-for-page-break-inside-p-by-moving- to-the-body-element – Nishant

+0

Können Sie noch ein paar divs hinzufügen und was erwarten Sie als Ausgabe? –

+0

Ja, jedes solche Div sollte auf Körper-Ebene verschoben werden. Das ist meine gewünschte Ausgabe. Meine Code-Review-Lösung scheint, aber ich muss die Lxml-Lösung testen. – Nishant

Antwort

1

Sie können die soupparser in lxml nutzen und verarbeiten noch die Daten mit XPaths etc ..:

from lxml.html.soupparser import fromstring 

html_element = fromstring(html_string) 

Das wird <div></div> innerhalb der p beibehalten.

+0

@Padriac, Gibt es einen Grund, warum das so in lxml funktioniert? Warum dieser Unterschied? – Nishant

+0

@Nishant, libxml2 versucht, Ihnen richtig strukturierten HTML zu geben, mit souparser ist viel milder. Wenn Sie sich das Meta/Head-Beispiel in den Dokumenten anschauen, ist es ziemlich genau die gleiche Idee, die Sie selbst haben. –

0

Sie müssen einige zusätzliche Argumente zu übergeben, das Verhalten von tostring zu ändern():

etree.tostring(d, method="html", with_tail=False) 
'<div></div>' 
+0

Mein Problem ist nicht die 'tostring', ich wollte page_break_elements unabhängig sein, so dass ich es anderswo übertragen kann. Ich habe auf jeden Fall eine Lösung mit BeautifulSoup erstellt, die jeder überprüfen kann. – Nishant

+1

Ja, lxml hat seine Grenzen. Die Art, wie es auf Syntax überprüft, funktioniert nicht gut mit ausgearbeiteten HTML-Dokumenten. – mljli

+0

Ich bin mir nicht sicher, warum die Down-Abstimmung darüber, aber dass dies ein Schwanz ist, ein wichtiger Input ist, an dem ich arbeiten kann. https://docs.python.org/2/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element.text. Das ist also eine gute Antwort. – Nishant