UWP获取任意网页加载完成后的HTML
主要思想:通过后台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的更多相关文章
- js判断图片加载完成后获取图片实际宽高
通常,我们会用jq的.width()/.height()方法获取图片的宽度/高度或者用js的.offsetwidth/.offsetheight方法来获取图片的宽度/高度,但这些方法在我们通过样式设置 ...
- Web前端性能优化总结——如何提高网页加载速度
一.提高网页加载速度的必要性 国际知名的一组来自Jupiter Research的数据显示:购物者在访问网站过程中的不满会导致销售损失和品牌受损,其中 77%的人将不再访问网站 ,62%的人不再从该网 ...
- 《转》如何让你的网页加载时间降低到 1s 内
当初分析了定宽高值和定宽高比这两种常见的图片延迟加载场景,也介绍了他们的应对方案,还做了一点技术选型的工作. 经过一段时间的项目实践,在先前方案的基础上又做了很多深入的优化工作.最终将好奇心日报的网页 ...
- 使用WebView监控网页加载状况,PerformanceMonitor,WebViewClient生命周期
原理:WebView加载Url完成后,注入js脚本,脚本代码使用W3C的PerformanceTimingAPI, 往js脚本传入一个Android对象(代码中为AndroidObject),在js脚 ...
- 如何让你的网页加载时间降低到 1s 内
当初分析了定宽高值和定宽高比这两种常见的图片延迟加载场景,也介绍了他们的应对方案,还做了一点技术选型的工作. 经过一段时间的项目实践,在先前方案的基础上又做了很多深入的优化工作.最终将好奇心日报的网页 ...
- iOS WKWebView添加网页加载进度条(转)
一.效果展示 WKWebProgressViewDemo.gif 二.主要步骤 1.添加UIProgressView属性 @property (nonatomic, strong) WKWebView ...
- 前端性能优化(四)——网页加载更快的N种方式
网站前端的用户体验,决定了用户是否想要继续使用网站以及网站的其他功能,网站的用户体验佳,可留住更多的用户.除此之外,前端优化得好,还可以为企业节约成本.那么我们应该如何对我们前端的页面进行性能优化呢? ...
- 浅析用Base64编码的图片优化网页加载速度
想必大家都知道网页加载的过程,从开始请求,到加载页面,开始解析和显示网页,遇到图片就再次向服务器发送请求,加载图片.如果图片很多的话,就会产生大量的http请求,从而影响页面的加载速度.所以现在有一种 ...
- Webbrowser控件判断网页加载完毕的简单方法 (转)
摘自:http://blog.csdn.net/cometnet/article/details/5261192 一般情况下,当ReadyState属性变成READYSTATE_COMPLETE时,W ...
随机推荐
- Java 使用模板生成 Word 文件---基于 Freemarker 模板框架
Java项目引入 Freemarker 插件自行完成. 步骤如下: .编写 Word 模板,并将模板中要用代码动态生成数据用 Freemarker 变量取代,即${变量名},如${username}: ...
- C#(.net)中的DllImport
大家在实际工作学习C#的时候,可能会问:为什么我们要为一些已经存在的功能(比如Windows中的一些功能,C++中已经编写好的一些方法)要重新编写代码,C#有没有方法可以直接都用这些原本已经存在的功能 ...
- 主成分分析(PCA)原理详解_转载
一.PCA简介 1. 相关背景 在许多领域的研究与应用中,往往需要对反映事物的多个变量进行大量的观测,收集大量数据以便进行分析寻找规律.多变量大样本无疑会为研究和应用提供了丰富的信息,但也在一定程度上 ...
- js阻止冒泡和默认事件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Tool-MySQL-SQLyog:SQLyog
ylbtech-Tool-MySQL-SQLyog:SQLyog SQLyog 是一个快速而简洁的图形化管理MYSQL数据库的工具,它能够在任何地点有效地管理你的数据库,由业界著名的Webyog公司出 ...
- String和StringBuffer的区别;字符串的一些基本方法
String 和 StringBuffer区别 字符串广泛应用 在Java 编程中,在 Java 中字符串属于对象,Java 提供了 String 类来创建和操作字符串. 需要注意的是,String的 ...
- lumen使用CORS解决跨域问题
因为公司的业务是前后端分离,web前端和后端接口域名不同,所以存在跨域问题,开始使用的是jsonp解决,但是因为接口风格是rest的,还有delete.put等请求,jsonp就不够用了(涉及HTTP ...
- hdu4565
#include<iostream> #include<cstdio> #include<queue> #include<algorithm> #inc ...
- JAVA面试常见问题之锁机制篇
1.说说线程安全问题,什么是线程安全,如何保证线程安全 线程安全:就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用.不 ...
- vue-i18n 的用法
主要用于网站国际化,开发可以切换多语言的网站 1,安装 npm install vue-i8n 2,在main.js中引入和注册 import VueI18n from 'vue-i18n' impo ...