我需要捕获生成的HTML的图像。我使用的是亚历克斯Filipovici的优秀的解决方案从这里: HTML字符串转换为图片。它除了当我试图加载一个页面,有一个使用一些JavaScript加载一个iframe的伟大工程。
I need to capture an image of generated HTML. I'm using Alex Filipovici's excellent solution from here: Convert HTML string to image. It works great except when I'm trying to load a page that has an iframe that uses some Javascript to load.
static int width = 1024;
static int height = 768;
public static void Capture()
{
var html = @"
<!DOCTYPE html>
<meta http-equiv='X-UA-Compatible' content='IE=Edge'>
<html>
<iframe id='forecast_embed' type='text/html' frameborder='0' height='245' width='100%' src='https://m.xsw88.com/allimgs/daicuo/20230904/7102.png", System.Drawing.Imaging.ImageFormat.Jpeg);
}
Application.Exit();
}
据我所知,有可能是没有明确的办法知道的已经结束了所有的JavaScript和iframe装载的变幻莫测和事实DocumentCompleted得到,因为有帧/内置页框+ 1。我可以用iframe负载处理的称为多次有一个计数器或东西,但我要的是一个合理的延迟,所以JavaScript在它加载,我没有得到的图像与加载是这样的:的 http://imgur.com/FiFMTmm
如果你正在处理与使用框架和AJAX大量动态网页,没有完美的解决方案,以发现,当一个特定的页面完成加载资源。你可以得到附近做以下两件事情:
If you're dealing with dynamic web pages which use frames and AJAX heavily, there is no perfect solution to find when a particular page has finished loading resources. You could get close by doing the following two things:
处理页面的的window.onload
事件;
,然后异步轮询 web浏览器
的忙性,具有一定的predefined相当短的时间了。
handle the page's window.onload
event;
then asynchronously poll WebBrowser
Busy property, with some predefined reasonably short time-out.
例如,(检查 http://stackoverflow.com/a/19283143/1768303 以一个完整的例子):
E.g., (check http://stackoverflow.com/a/19283143/1768303 for a complete example):
const int AJAX_DELAY = 2000; // non-deterministic wait for AJAX dynamic code
const int AJAX_DELAY_STEP = 500;
// wait until webBrowser.Busy == false or timed out
async Task<bool> AjaxDelay(CancellationToken ct, int timeout)
{
using (var cts = CancellationTokenSource.CreateLinkedTokenSource(ct))
{
cts.CancelAfter(timeout);
while (true)
{
try
{
await Task.Delay(AJAX_DELAY_STEP, cts.Token);
var busy = (bool)this.webBrowser.ActiveXInstance.GetType().InvokeMember("Busy", System.Reflection.BindingFlags.GetProperty, null, this.webBrowser.ActiveXInstance, new object[] { });
if (!busy)
return true;
}
catch (OperationCanceledException)
{
if (cts.IsCancellationRequested && !ct.IsCancellationRequested)
return false;
throw;
}
}
}
}
如果你不想使用异步/计谋
,您可以使用定时器实现相同的逻辑。
If you don't want to use async/await
, you can implement the same logic using a timer.