webbrowser 层层跳转的问题

胡椒csdn 2017-02-07 01:52:39
请教大神们个问题:
bool loading=true;
public void btn_Click(object sender, EventArgs e){
wb = new WebBrowser();
wb.DocumentCompleted += wb_DocumentCompleted;

wb.Navigate(url);
}
void wb_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e){
if (this.wb.ReadyState == WebBrowserReadyState.Complete) {
wb.DocumentCompleted -= wb_DocumentCompleted;
HtmlElementCollection collections = wb.Document.GetElementsByTagName("A");
wb.DocumentCompleted += detail_DocumentCompleted;
foreach (HtmlElement ele in collections) {
loading=true;
wb.Navigate(ele.GetAttribute("href"));
while(loading){
Application.DoEvents();
}
}
}
}

void detail_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) {
if (this.wb.ReadyState == WebBrowserReadyState.Complete) {
dosomething();
loading=false;
}
}
想实现通过层层跳转,跳转到目标页面,但是detail_DocumentCompleted事件不能被触发,如果把wb_DocumentCompleted里面的for循环去掉只navigate一次就可以触发detail_DocumentCompleted不知道是什么原因?希望大神们可以指点一下,
...全文
256 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
首先考虑你自己的问题,因为服务器端发生了 什么你无从知道。 我通常不检查readystate,而是用getElementById等方法检查我关心的元素加载了没有。 另外,适当增加延时(修改timer的Interval 属性)也可试试。
  • 打赏
  • 举报
回复
foreach 加上navigate很危险。如果真要全部访问,用Timer,先把所有链接地址收集起来,存放在某个数据结构比如List里面,用个全局变量作为list的索引值,然后在timer里递增索引值,设置适当的延时,然后逐个访问。大致这样: private int _idx = 0; private List<string> _urls = new List<string>(); .... foreach (HtmlElement ele in collections) { _urls.Add(ele.GetAttribute("href")); } timer1_tick() { timer1.Stop(); if (_idx < _urls.Count - 1) { _idx++; wb.Navigate(_urls[_idx]); } } void detail_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { ... dosomething(); timer1.Start(); webbrowser的程序经常需要用timer。
胡椒csdn 2017-02-09
  • 打赏
  • 举报
回复
引用 6 楼 hzzasdf 的回复:
foreach 加上navigate很危险。如果真要全部访问,用Timer,先把所有链接地址收集起来,存放在某个数据结构比如List里面,用个全局变量作为list的索引值,然后在timer里递增索引值,设置适当的延时,然后逐个访问。大致这样: private int _idx = 0; private List<string> _urls = new List<string>(); .... foreach (HtmlElement ele in collections) { _urls.Add(ele.GetAttribute("href")); } timer1_tick() { timer1.Stop(); if (_idx < _urls.Count - 1) { _idx++; wb.Navigate(_urls[_idx]); } } void detail_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { ... dosomething(); timer1.Start(); webbrowser的程序经常需要用timer。
非常感谢,采用了你的方法问题解决了。现在又出现了新问题,navigate后进入DocumentCompleted方法this.wb.ReadyState的状态是Loading之后就是程序结束了,并没有出现complete状态,这是什么原因呢?是因为抓取次数多被人家的网站屏蔽了吗?
crystal_lz 2017-02-07
  • 打赏
  • 举报
回复
为什么不用httpwebrequest?
cpycpy000 2017-02-07
  • 打赏
  • 举报
回复
你可以试试把foreach里的内容拿出来,封装成一个函数,开子线程调用函数,然后用委托去控制webbrowser的Navigate

private delegate void ChangeNavigate(string url);
ChangeNavigate cn;

private void Form1_Load()
{
    cn = new ChangeNavigate(WebNavigate);
}

private void WebNavigate(string url)
{
    wb.Navigate(url);
}

private void beginForeach()
{
    foreach(xxx)
    { 
         //xxxxx
         cn.invoke(ele.GetAttribute("href"));
    }
}

private void wb_DocumentCompleted( xxx)
{
     //xxxx
     Task.Run(()=>beginForeach());
}
mlqxj35674 2017-02-07
  • 打赏
  • 举报
回复
死循环了, loading=true; wb.Navigate(ele.GetAttribute("href")); while(loading){ Application.DoEvents(); //这里出不来了 }
胡椒csdn 2017-02-07
  • 打赏
  • 举报
回复
用另一webbrowser同样触发不了DocumentCompleted事件
卧_槽 2017-02-07
  • 打赏
  • 举报
回复
我要是你,就在放一个WebBrowser专门给detail用。

110,571

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧