Jak uzyskać tytuł strony HTML wyświetlany w UIWebView?

145

Muszę wyodrębnić zawartość tagu tytułu ze strony HTML wyświetlanej w UIWebView. Jaki jest najsolidniejszy sposób, aby to zrobić?

Wiem, że potrafię:

- (void)webViewDidFinishLoad:(UIWebView *)webView{
    NSString *theTitle=[webView stringByEvaluatingJavaScriptFromString:@"document.title"];
}

Jednak działa to tylko wtedy, gdy włączony jest javascript.

Ewentualnie mógłbym po prostu zeskanować tekst kodu HTML w celu znalezienia tytułu, ale wydaje się to nieco kłopotliwe i może okazać się kruche, jeśli autorzy strony wpadną w wir swojego kodu. Jeśli chodzi o to, jaka jest najlepsza metoda przetwarzania tekstu HTML w iPhone API?

Czuję, że zapomniałem o czymś oczywistym. Czy istnieje lepsza metoda niż te dwie opcje?

Aktualizacja:

Z odpowiedzi na to pytanie wynika: UIWebView: Can You Disable Javascript? wydaje się, że nie ma możliwości wyłączenia JavaScript w UIWebView. Dlatego powyższa metoda Javascript zawsze będzie działać.

TechZen
źródło
1
+1 Musiałem też skorzystać z metody @ "document.title".
Dave DeLong,
Właśnie tego szukałem i miałem przerażające wizje parsowania kodu HTML. Bardzo sprytne rozwiązanie.
margusholland,
Zobacz także następującą odpowiedź na podobne pytanie SO: stackoverflow.com/a/2313430/908621
fishinear
W tym portalu jest wiele linków, takich jak: stackoverflow.com/questions/11704560/… lub stackoverflow.com/questions/2301468/…
Kamil Wozniak
Społeczność wsparcia Apple również ma tę samą odpowiedź
Daniel

Odpowiedzi:

88

Dla tych, którzy po prostu przewiń w dół, aby znaleźć odpowiedź:

- (void)webViewDidFinishLoad:(UIWebView *)webView{
    NSString *theTitle=[webView stringByEvaluatingJavaScriptFromString:@"document.title"];
}

To zawsze będzie działać, ponieważ nie ma możliwości wyłączenia JavaScript w UIWebView.

Brigham
źródło
używając tego, jeśli kodowanie strony internetowej nie jest „utf-8”, tytuł byłby niechlujny.
Xiao
A co z Swift 4?
Jayprakash Dubey
4

WKWebView ma właściwość „title”, po prostu zrób to w ten sposób,

func webView(_ wv: WKWebView, didFinish navigation: WKNavigation!) {
    title = wv.title
}

Myślę, że nie UIWebViewjest teraz odpowiedni.

DawnSong
źródło
3

Jeśli włączona jest obsługa JavaScript, użyj tego: -

NSString *theTitle=[webViewstringByEvaluatingJavaScriptFromString:@"document.title"];

Jeśli JavaScript jest wyłączony, użyj tego: -

NSString * htmlCode = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"http://www.appcoda.com"] encoding:NSASCIIStringEncoding error:nil];
NSString * start = @"<title>";
NSRange range1 = [htmlCode rangeOfString:start];

NSString * end = @"</title>";
NSRange range2 = [htmlCode rangeOfString:end];

NSString * subString = [htmlCode substringWithRange:NSMakeRange(range1.location + 7, range2.location - range1.location - 7)];
NSLog(@"substring is %@",subString);

Użyłem +7 i -7 w NSMakeRange, aby wyeliminować długość <title>np. 7

Pawandeep Singh
źródło
Czy możesz teraz wyłączyć Javascript w UIWebview? W 2010 roku nie mogłeś.
TechZen
Nie wiem o IOS przed IOS 8, ale możesz to zrobić, przejdź do Ustawienia -> Safari -> Zaawansowane -> Javascript On / Off
Pawandeep Singh
Skąd wiesz, czy JavaScript jest włączony czy wyłączony w kodzie?
Eddie
2

Edycja: właśnie widziałem, jak znalazłeś odpowiedź ... sheeeiiitttt

Dosłownie właśnie się tego nauczyłem! Aby to zrobić, nie musisz nawet wyświetlać go w UIWebView. (Ale ponieważ go używasz, możesz po prostu uzyskać adres URL bieżącej strony)

Tak czy inaczej, oto kod i jakieś (słabe) wyjaśnienie:

    //create a URL which for the site you want to get the info from.. just replace google with whatever you want
    NSURL *currentURL = [NSURL URLWithString:@"http://www.google.com"];
    //for any exceptions/errors
    NSError *error;
    //converts the url html to a string
    NSString *htmlCode = [NSString stringWithContentsOfURL:currentURL encoding:NSASCIIStringEncoding error:&error];

Mamy więc kod HTML, a teraz jak uzyskać tytuł? Cóż, w każdym dokumencie opartym na html tytuł jest sygnalizowany przez To jest tytuł, więc prawdopodobnie najłatwiejszą rzeczą do zrobienia jest wyszukanie tego ciągu htmlCode dla i dla oraz podciągnięcie go, aby uzyskać zawartość pomiędzy.

    //so let's create two strings that are our starting and ending signs
    NSString *startPoint = @"<title>";
    NSString *endPoint = @"</title>";
    //now in substringing in obj-c they're mostly based off of ranges, so we need to make some ranges
    NSRange startRange = [htmlCode rangeOfString:startPoint];
    NSRange endRange = [htmlCode rangeOfString:endPoint];
    //so what this is doing is it is finding the location in the html code and turning it
    //into two ints: the location and the length of the string
    //once we have this, we can do the substringing!
    //so just for easiness, let's make another string to have the title in
    NSString *docTitle = [htmlString substringWithRange:NSMakeRange(startRange.location + startRange.length, endRange.location)];
    NSLog(@"%@", docTitle);
    //just to print it out and see it's right

I to naprawdę wszystko! Zasadniczo, aby wyjaśnić wszystkie shenanigans zachodzące w docTitle, gdybyśmy utworzyli zakres po prostu mówiąc NSMakeRange (startRange.location, endRange.location), otrzymalibyśmy tytuł ORAZ tekst startString (czyli), ponieważ lokalizacja jest pierwszy znak ciągu. Aby to zrównoważyć, dodaliśmy po prostu długość łańcucha

Teraz pamiętaj, że ten kod nie jest testowany ... jeśli są jakieś problemy, może to być błąd ortograficzny lub że nie dodałem / nie dodałem wskaźnika, gdy nie powinienem.

Jeśli tytuł jest trochę dziwny i nie do końca poprawny, spróbuj pomieszać z NSMakeRange - mam na myśli dodawanie / odejmowanie różnych długości / lokalizacji ciągów - wszystko, co wydaje się logiczne.

Jeśli masz jakieś pytania lub są jakieś problemy, nie wahaj się zapytać. To moja pierwsza odpowiedź na tej stronie, więc przepraszam, jeśli jest trochę zdezorganizowana

user3016226
źródło
1

Oto wersja Swift 4, na podstawie odpowiedzi tutaj

func webViewDidFinishLoad(_ webView: UIWebView) {
    let theTitle = webView.stringByEvaluatingJavaScript(from: "document.title")
}
Nizzam
źródło
0

Nie mam do tej pory doświadczenia z przeglądaniem stron internetowych, ale wydaje mi się, że ustawia to tytuł jako tytuł strony, więc sugeruję, aby użyć kategorii w widoku internetowym i nadpisać ustawiacz dla self.title, aby dodać wiadomość do jeden z was sprzeciwi się lub zmodyfikuje jakąś właściwość, aby uzyskać tytuł.

Czy możesz mi spróbować powiedzieć, czy to działa?

Rozwój RP
źródło
0

Jeśli potrzebujesz go często w swoim kodzie, sugeruję dodanie funkcji do „rozszerzenia UIWebView” w ten sposób

extension UIWebView {

func title() -> String{
    let title: String = self.stringByEvaluatingJavaScript(from: "document.title")!
    return title
}

alternatywnie lepiej jest użyć WKWebView.

Niestety nie jest dobrze obsługiwany w ARKit. Musiałem zrezygnować z WKWebView. Nie mogłem załadować strony internetowej do webView. Jeśli ktoś ma tutaj rozwiązanie tego problemu -> mam podobny problem, to bardzo by pomogło.

MasterNaz
źródło