Frage

Ich möchte aus einer allgemeinen HTML -Seite, dem gesamten Text (angezeigt oder nicht) extrahieren.

Ich möchte Löschen

  • Alle HTML -Tags
  • Jedes JavaScript
  • Alle CSS -Stile

Gibt es einen regelmäßigen Ausdruck (einen oder mehrere), der das erreichen wird?

War es hilfreich?

Lösung

Sie können HTML nicht wirklich mit regulären Ausdrücken analysieren. Es ist zu komplex. Re wird nicht umgehen <![CDATA[ Abschnitte überhaupt korrekt. Darüber hinaus einige Arten von gemeinsamen HTML -Dingen wie &lt;text> Wird in einem Browser als richtiger Text arbeiten, könnte aber einen naiven Re verblüfft.

Mit einem richtigen HTML -Parser werden Sie glücklicher und erfolgreicher sein. Python -Leute benutzen oft etwas Schöne Suppe HTML analysieren und Tags und Skripte ausziehen.


Auch Browser tolerieren massive HTML. Sie werden also oft versuchen, HTML zu analysieren, was eindeutig unangemessen ist, aber in einem Browser in Ordnung ist.

Möglicherweise können Sie schlechte HTML mit REs analysieren. Alles, was es erfordert, ist Geduld und harte Arbeit. Aber es ist oft einfacher, den Parser eines anderen zu verwenden.

Andere Tipps

Entfernen Sie JavaScript und CSS:

<(script|style).*?</\1>

Tags entfernen

<.*?>

Benötigte eine Regex -Lösung (in PHP) Das würde den einfachen Text genauso gut (oder besser als) phpSimpledom zurückgeben, nur viel schneller. Hier ist die Lösung, die ich mir ausgedacht habe:

function plaintext($html)
{
    // remove comments and any content found in the the comment area (strip_tags only removes the actual tags).
    $plaintext = preg_replace('#<!--.*?-->#s', '', $html);

    // put a space between list items (strip_tags just removes the tags).
    $plaintext = preg_replace('#</li>#', ' </li>', $plaintext);

    // remove all script and style tags
    $plaintext = preg_replace('#<(script|style)\b[^>]*>(.*?)</(script|style)>#is', "", $plaintext);

    // remove br tags (missed by strip_tags)
    $plaintext = preg_replace("#<br[^>]*?>#", " ", $plaintext);

    // remove all remaining html
    $plaintext = strip_tags($plaintext);

    return $plaintext;
}

Als ich dies an einigen komplizierten Websites getestet habe (Foren scheinen einen Teil der härteren HTML zu enthalten), gab diese Methode das gleiche Ergebnis wie phpSimpledom -Klartext zurück, nur viel, viel schneller. Es hat auch die Listenelemente (LI -Tags) ordnungsgemäß behandelt, bei denen PhpSimpledom dies nicht getan hat.

Wie für die Geschwindigkeit:

  • Simpledom: 0,03248 Sek.
  • Regex: 0,00087 Sek.

37 -mal schneller!

Es ist entmutigend, dies mit regelmäßigen Ausdrücken zu betrachten. Haben Sie XSLT in Betracht gezogen? Der XPath -Ausdruck, um alle Textknoten in einem XHTML -Dokument, Minus -Skript- und Stilinhalt, zu extrahieren, wäre:

//body//text()[not(ancestor::script)][not(ancestor::style)]

Mit der Perl -Syntax zum Definieren der Regexes könnte ein Start sein:

!<body.*?>(.*)</body>!smi

Anschließend das folgende Ersatz auf das Ergebnis dieser Gruppe anwenden:

!<script.*?</script>!!smi
!<[^>]+/[ \t]*>!!smi
!</?([a-z]+).*?>!!smi
/<!--.*?-->//smi

Dies wird natürlich nicht gut als Textdatei formatiert, aber es streift alle HTML aus (meistens gibt es einige Fälle, in denen es möglicherweise nicht ganz richtig funktioniert). Eine bessere Idee ist es jedoch, einen XML -Parser in jeder Sprache zu verwenden, die Sie verwenden, um das HTML richtig zu analysieren und den Text daraus zu extrahieren.

Der einfachste Weg für einfache HTML (Beispiel in Python):

text = "<p>This is my> <strong>example</strong>HTML,<br /> containing tags</p>"
import re
" ".join([t.strip() for t in re.findall(r"<[^>]+>|[^<]+",text) if not '<' in t])

Gibt dies zurück:

'This is my> example HTML, containing tags'

Hier ist eine Funktion, um selbst die komplexesten HTML -Tags zu entfernen.

function strip_html_tags( $text ) 
{

$text = preg_replace(
    array(
        // Remove invisible content
        '@<head[^>]*?>.*?</head>@siu',
        '@<style[^>]*?>.*?</style>@siu',
        '@<script[^>]*?.*?</script>@siu',
        '@<object[^>]*?.*?</object>@siu',
        '@<embed[^>]*?.*?</embed>@siu',
        '@<applet[^>]*?.*?</applet>@siu',
        '@<noframes[^>]*?.*?</noframes>@siu',
        '@<noscript[^>]*?.*?</noscript>@siu',
        '@<noembed[^>]*?.*?</noembed>@siu',

        // Add line breaks before & after blocks
        '@<((br)|(hr))@iu',
        '@</?((address)|(blockquote)|(center)|(del))@iu',
        '@</?((div)|(h[1-9])|(ins)|(isindex)|(p)|(pre))@iu',
        '@</?((dir)|(dl)|(dt)|(dd)|(li)|(menu)|(ol)|(ul))@iu',
        '@</?((table)|(th)|(td)|(caption))@iu',
        '@</?((form)|(button)|(fieldset)|(legend)|(input))@iu',
        '@</?((label)|(select)|(optgroup)|(option)|(textarea))@iu',
        '@</?((frameset)|(frame)|(iframe))@iu',
    ),
    array(
        ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
        "\n\$0", "\n\$0", "\n\$0", "\n\$0", "\n\$0", "\n\$0",
        "\n\$0", "\n\$0",
    ),
    $text );

// Remove all remaining tags and comments and return.
return strip_tags( $text );
    }

Wenn Sie PHP verwenden, probieren Sie einfache HTML -DOM, die bei SourceForge verfügbar sind.

Andernfalls finden Google HTML2Text und finden Sie eine Vielzahl von Implementierungen für verschiedene Sprachen, die im Grunde genommen eine Reihe regulärer Ausdrücke verwenden, um das gesamte Markup auszusaugen. Seien Sie hier vorsichtig, denn Tags ohne Endungen können manchmal sowie Sonderzeichen wie & (was &) gelassen werden.

Achten Sie auch auf Kommentare und JavaScript, da ich festgestellt habe, dass es besonders ärgerlich für reguläre Ausdrücke ist und warum ich im Allgemeinen nur lieber einfach einen kostenlosen Parser für mich erledigen kann.

Noch sicher diese Seite könnte helfen.

Können Sie nicht einfach die mit C# verfügbare Webbrowser -Steuerung verwenden?

        System.Windows.Forms.WebBrowser wc = new System.Windows.Forms.WebBrowser();
        wc.DocumentText = "<html><body>blah blah<b>foo</b></body></html>";
        System.Windows.Forms.HtmlDocument h = wc.Document;
        Console.WriteLine(h.Body.InnerText);
string decode = System.Web.HttpUtility.HtmlDecode(your_htmlfile.html);
                Regex objRegExp = new Regex("<(.|\n)+?>");
                string replace = objRegExp.Replace(g, "");
                replace = replace.Replace(k, string.Empty);
                replace.Trim("\t\r\n ".ToCharArray());

then take a label and do "label.text=replace;" see on label out put

.

Ich glaube, Sie können einfach tun

document.body.innerText

Dies gibt den Inhalt aller Textknoten im Dokument zurück, sichtbar oder nicht.

Edit (Olliej): seufzen Egal, das funktioniert nur in Safari und IE, und ich kann mich nicht die Mühe machen, einen Firefox-Nachts abzuladen, um zu sehen, ob es in Trunk existiert:-/

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