首页 文章

在Xamarin浏览器控件中访问html响应内容

提问于
浏览
1

我的同事和我在Xamarin项目中无法实现,这似乎是一个不寻常的要求 . 我们要做的是动态处理浏览器导航到的任何页面的内容,而不是简单地从它访问的初始URL返回的内容 .

我见过访问以这种方式返回的内容的解决方案:

Xamarin: How to get HTML from page in WebView?

但是,此代码仅在浏览器从其指向的初始URL接收到第一个html响应时才会运行 . 我们需要动态处理浏览器收到的内容,即使它被重定向到不同的URL,或者用户点击了内容中的链接 . 我们使用WebBrowser.DocumentCompleted事件在我们的.NET本机Windows客户端中实现了这一点,该事件在控件加载内容时引发 . 当Xamarin WebViewRendered加载除第一次加载之外的内容时,我们没有发现任何引发的事件或方法,因此我们无法获得后续资源的内容 .

总结一下:如何动态获取Web浏览器导航到的任何URL的内容?答案可以包括可部署到Android和iOS的.NET Xamarin项目中可访问的任何内容,包括第三方开源代码 .

1 回答

  • 4

    这两种依赖于设备的技术在HTML页面加载完成后使用JavaScript评估/执行,以便将整个html内容作为JavaScript结果接收(如果您的要求不需要整个页面返回,请编辑示例中的JavaScript ) .

    Xamarin.Android

    您可以通过分配实现 IValueCallback 的子类 WebViewClient 来捕获 WebView 中加载的html . 页面加载完成后, OnReceiveValue 方法将包含html内容:

    示例WebViewClient类:

    public class EmbeddedWebViewClient : WebViewClient, IValueCallback
    {
        public EmbeddedWebViewClient(WebView view)
        {
            view.Settings.JavaScriptEnabled = true;
        }
    
        public override void OnPageFinished(WebView view, string url)
        {
            base.OnPageFinished(view, url);
            Log.Info("SO", $"Page loaded from: {url}");
            view.EvaluateJavascript("(function() { return ('<html>'+document.getElementsByTagName('html')[0].innerHTML+'</html>'); })();", this);
        }
    
        public void OnReceiveValue(Java.Lang.Object value)
        {
            // "value" holds the html contents of the loaded page
            Log.Debug("SO", ((string)value).Substring(0, 40));
        }
    }
    

    WebViewClient示例用法:

    WebView webview = FindViewById<WebView>(Resource.Id.webview);
    webview.SetWebViewClient(new EmbeddedWebViewClient(webview));
    webview.LoadUrl("https://xamarin.com");
    

    Xamarin.iOS

    您可以通过为 IWKNavigationDelegate 分配 IWKNavigationDelegate 来捕获加载的html . 要么在自己的类中实现它,要么在包含 WKWebView 的控制器中实现它

    示例IWKNavigationDelegate实现:

    public class NavigationDelegate : NSObject, IWKNavigationDelegate
    {
        [Export("webView:didFinishNavigation:")]
        public async void DidFinishNavigation(WKWebView webView, WKNavigation navigation)
        {
            var content = await webView.EvaluateJavaScriptAsync("(function() { return ('<html>'+document.getElementsByTagName('html')[0].innerHTML+'</html>'); })();");
            var html = FromObject(content);
            Console.WriteLine((html.ToString()).Substring(0, 40));
        }
    }
    

    示例WKWebView用法:

    wkwebview = new WKWebView(UIScreen.MainScreen.Bounds, new WKWebViewConfiguration());
    wkwebview.NavigationDelegate = new NavigationDelegate();
    Add(wkwebview);
    wkwebview.LoadRequest(new NSUrlRequest(new Uri("https://xamarin.com")));
    

    注意:使用 UIWebView 可以完成相同的基本逻辑,但 WKWebView 速度要快得多,如果您不需要支持iOS 7客户端,我个人会专注于使用 WKWebView

相关问题