如何从 WKWebView 中的网页获取所有呈现的文本?

How to get all rendered text from a web page in a WKWebView?

主要目标

完全按照此页面的方式进行操作:textise.net

次要目标

像 Safari 中的 Reader View 一样提供 reader 友好的网站版本。

艰难的道路

我写了一个自定义的 WKWebView class 和一个自定义的导航委托来实现这个函数来获取 HTML 代码:

- (void)getHTMLCodeWithCompletionHandler:(void (^)(NSString *htmlCode))completionHandler

我使用 HTMLKit 库来解析 HTML 代码并搜索 DOM。这就是一切的运作方式:

#pragma mark - SNWebViewNavigationDelegate

- (void)webViewDidFinishNavigation:(SNWebView *)webView {
    
    [webView getHTMLCodeWithCompletionHandler:^(NSString *htmlCode){
        
        HTMLParser *parser = [[HTMLParser alloc] initWithString:htmlCode];
    
        HTMLDocument *document = [parser parseDocument];

        // ...
    }];
}

我正在使用此函数解析可能包含文本的子元素和兄弟元素(来自 this 列表)。不幸的是,这并不总是有效。对于许多站点,文本嵌套在我无法访问的结构或需要 运行.

的脚本中

简单的方法

对 Apple 已经用于不同目的的方法进行逆向工程。比如有一个网页搜索文本的方法:

- (void)findString:(NSString *)string 
 withConfiguration:(WKFindConfiguration *)configuration 
 completionHandler:(void (^)(WKFindResult *result))completionHandler;

您只返回一个关于是否找到文本的 BOOL 变量。无法获取用于执行搜索的文本。

您可以执行如下简单的操作:

NSAttributedString *attributedStringFromHTML = [[NSAttributedString alloc] initWithData:[htmlString dataUsingEncoding:NSUTF8StringEncoding] options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute:@(NSUTF8StringEncoding)} documentAttributes:nil error:nil];

NSString *stringResult = [attributedStringFromHTML string];

但这有很多缺点。一个主要问题是 HTML->Attributed String 可能非常慢,这取决于您应该支持的最小 iOS 版本,它可能需要在主线程上 运行 最后 - 它是只是将 HTML 转为文本并不是最佳选择。它需要一些额外的分隔(换行符、空格等)。