WebBrowser的DocumentCompleted事件遇到了一些问题,求助
WebBrowser是类似浏览器把?WebBrowser.DocumentCompleted是在页面加载完成之后,触发的时间,可是有些页面加载完成之后还在继续加载,这种行为是叫异步加载么?页面加载完成之后触发DocumentCompleted事件,但是一些Json数据和其他HTML代码,还在继续加载,但是等到这些所有的东西全部加载完成之后,可能因为地址没有变或者其他原因,就不再触发DocumentCompleted事件了。
所以把代码卸载DocumentCompleted事件里头,我取不到我需要的Json数据。
wbsTaoBaoIndex.DocumentCompleted += (sender, e) =>
{
if (wbsTaoBaoIndex.DocumentText.IndexOf("登陆页") > 0)
LoginUser();//登录
else if (wbsTaoBaoIndex.DocumentText.IndexOf("搜索数据") > 0)
;//
else if (wbsTaoBaoIndex.DocumentText.IndexOf("品牌数据") > 0)
;//
};
这样的话值触发一次事件,等到实际加载完成之后并不出发这个事件,所以我取不到数据,这个该怎么解决?
while (true)
{
Thread.Sleep(500);
Application.DoEvents();
System.IO.StreamReader streamReader = new System.IO.StreamReader(browser.DocumentStream, encoding);
string htmlDocumentText = streamReader.ReadToEnd();
//如果不加第二个判断,可能会在页面未全部加载就通过判断,因为页面并不是一次加载完,
//程序执行到这里的时候,WebBrowserReadyState可能已经完成,但是页面没有加载完成,
//所以此处需要多一个“搜索数据”的判断
if (browser.ReadyState == WebBrowserReadyState.Complete
&& htmlDocumentText.IndexOf("搜索数据") > 0)
//......其他代码
现在只能这么完成,Application.DoEvents();这个方法以前没用过,我对此不是很懂,我一开始一直以为这个是先执行其他线程,我求助群里的人,群里的人告诉我这个是告诉当前线程,把其他事件先去执行完成,我似懂非懂,同一个线程,还能先执行其他事件么?
我主要想求助用WebBrowser如果写的正规点,该怎么完成,现在这种方法显然不太好把,死循环,还用DoEvents(),虽然确实可以正常使用。
这段可以执行的代码,上面还有一个类似的死循环,加载完成之后空wbs状态是完成(browser.ReadyState == WebBrowserReadyState.Complete)也会触发DocumentCompleted ,然后完成登录,登录之后跳转到我要的有Json数据的页面,很快又会加载完成状态又会变成完成(browser.ReadyState == WebBrowserReadyState.Complete),又触发DocumentCompleted 事件,
但是这个时候并没有实际数据然后WBS状态又会变回加载,然后所以这个时候就运行到我上面贴出来的第二段代码了,在这里头不断的循环执行,知道状态变成完成(browser.ReadyState == WebBrowserReadyState.Complete),但是这次状态完成就不再触发DocumentCompleted 事件了,所以我的第一段代码取不出数据,第二段执行到这里的时候,已经是第二次异步加载的时候,所以一直循环知道完成就能取出数据。
说的很乱,不好意思,麻烦各位哥哥姐姐们了,帮帮小弟
[解决办法]
private void Delay(int Millisecond) //延迟系统时间,但系统又能同时能执行其它任务;
{
DateTime current = DateTime.Now;
while (current.AddMilliseconds(Millisecond) > DateTime.Now)
{
Application.DoEvents();//转让控制权
}
return;
}
主要的函数:
private bool WaitWebPageLoad()
{
int i=0;
string sUrl;
while (true)
{
Delay(50); //系统延迟50毫秒,够少了吧!
if (webBrowser1.ReadyState == WebBrowserReadyState.Complete) //先判断是否发生完成事件。
{
if (!webBrowser1.IsBusy) //再判断是浏览器是否繁忙
{
i = i + 1;
if (i == 2) //为什么 是2呢?因为每次加载frame完成时就会置IsBusy为false,未完成就就置IsBusy为false,你想一想,加载一次,然后再一次,再一次...... 最后一次.......
{
sUrl = webBrowser1.Url.ToString();
if (sUrl.Contains("res")) //这是判断没有网络的情况下
{
return false;
}
else
{
return true;
}
}
continue;
}
i=0;
}
}
}//当然你也可以加上超时的情况,那就让你自己解决了。