Twitter Clientname aus HTML extrahieren

Für ein kleines Experiment habe ich begonnen, einen Twitter Client zu entwickeln. Details dazu folgen ein anderes mal… Bei der Arbeit mit der Twitter API bin ich über folgende Herausforderung gestolpert: jeder Tweet enthält eine Angabe, mit welchem Twitter Client der Tweet abgesetzt wurde. Diese Angabe ist jedoch in einem HTML Anchor Tag verpackt. Darüber hinaus sind Umlaute und Sonderzeichen kodiert, so wie es sich für HTML gehört. Aus einem “ß” wird also “ß” etc. Gemeinerweise sind auch die spitzen Klammern der HTML Tags kodiert.

Twitter sendet folgendes HTML Tag, wenn ein Tweet über die Weboberfläche eingegeben wurde:

<a href="http://twitter.com/">web</a>

Allerdings sind die Sonderzeichen in diesem Tag kodiert, so dass tatsächlich folgende Zeichenkette auszuwerten ist:

&lt;a href=&quot;http://twitter.com/&quot;&gt;web&lt;/a&gt;

Wie extrahiert man nun den Namen der Twitteranwendung, in diesem Beispiel “web”, aus diesem HTML Tag? Meine erste Idee war, das Problem mit einem regulären Ausdruck zu knacken. Doch damit wäre das Dekodieren der Sonderzeichen noch nicht gelöst. Eine Extraktion des gesuchten Textes mit Hilfe von XElement aus dem .NET Framework scheidet aus dem selben Grund aus. Was tun? Die Suchmaschine meiner Wahl ergab einen interessanten Treffer: das HTML Agility Pack.

Bei diesem Open Source Projekt handelt es sich um ein Framework zur Arbeit mit HTML. Aufgaben wie Kodieren/Dekodieren sind damit leicht zu bewerkstelligen. Und auch die Extraktion des Textes aus dem Anchor Tag ist kein Problem. Der Code dazu sieht wie folgt aus:

private static string ExtractApplicationName(string sourceAsHtml) {    var html = HtmlEntity.DeEntitize(sourceAsHtml);    var node = HtmlNode.CreateNode(html);    return node.InnerText;}

Die Klasse HtmlEntity befasst sich mit dem Kodieren und Dekodieren der Sonderzeichen. Durch die Methode DeEntitize werden die kodierten Sonderzeichen in Ascii Zeichen übersetzt.

Die Klasse HtmlNode repräsentiert einen HTML Knoten. Mit CreateNode wird ein solcher HTML Knoten aus einem String erzeugt. Dabei wird die Zeichenkette geparsed, so dass auf die einzelnen Bestandteile wie beispielsweise den enthaltenen Text zugegriffen werden kann.

Das hier gezeigte Beispiel zeigt nur einen sehr kleinen Ausschnitt aus dem Framework. Es ist beispielsweise möglich, mit XPath Ausdrücken im DOM eines HTML Textes zu navigieren. Auch Verändern lässt sich das HTML. Wer unter .NET mit HTML arbeitet, sollte sich das Framework einmal ansehen.

Kick it on dotnet-kicks.de

5 Responses to “Twitter Clientname aus HTML extrahieren”

  1. Jürgen Gutsch Says:

    Hi Stefan,

    alleine für dieses Beispiel benötigt man weder reguläre Ausdrücke noch das HTML Agility Pack, sondern nur System.Web und System.Xml.Linq und man hat ebenfalls einen Dreizeiler:
    private string ExtractApplicationName(string sourceAsHtml)
    {
    var html = HttpUtility.HtmlDecode(sourceAsHtml);
    var node = XDocument.Parse(html);
    return node.Element(“a”).Value;
    }

  2. Golo Roden Says:

    Hoi Stefan, hoi Jürgen,

    den gleichen Gedanken wie Jürgen hatte ich auch – nur dass man noch nicht mal XDocument bemühen muss, XElement reicht völlig aus, wodurch man sich den Zugriff auf die Element-Funktion sparen kann:

    var twitterClient =
    XElement.Parse(
    HttpUtility.HtmlDecode(
    “<a href="http://twitter.com/">web</a>
    )).Value;

    Viele Grüße,

    Golo

  3. Golo Roden Says:

    PS: @ Stefan: Gibt man HTML-maskierte Sonderzeichen ein, wandelt Dein Blog die um …

  4. Stefan Lieser Says:

    Menno, das war so ein schönes Beispiel ;-)

    Ja Jungs, ihr habt Recht. Da zeigt sich wieder, dass ich kein Webentwickler bin ;-)

    Danke für den Tipp!

  5. Jürgen Gutsch Says:

    Hi Stefan,

    kam vielleicht nicht so rüber, aber das HTML Agility Pack wollte ich garnicht wirklich in Frage stellen. Es gibt tatsächlich auch Situationen in denen das Pack Sinn macht: z. B: “The parser is very tolerant with “real world” malformed HTML” Da würde dann auch kein LinqToXml mehr weiter helfen. ;-)
    Auch für das Beispiel auf CodePlex (http://htmlagilitypack.codeplex.com/wikipage?title=Examples) ist es natürlich eine praktische Hilfe.

    Viele Grüße
    Jürgen