主要思想:通过后台WebView载入指定网页,再提取出WebView中的内容

关键代码:

var html = await webView.InvokeScriptAsync("eval", new string[] { "document.documentElement.outerHTML;" });

有一个很简单的思路,

订阅WebView NavigationCompleted事件,然后让Navigate到指定的网址,发生事件时执行这行代码

除此之外,这里还有一个异步的方法,用到了TaskCompletionSource这个东西

首先,创建一个TaskCompletionSource:

TaskCompletionSource<string> completionSource = new TaskCompletionSource<string>();

因为返回的东西是string(html),所以泛型T设置成string

然后使用lambda的形式订阅Navigation事件:

 webView.NavigationCompleted += async (sender, args) =>
{
if (args.Uri != uri)
return;
await Task.Delay();
var html = await sender.InvokeScriptAsync("eval", new string[] { "document.documentElement.outerHTML;" });
webView.NavigateToString("");
webView = null;
completionSource.SetResult(html);
};

Line5的延迟200ms,是为了Navigation完成之后再给页面里的其他一些元素(比如一些js脚本)一些加载的时间(讲道理订阅事件里也应该写一个的)

Line7的导航到空是为了防止WebView里的东西继续运行从而导致一些灵异事件(尤其是一些带视频的网页,咳咳)

Line9,给Task设置个Result,await就会结束

最后:

 return completionSource.Task;

封装成类:

    public class WebHelper
{
public class WebLoadedArgs:EventArgs
{
public bool Success { get; private set; }
public WebErrorStatus WebErrorStatus { get; private set; }
public string Html { get; private set; } public WebLoadedArgs(WebErrorStatus webErrorStatus)
{
WebErrorStatus = webErrorStatus;
Success = false;
} public WebLoadedArgs(string Html,WebErrorStatus webErrorStatus)
{
this.Html = Html;
WebErrorStatus = webErrorStatus;
Success = true;
}
} public string Url { get; private set; }
public event EventHandler<WebLoadedArgs> WebLoaded;
private WebView webView; public WebHelper(string Url)
{
this.Url = Url;
webView = new WebView(WebViewExecutionMode.SeparateThread);
webView.Navigate(new Uri(Url));
webView.NavigationCompleted += WebView_NavigationCompleted;
webView.NavigationFailed += WebView_NavigationFailed;
} private void WebView_NavigationFailed(object sender, WebViewNavigationFailedEventArgs e)
{
WebLoaded(this, new WebLoadedArgs(e.WebErrorStatus));
} private async void WebView_NavigationCompleted(WebView sender, WebViewNavigationCompletedEventArgs args)
{ var html = await sender.InvokeScriptAsync("eval", new string[] { "document.documentElement.outerHTML;" });
webView = null;
WebLoaded(this, new WebLoadedArgs(html,args.WebErrorStatus));
} /// <summary>
/// 异步实现获取Web内容
/// </summary>
/// <param name="Url">网址</param>
/// <param name="TimeOut">超时时间</param>
/// <returns>Web的Html内容</returns>
public static Task<string> LoadWebAsync(string Url,int Timeout)
{
return LoadWebAsync(Url, "", Timeout);
} /// <summary>
/// 异步实现获取Web内容
/// </summary>
/// <param name="Url">网址</param>
/// <param name="Referer">Header[Referer],用以解决一些盗链效验</param>
/// <param name="TimeOut">超时时间</param>
/// <returns>Web的Html内容</returns>
public static Task<string> LoadWebAsync(string Url,string Referer, int TimeOut)
{ WebView webView = new WebView(WebViewExecutionMode.SeparateThread);
Uri uri = new Uri(Url);
HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, uri);
requestMessage.Headers.Add("Referer", Referer);
webView.NavigateWithHttpRequestMessage(requestMessage); TaskCompletionSource<string> completionSource = new TaskCompletionSource<string>();
webView.NavigationCompleted += async (sender, args) =>
{
if (args.Uri != uri)
return;
await Task.Delay();
var html = await sender.InvokeScriptAsync("eval", new string[] { "document.documentElement.outerHTML;" });
webView.NavigateToString("");
webView = null;
completionSource.SetResult(html);
};
webView.NavigationFailed += (sender, args) =>
{
webView = null;
completionSource.SetException(new WebException("", (WebExceptionStatus)args.WebErrorStatus));
};
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(TimeOut);
timer.Tick += (sender, args) =>
{
timer = null;
webView.NavigateToString("");
webView = null;
completionSource.SetException(new TimeoutException());
};
timer.Start(); return completionSource.Task;
}
}

使用方法:

(事件订阅的方式)

        WebHelper webHelper = new WebHelper("http://www.baidu.com/");
webHelper.WebLoaded += WebHelper_WebLoaded; private void WebHelper_WebLoaded(object sender, WebHelper.WebLoadedArgs e)
{
if(e.Success)
{
var html = e.Html;
}
}

(异步的方式)

var html = await WebHelper.LoadWebAsync("http://www.baidu.com", );

UWP获取任意网页加载完成后的HTML的更多相关文章

  1. js判断图片加载完成后获取图片实际宽高

    通常,我们会用jq的.width()/.height()方法获取图片的宽度/高度或者用js的.offsetwidth/.offsetheight方法来获取图片的宽度/高度,但这些方法在我们通过样式设置 ...

  2. Web前端性能优化总结——如何提高网页加载速度

    一.提高网页加载速度的必要性 国际知名的一组来自Jupiter Research的数据显示:购物者在访问网站过程中的不满会导致销售损失和品牌受损,其中 77%的人将不再访问网站 ,62%的人不再从该网 ...

  3. 《转》如何让你的网页加载时间降低到 1s 内

    当初分析了定宽高值和定宽高比这两种常见的图片延迟加载场景,也介绍了他们的应对方案,还做了一点技术选型的工作. 经过一段时间的项目实践,在先前方案的基础上又做了很多深入的优化工作.最终将好奇心日报的网页 ...

  4. 使用WebView监控网页加载状况,PerformanceMonitor,WebViewClient生命周期

    原理:WebView加载Url完成后,注入js脚本,脚本代码使用W3C的PerformanceTimingAPI, 往js脚本传入一个Android对象(代码中为AndroidObject),在js脚 ...

  5. 如何让你的网页加载时间降低到 1s 内

    当初分析了定宽高值和定宽高比这两种常见的图片延迟加载场景,也介绍了他们的应对方案,还做了一点技术选型的工作. 经过一段时间的项目实践,在先前方案的基础上又做了很多深入的优化工作.最终将好奇心日报的网页 ...

  6. iOS WKWebView添加网页加载进度条(转)

    一.效果展示 WKWebProgressViewDemo.gif 二.主要步骤 1.添加UIProgressView属性 @property (nonatomic, strong) WKWebView ...

  7. 前端性能优化(四)——网页加载更快的N种方式

    网站前端的用户体验,决定了用户是否想要继续使用网站以及网站的其他功能,网站的用户体验佳,可留住更多的用户.除此之外,前端优化得好,还可以为企业节约成本.那么我们应该如何对我们前端的页面进行性能优化呢? ...

  8. 浅析用Base64编码的图片优化网页加载速度

    想必大家都知道网页加载的过程,从开始请求,到加载页面,开始解析和显示网页,遇到图片就再次向服务器发送请求,加载图片.如果图片很多的话,就会产生大量的http请求,从而影响页面的加载速度.所以现在有一种 ...

  9. Webbrowser控件判断网页加载完毕的简单方法 (转)

    摘自:http://blog.csdn.net/cometnet/article/details/5261192 一般情况下,当ReadyState属性变成READYSTATE_COMPLETE时,W ...

随机推荐

  1. Java 使用模板生成 Word 文件---基于 Freemarker 模板框架

    Java项目引入 Freemarker 插件自行完成. 步骤如下: .编写 Word 模板,并将模板中要用代码动态生成数据用 Freemarker 变量取代,即${变量名},如${username}: ...

  2. C#(.net)中的DllImport

    大家在实际工作学习C#的时候,可能会问:为什么我们要为一些已经存在的功能(比如Windows中的一些功能,C++中已经编写好的一些方法)要重新编写代码,C#有没有方法可以直接都用这些原本已经存在的功能 ...

  3. 主成分分析(PCA)原理详解_转载

    一.PCA简介 1. 相关背景 在许多领域的研究与应用中,往往需要对反映事物的多个变量进行大量的观测,收集大量数据以便进行分析寻找规律.多变量大样本无疑会为研究和应用提供了丰富的信息,但也在一定程度上 ...

  4. js阻止冒泡和默认事件

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. Tool-MySQL-SQLyog:SQLyog

    ylbtech-Tool-MySQL-SQLyog:SQLyog SQLyog 是一个快速而简洁的图形化管理MYSQL数据库的工具,它能够在任何地点有效地管理你的数据库,由业界著名的Webyog公司出 ...

  6. String和StringBuffer的区别;字符串的一些基本方法

    String 和 StringBuffer区别 字符串广泛应用 在Java 编程中,在 Java 中字符串属于对象,Java 提供了 String 类来创建和操作字符串. 需要注意的是,String的 ...

  7. lumen使用CORS解决跨域问题

    因为公司的业务是前后端分离,web前端和后端接口域名不同,所以存在跨域问题,开始使用的是jsonp解决,但是因为接口风格是rest的,还有delete.put等请求,jsonp就不够用了(涉及HTTP ...

  8. hdu4565

    #include<iostream> #include<cstdio> #include<queue> #include<algorithm> #inc ...

  9. JAVA面试常见问题之锁机制篇

    1.说说线程安全问题,什么是线程安全,如何保证线程安全 线程安全:就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用.不 ...

  10. vue-i18n 的用法

    主要用于网站国际化,开发可以切换多语言的网站 1,安装 npm install vue-i8n 2,在main.js中引入和注册 import VueI18n from 'vue-i18n' impo ...