Text aus HTML Seite extrahieren

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Text aus HTML Seite extrahieren

    Hi,

    ich habe mal wieder ein Problem, bei welchem ich keine Lösung finde. Ich habe irgendeine Nachrichtenseite. Es kann jede auf der Welt sein. Diese Seite lade ich in meine App. Nun muss ich irgendwie an den Text rankommen. Das heißt, mich interessiert nicht die ganze Seite sondern nur der Nachrichtentext und da liegt das Problem. Wie in aller Welt bekomme ich den? Ich habe zwar folgenden Algorithmus geschrieben aber der ist auch nicht das gelbe vom Ei. Wenn jetzt zwischen den Text ein Bild oder ein Video kommt, dann aber der Text weiter geht dann schneidet der mir den Text ab dem Video ab. Was auch nicht Sinn und Zweck ist. Weiterhin wenn am Anfang statt am Ende die ganzen Social Buttons wie Facebook, Twitter und Co stehen werden die auch mit reingenommen. Auch nicht ideal. Jemand eine Idee, wie ich das lösen kann?

    Ich selber finde mein Code, den ich da geschrieben habe grauenvoll und das ist mehr Lücken flickerei aber irgendwie habe ich keine andere Idee. Ich habe schon versucht anhand der HTML-Tags das herauszubekommen aber das geht genauso wenig, denn jede Seite ist anders und der Text fängt mit mehreren Tags an und hört dann wieder auf, dann kommt Skript und dann fängt der Text wieder an.

    Ich bin am verzweifeln! Gibt es da irgendwas, was ein diese Arbeit abnimmt?

    Hier mein Code:

    C-Quellcode

    1. -(NSString *)stringWithoutHTMLContentWithString:(NSString *)htmlString AndTextDescription:(NSString *)textDescription {
    2. NSAttributedString *attributedTextString = [[NSAttributedString alloc] initWithData:[htmlString dataUsingEncoding:NSUTF8StringEncoding] options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: [NSNumber numberWithInt:NSUTF8StringEncoding]} documentAttributes:nil error:nil];
    3. NSMutableString *normalString = [[NSMutableString alloc] init];
    4. NSString *scannerString = [attributedTextString string];
    5. scannerString = [scannerString stringByReplacingOccurrencesOfString:@"•\n\t" withString:@""];
    6. scannerString = [scannerString stringByReplacingOccurrencesOfString:@"\n\t\t" withString:@""];
    7. scannerString = [scannerString stringByReplacingOccurrencesOfString:@"•\t\n" withString:@""];
    8. scannerString = [scannerString stringByReplacingOccurrencesOfString:@"•\t\n\t" withString:@""];
    9. scannerString = [scannerString stringByReplacingOccurrencesOfString:@"\n\n\n" withString:@"//n//n//n "];
    10. scannerString = [scannerString stringByReplacingOccurrencesOfString:@"\n\n\n\n" withString:@"//n//n//n//n"];
    11. scannerString = [scannerString stringByReplacingOccurrencesOfString:@"\n\n" withString:@"//n//n"];
    12. scannerString = [scannerString stringByReplacingOccurrencesOfString:@"◦" withString:@""];
    13. NSScanner *textScanner = [[NSScanner alloc] initWithString:scannerString];
    14. [textScanner scanUpToString:textDescription intoString:nil];
    15. [textScanner scanString:textDescription intoString:nil];
    16. while (![textScanner isAtEnd]) {
    17. NSString *scentences;
    18. [textScanner scanUpToCharactersFromSet:[NSCharacterSet characterSetWithCharactersInString:@",.!?"] intoString:&scentences];
    19. if (scentences && ![scentences isEqualToString:@""]) {
    20. if (scentences.length >= 300) {
    21. break;
    22. } else if ([scentences componentsSeparatedByString:@"\n"].count > 1 && [[scentences componentsSeparatedByString:@"\n"] objectAtIndex:0].length < 10 && ![[[scentences componentsSeparatedByString:@"\n"] objectAtIndex:0] isEqualToString:@"\""]) {
    23. break;
    24. }
    25. NSString *tag;
    26. [textScanner scanCharactersFromSet:[NSCharacterSet characterSetWithCharactersInString:@",.!?"] intoString:&tag];
    27. [normalString appendString:scentences];
    28. if (![tag isEqualToString:@","]) {
    29. [normalString appendString:@"."];
    30. [normalString appendString:@" "];
    31. }
    32. }
    33. }
    34. return normalString;
    35. }
    Alles anzeigen
    Viele Grüße
    Nils
  • Versuchen, HTML selber zu parsen ist grausam und vermutlich fast eine Lebensaufgabe. Nimm' einen Webview, lass' den die Arbeit machen und greife auf den Inhalt z.B. mittels DOM zu. Das gibt's unter OS X direkt als ObjC-Framework auf dem Device nimmst' halt JavaScript und die Methode stringByEvaluatingJavaScriptFromString von UIWebView

    ciao

    gandhi
  • gandhi schrieb:

    Versuchen, HTML selber zu parsen ist grausam und vermutlich fast eine Lebensaufgabe. Nimm' einen Webview, lass' den die Arbeit machen und greife auf den Inhalt z.B. mittels DOM zu. Das gibt's unter OS X direkt als ObjC-Framework auf dem Device nimmst' halt JavaScript und die Methode stringByEvaluatingJavaScriptFromString von UIWebView

    ciao

    gandhi
    Danke für deine Antwort! Was meinst du mit DOM? Kannst du mal bitte ein Beispiel nennen oder irgendwas wo ich mich belesen kann? Denn das hört sich gut an aber ich habe da leider keine Vorstellung, wie ich mit JavaScript den Text herausbekomme.
  • AppleDeveloper schrieb:

    Was meinst du mit DOM?
    DOM = Document Object Model. Such' mal danach, das beschreibt eben das hinter einer HTML-Seite bestehende Objekt-Modell. Implementierungen gibt's eben in Objective-C (die ganzen DOMXXX-Klassen. Nicht gerade toll von Apple dokumentiert.) oder auch in JavaScript. Damit kommst Du z.B. sehr schnell an den Inhalt von bestimmten HTML-Konstrukten (Link mit einer bestimmten ID, oder eben eine Tabelle oder so) ohne dich mit den schier endlosen Sonderfällen von realen HTML-Seiten rumplagen zu müssen (Ganz zu schweigen von dem ganzen JavaScript-Code der heutzutage auf dem Client ausgeführt wird)

    ciao

    gandhi
  • gandhi schrieb:

    AppleDeveloper schrieb:

    Was meinst du mit DOM?
    DOM = Document Object Model. Such' mal danach, das beschreibt eben das hinter einer HTML-Seite bestehende Objekt-Modell. Implementierungen gibt's eben in Objective-C (die ganzen DOMXXX-Klassen. Nicht gerade toll von Apple dokumentiert.) oder auch in JavaScript. Damit kommst Du z.B. sehr schnell an den Inhalt von bestimmten HTML-Konstrukten (Link mit einer bestimmten ID, oder eben eine Tabelle oder so) ohne dich mit den schier endlosen Sonderfällen von realen HTML-Seiten rumplagen zu müssen (Ganz zu schweigen von dem ganzen JavaScript-Code der heutzutage auf dem Client ausgeführt wird)
    ciao

    gandhi
    Ich habe mir das ganze jetzt mal ausführlich angeschaut und durchgelesen! Danke dir erstmal! Man kann damit so wie ich es verstanden habe jede Webseite auseinander nehmen, weil die alle Gleich sind vom der Struktur. Nur mein Problem ist, wenn ich jetzt alle <p> Tags z.B filtere bekomme ich viel mehr als ich brauche. Denn auf so einer Seite stehen Beschreibungen zu anderen Artikel, Kategorien, Kommentare die auch immer in p und div eingebettet sind. Spezielle ID's kann ich ja auch nicht nehmen, denn die sind ja überall anders.

    Habe ich da einen Denkfehler?
  • Was soll denn das Ergebnis von dem Ganzen sein? Für mich hört sich das sehr nach einer rechtlich nicht machbaren App an. Schließlich darfst du nicht einfach irgendwelche Nachrichten von einer Webseite nehmen und in Deiner App ausgeben.
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Thallius schrieb:

    Was soll denn das Ergebnis von dem Ganzen sein? Für mich hört sich das sehr nach einer rechtlich nicht machbaren App an. Schließlich darfst du nicht einfach irgendwelche Nachrichten von einer Webseite nehmen und in Deiner App ausgeben.
    Das ist logisch. Das wäre sonst illegal. Also: Ich habe eine App, welche Nachrichten automatisch auf das wichtigste zusammenkürzt. Damit, dass nicht so aussieht, als wäre der Text von mir steht überall in großer Schrift drunter: "Text gekürzt von: -Link-" sowie man hat die Möglichkeit sich den Originalartikel anzuzeigen und man wird da auf die Seite geleitet.

    Wegen der rechtlichen Sache will ich auch noch mal einen Anwalt konsultieren. Ich habe keine Lust irgendwelchen Ärger mir einzufangen. Wenn jemand eine bessere Lösung hat bezüglich der Quellen bzw. die Nennung so nicht ausreicht bitte immer her mit den Vorschlägen! JederVorschlag ist gerne gesehen!

    Damit ich den Text eben Zusammenfassen kann, brauche ich erstmal den Originaltext. Als Quelle von den Nachrichten dient der RSS-Feed, von welchen ich dann ja eine URL zu dem gesamten Text bekomme. Zum zusammenfassen habe ich einen Algorithmus entwickelt, der auch ganz gut funktioniert. Bitte jetzt keine Kommentare, dass so ein Algorithmus gar nicht gehen kann und das wenn es sowas funktionieren würde das Google schon längst gemacht hätte. Solche Diskussionen musste ich schon oft führen aber nachdem die Leute die App gesehen haben waren sie überzeugt.
  • Ich bin nicht sicher ob du schnell genug mit deinen Updates hinterherkommst wenn Du das auf die Art machst. Vor allem wenn du die Nachrichten von vielen verschiedenen Seiten nimmst, dann wird immer irgendeine mal wieder was ändern und schon geht Deine App nicht mehr. Der User muss dann 10-14 Tage warten bis das Update durch den Review ist und in der Zeit geht dann schon wieder eine andere Nachrichtenseite nicht mehr......

    Ich würde da echt de Finger von lassen. Das kann eigentlich nur in fürchterlichen Bewertungen enden.
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Bei solchen Baustellen setze ich nur noch eine eigene Schnittstelle zwischen die Anwendung und der Quelle der Daten.
    Somit ist sichergestellt, dass die Anwendung immer mit korrekt spezifizierten Daten versorgt wird.

    D.h. ändert sich die ursprüngliche Quelle, dann kann serverseitig an der Schnittstelle (also der Perser etc. dahinter) angepasst werden.
    Somit bleibt die Anwendung unabhängig der Quelle und immer lauffähig.

    Viele Grüße
  • Genauso hatte ich es auch vor. Ich wollte alles in die Objective C Cloud verlagern. Denn Ihr habt vollkommen Recht, es kann immer sein, dass was nicht geht und da 14 Tage warten ist echt immer blöd. Deswegen war das meine Idee.

    Zu den RSS-Feeds: Das sind alles RSS-Feeds. Ich lade davon die Nachrichten aber man bekommt leider bei einen RSS-Feed nur so eine kurze Beschreibung um neugierig zu machen. Nie den gesamten Text. Das ist das blöde.
  • AppleDeveloper schrieb:

    man bekommt leider bei einen RSS-Feed nur so eine kurze Beschreibung um neugierig zu machen. Nie den gesamten Text. Das ist das blöde.
    Nein. Das ist das Design. Wenn mich die kurze Beschreibung/der Teaser nicht interessiert, werde ich mir garantiert nicht den Rest ansehen.
    Dafür den gesamten Inhalt laden zu müssen wäre fatale Bandbreitenverschwendung. ;)
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • Marco Feltmann schrieb:

    AppleDeveloper schrieb:

    man bekommt leider bei einen RSS-Feed nur so eine kurze Beschreibung um neugierig zu machen. Nie den gesamten Text. Das ist das blöde.
    Nein. Das ist das Design. Wenn mich die kurze Beschreibung/der Teaser nicht interessiert, werde ich mir garantiert nicht den Rest ansehen.Dafür den gesamten Inhalt laden zu müssen wäre fatale Bandbreitenverschwendung. ;)
    Ach komm,

    in Zeiten wo jede Email in HTML mit einem Footer mindestens 100k groß ist, wo jede Whatsapp-Mitteilung der Einfachheit halber als Voice-Chat versendet wird, wo jede noch so pisselige Webseite unmengen von Daten an den Browser schickt nur um nöglichst viele Suchmaschienen Optimierungen zu enthalten die den eigentlich Leser überahupt nicht interessieren... ;)
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Marco Feltmann schrieb:

    AppleDeveloper schrieb:

    man bekommt leider bei einen RSS-Feed nur so eine kurze Beschreibung um neugierig zu machen. Nie den gesamten Text. Das ist das blöde.
    Nein. Das ist das Design. Wenn mich die kurze Beschreibung/der Teaser nicht interessiert, werde ich mir garantiert nicht den Rest ansehen.Dafür den gesamten Inhalt laden zu müssen wäre fatale Bandbreitenverschwendung. ;)
    Daa stimmt auch wieder nur wäre es schön, wenn es beide Varianten gibt. Denn so ist es echt schwer einen Parser zu bauen.
  • Marco Feltmann schrieb:

    Dafür den gesamten Inhalt laden zu müssen wäre fatale Bandbreitenverschwendung
    Kommt immer darauf an. Im Wlan/am DSLer ist Bandbreite nun wirklich kein Thema und unterwegs hab ich dann den kompletten Artikel offline zum lesen dabei anstatt nur den RSS Teaser.

    Mach ich mit Reeder + Miniflux so. Miniflux holt mir anstatt den RSS Teaser gleich den gesamten Inhalt (ohne Menüs und Werbung), Reeder lädt das zum Offline lesen aufs iPhone.
  • helmut72 schrieb:

    Marco Feltmann schrieb:

    Dafür den gesamten Inhalt laden zu müssen wäre fatale Bandbreitenverschwendung
    Kommt immer darauf an. Im Wlan/am DSLer ist Bandbreite nun wirklich kein Thema und unterwegs hab ich dann den kompletten Artikel offline zum lesen dabei anstatt nur den RSS Teaser.
    Nicht böse gemeint, aber diese Sichtweise ist viel zu einfach und eigentlich nur von einem Endanwender dahergesagt.
    Für den ist es nämlich nur ein Paket mit z.B. 300kb, das er abholt. Aber für den Server auf dem das betrieben wird ist es ein Upload 300kb multipliziert der Anfragen. Also das Vielfache.
    Und das ist der entscheidende Unterschied! Neben der Serverlast ist der Durchsatz von der Internanbindung der Flaschenhals.

    Deshalb finde ich Dein Argument nichtig…

    Ich wette nen Kaltgetränk nach Wahl, dass das auch der Hauptgrund von Apple mit App Thinning/Slicing ist.
    Weil sie täglich Tonnen an Gigabyte sinnlos hochladen müssen.

    Viele Grüße
  • little_pixel schrieb:

    helmut72 schrieb:

    Marco Feltmann schrieb:

    Dafür den gesamten Inhalt laden zu müssen wäre fatale Bandbreitenverschwendung
    Kommt immer darauf an. Im Wlan/am DSLer ist Bandbreite nun wirklich kein Thema und unterwegs hab ich dann den kompletten Artikel offline zum lesen dabei anstatt nur den RSS Teaser.
    Nicht böse gemeint, aber diese Sichtweise ist viel zu einfach und eigentlich nur von einem Endanwender dahergesagt.Für den ist es nämlich nur ein Paket mit z.B. 300kb, das er abholt. Aber für den Server auf dem das betrieben wird ist es ein Upload 300kb multipliziert der Anfragen. Also das Vielfache.
    Und das ist der entscheidende Unterschied! Neben der Serverlast ist der Durchsatz von der Internanbindung der Flaschenhals.

    Deshalb finde ich Dein Argument nichtig…

    Ich wette nen Kaltgetränk nach Wahl, dass das auch der Hauptgrund von Apple mit App Thinning/Slicing ist.
    Weil sie täglich Tonnen an Gigabyte sinnlos hochladen müssen.

    Viele Grüße
    Ist kein Thema, der RSS Server steht im LAN und es greifen nur wenige zu. Es ist auch für eine Firma wirtschaftlicher, wenn der Außendienstmitarbeiter Hunderte von MB Prospektmaterial im Firmen-LAN synchronisiert anstatt mit Mobilfunk.
    So ist es auch für mich wirtschaftlicher, die Artikel komplett offline dabei zu haben und nicht nur den Teaser.
  • Thallius schrieb:

    Für mich hört sich das sehr nach einer rechtlich nicht machbaren App an. Schließlich darfst du nicht einfach irgendwelche Nachrichten von einer Webseite nehmen und in Deiner App ausgeben.
    Jetzt greife ich das nochmal auf, weil ich ich ebenfalls in der Situation bin und meine App, die ich schon länger privat nutze und zuverlässig funktioniert, kostenlos in den App Store stellen möchte.

    Meine App stellt eine im Auto unmöglich zu lesende Webseite (lokaler Radiosender) mit Verkehrsmeldungen in einer Tabelle dar. Per antapsen zeigt es die komplette Meldung in noch größerer Schrift dar. Zugegeben einfach, aber sehr praktisch und mehr benötige ich nicht.

    Nichts weiteres macht doch ein Webbrowser!? Ein Browser zeigt Webseiten an. Bei dem ist es wieder ok? Warum? Dann bau ich also noch einen Webbrowser mit URL-Zeile und Bookmark-Funktion ein, der dann speziell diese eine Seite im Auto lesbar darstellt und bin wieder im grünen Bereich!?

    Oder wie muss ich das genau verstehen? Mit fehlt jegliche Logik, dass ich das nicht machen darf. Siehe Beispiel Browser. Gibt es einen Link zu dem Thema? Nur weil ich jetzt etwas in den App Store stellen möchte, möchte ich keinen Ärger bekommen.

    Danke!
  • helmut72 schrieb:

    Thallius schrieb:

    Für mich hört sich das sehr nach einer rechtlich nicht machbaren App an. Schließlich darfst du nicht einfach irgendwelche Nachrichten von einer Webseite nehmen und in Deiner App ausgeben.
    Jetzt greife ich das nochmal auf, weil ich ich ebenfalls in der Situation bin und meine App, die ich schon länger privat nutze und zuverlässig funktioniert, kostenlos in den App Store stellen möchte.
    Meine App stellt eine im Auto unmöglich zu lesende Webseite (lokaler Radiosender) mit Verkehrsmeldungen in einer Tabelle dar. Per antapsen zeigt es die komplette Meldung in noch größerer Schrift dar. Zugegeben einfach, aber sehr praktisch und mehr benötige ich nicht.

    Nichts weiteres macht doch ein Webbrowser!? Ein Browser zeigt Webseiten an. Bei dem ist es wieder ok? Warum? Dann bau ich also noch einen Webbrowser mit URL-Zeile und Bookmark-Funktion ein, der dann speziell diese eine Seite im Auto lesbar darstellt und bin wieder im grünen Bereich!?

    Oder wie muss ich das genau verstehen? Mit fehlt jegliche Logik, dass ich das nicht machen darf. Siehe Beispiel Browser. Gibt es einen Link zu dem Thema? Nur weil ich jetzt etwas in den App Store stellen möchte, möchte ich keinen Ärger bekommen.

    Danke!
    du darfst im browser (bzw auf deiner webseite die ein browser darstellt) auch keine fremden inhalte anzeigen ohne dessen erlaubnis zu haben.
    Warum kontaktierst du nicht einfach den lokalen radiosender und fragst die ob sie das erlauben. wenn du das sogar kostenlos machst ohne irgendwelchen hintergedanken werden sie das vielleicht sogar erlauben (außer sie haben selbst nicht die rechte dir die rechte dafür zu geben).