Die beste Weg, um mit der Macht des lxml, um wieder nach einem regulären Ausdruck zu verwenden, etwas in einem HTML-Dokument zu finden

StackOverflow https://stackoverflow.com/questions/2421396

Frage

Ich versuche, einen Text aus einer großen Anzahl von HTML-Dokumenten (Zahlen in den Hunderttausenden) zu rippen. Die Dokumente sind wirklich Formen, sondern sie zeichnen sich durch eine sehr große Gruppe von verschiedenen Organisationen vorbereitet, so gibt es erhebliche Unterschiede in der, wie sie das Dokument erstellen. Zum Beispiel werden die Dokumente in Kapitel unterteilt. Ich könnte den Inhalt des Kapitels 5 aus jedem Dokument extrahiert werden soll, damit ich den Inhalt des Kapitels analysieren kann. Anfangs dachte ich, das wäre leicht, aber es stellt sich heraus, dass die Autoren eine Reihe von nicht-verschachtelten Tabellen im gesamten Dokument verwenden könnten, den Inhalt zu halten, so dass Kapitel n mit td-Tags in einer Tabelle angezeigt werden. Oder sie können andere Elemente verwendet werden, wie beispielsweise p-Tags H-Tags, div-Tags oder anderen Blockebene-Element.

wiederholt Nach dem Versuch lxml zu verwenden, um mir den Anfang und das Ende jedes Kapitels zu helfen zu identifizieren Ich habe festgestellt, dass es viel sauberer ist es, einen regulären Ausdruck zu verwenden, da in jedem Fall, egal, was das einschließende html-Element ist das Kapitel Etikett immer in Form ist

>Chapter #

Es ist ein wenig komplizierter, dass es möglicherweise einige Leerraum oder non-breaking Raum auf unterschiedliche Weise dargestellt werden (oder oder nur Leerzeichen). Dennoch war es trivial einen regulären Ausdruck zu schreiben, den Anfang jedes Abschnitts zu identifizieren. (Beginn eines Abschnitts ist das Ende des vorherigen Abschnitts.)

Aber jetzt will ich lxml verwenden, um den Text raus. Mein Gedanke ist, dass ich wirklich keine andere Wahl, als auf meinen String zu Fuß die enge Tag für das Element zu finden, die den Text, den ich den entsprechenden Abschnitt finden bin mit einschließt.

Das ist hier ist ein Beispiel, bei dem das Element mit dem Kapitel Namen hält, ist ein div

<div style="DISPLAY: block; MARGIN-LEFT: 0pt; TEXT-INDENT: 0pt; MARGIN-RIGHT: 0pt" align="left"><font style="DISPLAY: inline; FONT-WEIGHT: bold; FONT-SIZE: 10pt; FONT-FAMILY: Times New Roman">Chapter 1.&#160;&#160;&#160;Our Beginnings.</font></div>

So vorstellen, ich bin, dass ich an der Stelle beginnen würde, wo ich das Spiel für Kapitel 1 und eine reguläre Ausdrücke eingerichtet, um die nächsten zu finden

</div|</td|</p|</h1 . . .

an dieser Stelle also ich die Art des Elements identifiziert habe meinen Kapitelüberschrift halte

kann ich die gleiche Logik verwenden den gesamten Text zu finden, die in diesem Element ist, das einen regulären Ausdruck eingerichtet ist, mir zu helfen Marke von

>Chapter 1.&#160;&#160;&#160;Our Beginnings.<

So habe ich erkannt, wo mein Kapitel 1 beginnt

Ich kann das gleiche tun für Kapitel 2 (wo Kapitel 1 Enden)

Jetzt habe ich stelle mir vor, dass ich das Dokument bei der Eröffnung des Elements beginnen schnippeln werde, die ich als das Element identifiziert die anzeigt, wo Kapitel 1 beginnt und endet kurz vor der Eröffnung des Elements, das ich als das Element identifiziert, zeigt an, wo Kapitel 2 beginnt. Die Zeichenfolge, die ich identifiziert haben, werden dann lxml zugeführt werden, um seine Macht zu nutzen, um den Inhalt zu erhalten.

ich gehe zu allen diesen Problemen, weil ich gelesen habe, immer und immer wieder - nie einen regulären Ausdruck Inhalt von HTML-Dokumenten zu extrahieren und ich habe nicht auf eine Art und Weise trifft so genau mit lxml, um den Ausgang zu identifizieren und zu beenden Standorte für den Text, den ich extrahieren möchten. Zum Beispiel kann ich nie sicher sein, dass der Untertitel des Kapitels 1 Unsere Anfänge sind, könnte es unser Red Canary sein. Lassen Sie uns sagen, dass ich zwei mit lxml festen Tagen damit verbracht, zuversichtlich zu sein, dass ich den Anfang und das Ende Element hatte und ich konnte nur genau sein, <60% der Zeit, aber ein sehr kurzen regulären Ausdrucks hat ich besser als 95% Erfolg.

Ich habe eine Tendenz, die Dinge komplizierter als nötig zu machen, so frage ich mich, ob jemand ein ähnlichen Probleme gesehen oder gelöst hat, und wenn sie einen Ansatz haben (nicht die Details wohlgemerkt), die sie anbieten möchten.

War es hilfreich?

Lösung 3

Wie ich befürchtet habe es keine systematische Art und Weise ist lxml zu verwenden, zu identifizieren und zu extrahieren, was ich brauche. O h gut ich alle schätzen läuten in. Hinweis-dies nicht die Schuld der lxml ist, ist es die Schuld der inkonsistenten HTML-Codierung ist. Zum Beispiel. Da ein Kapitel eine vernünftige Aufteilung eines Dokuments alle Inhalte in einem Kapitel ist, sollte in irgendeiner Art von Element gewickelt werden. Wahrscheinlich ist die flexibelste wäre ein div-Tag mit der nachfolgenden div das nächste Kapitel zu sein. Dies wäre ein Kapitel eines Zweig des Baumes machen. Leider, während etwa 20% der Dokumente, die gut strukturiert sein, könnte die andere nicht.

ich für jede Art von Element testen konnte, dass mein Gehalt halten sollte (div, p) und alle seine Kinder und alle seine Geschwister greifen, bis ich auf das nächste Element dieser Art erhalten, die Informationen hat, die mich informiert, dass wir sind am Ende des Abschnitts (Anfang des nächsten Abschnitts). Aber dies scheint, wie zu viel Arbeit, wenn ich bin gut 95% der Zeit oder mehr mit einem regulären Ausdruck.

Danke für alle Antworten und Kommentare wie immer ich learnded von ihnen.

Andere Tipps

Manchmal ist es nicht einen geraden Weg, den Inhalt zu bekommen, wenn sie mit schlecht oder inkonsistent geschrieben HTML handelt.

Sie könnten mit Luchs oder einer der textbasierten Browser aussehen wollen den Seiteninhalt zu entleeren, entweder in eine Datei oder in Ihr Code Rohr und verarbeiten sie dann. Oder Sie können lxml verwenden, um die Seite zu laden und zu analysieren, dann extrahieren den Text mit TEXT_CONTENT () und gehen nach den Kapiteln über regex.

Wie sie sagen, GIGO - garbage in, garbage out, und es ist unsere Aufgabe als Entwickler, dass Müll zu Gold spinnt. Dadurch kann ziemlich chaotisch.

Die einfachste Sache, es klingt wie Sie vielleicht ist tun könnte Iterierte über tree.getroot (). Iterdescendants () für einen Knoten mit node.text, die Ihre gewünschten regulären Ausdruck übereinstimmt. Ab diesem Zeitpunkt können Sie den Knoten an eine Funktion, die einige Ad-hoc-Heuristik verwendet, um zu bestimmen, wo der Text ist. (Vielleicht, wenn iterdescendants auf root ist man zu langsam Ihren regex Ansatz und tauchen Sie ein in etree verwenden kann, um zu versuchen, eine f(text_position) -> node Funktion zu finden.)

Zum Beispiel, wenn Sie feststellen, dass das Ziel eine //tr/td war, können Sie es zu einem gewissen Tisch-Text Findungsunterprogramm übergeben kann, die in die nächste td in node.parent sah (), um zu sehen, ob es sich um Text hat, die Sinn macht ( etwa Kapitel Länge, die bestimmte Worte, was auch immer). Ebenso können Sie einige Heuristiken zum Auffinden der Daten in anderen Tags wie div und p bilden. Wenn Sie sich in einem unbekannten Tag wie font finden können Sie versuchen, eine begrenzte Anzahl von Ebenen sprudeln, etwas zu finden, wie zu handhaben - Sie haben bis zu weit nicht zu sprudeln, vorsichtig zu sein, oder ich denke, Sie versehentlich Text abrufen können von einem anderen Kapitel.

Der Kern des Problems zu sein scheint, dass Sie Daten Bergbau, die nicht programmatisch in einer programmatischen Art und Weise präsentiert wird -. In diesen Fällen der menschliche Interaktion ist in der Regel notwendig, bis zu einem gewissen Grad

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top