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

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

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

Xamarin:如何在WebView中从页面获取HTML?

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

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

这两种依赖于设备的技术在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 (''+document.getElementsByTagName('html')[0].innerHTML+''); })();", 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(Resource.Id.webview); webview.SetWebViewClient(new EmbeddedWebViewClient(webview)); webview.LoadUrl("https://xamarin.com"); 

Xamarin.iOS

您可以通过WKWebView分配IWKNavigationDelegate来捕获WKWebView加载的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 (''+document.getElementsByTagName('html')[0].innerHTML+''); })();"); 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