Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/265.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 网络浏览器行为问题_C#_Browser_Web Scraping_Webbrowser Control_Screen Scraping - Fatal编程技术网

C# 网络浏览器行为问题

C# 网络浏览器行为问题,c#,browser,web-scraping,webbrowser-control,screen-scraping,C#,Browser,Web Scraping,Webbrowser Control,Screen Scraping,我正在尝试用.NET C#自动化Webbrowser。问题是控件或IE浏览器在不同的计算机上的行为很奇怪。例如,我点击链接并在第一台计算机上填写Ajax弹出表单,如下所示,没有任何错误: private void btn_Start_Click(object sender, RoutedEventArgs e) { webbrowserIE.Navigate("http://www.test.com/"); webbrowserIE.DocumentCompleted += fi

我正在尝试用.NET C#自动化Webbrowser。问题是控件或IE浏览器在不同的计算机上的行为很奇怪。例如,我点击链接并在第一台计算机上填写Ajax弹出表单,如下所示,没有任何错误:

private void btn_Start_Click(object sender, RoutedEventArgs e)
{
    webbrowserIE.Navigate("http://www.test.com/");
    webbrowserIE.DocumentCompleted += fillup_LoadCompleted; 
}

void fillup_LoadCompleted(object sender, System.Windows.Forms.WebBrowserDocumentCompletedEventArgs e)
{
    System.Windows.Forms.HtmlElement ele = web_BrowserIE.Document.GetElementById("login");
    if (ele != null)
        ele.InvokeMember("Click");

    if (this.web_BrowserIE.ReadyState == System.Windows.Forms.WebBrowserReadyState.Complete)
    {
        web_BrowserIE.Document.GetElementById("login").SetAttribute("value", myUserName);
        web_BrowserIE.Document.GetElementById("password").SetAttribute("value", myPassword);

        foreach (System.Windows.Forms.HtmlElement el in web_BrowserIE.Document.GetElementsByTagName("button"))
        {
            if (el.InnerText == "Login")
            {
                el.InvokeMember("click");
            }
        }

        web_BrowserIE.DocumentCompleted -= fillup_LoadCompleted;        
    }
}
但是,上述代码在第二台pc上不起作用,单击的唯一方式如下:

private void btn_Start_Click(object sender, RoutedEventArgs e)
{
    webbrowserIE.DocumentCompleted += click_LoadCompleted;
    webbrowserIE.Navigate("http://www.test.com/"); 
}

void click_LoadCompleted(object sender, System.Windows.Forms.WebBrowserDocumentCompletedEventArgs e)
{
    if (this.webbrowserIE.ReadyState == System.Windows.Forms.WebBrowserReadyState.Complete)
    {
        System.Windows.Forms.HtmlElement ele = webbrowserIE.Document.GetElementById("login");
        if (ele != null)
            ele.InvokeMember("Click");

        webbrowserIE.DocumentCompleted -= click_LoadCompleted;
        webbrowserIE.DocumentCompleted += fillup_LoadCompleted;
    }
}

void click_LoadCompleted(object sender, System.Windows.Forms.WebBrowserDocumentCompletedEventArgs e)
{

        webbrowserIE.Document.GetElementById("login_login").SetAttribute("value", myUserName);
        webbrowserIE.Document.GetElementById("login_password").SetAttribute("value", myPassword);

        //If you know the ID of the form you would like to submit:
        foreach (System.Windows.Forms.HtmlElement el in webbrowserIE.Document.GetElementsByTagName("button"))
        {
            if (el.InnerText == "Login")
            {
                el.InvokeMember("click");
            }
        }

        webbrowserIE.DocumentCompleted -= click_LoadCompleted;      
}

所以,在第二个解决方案中,我必须调用两个加载完成链。有人能建议我如何处理这个问题吗?此外,提出一个更为稳健的方法将非常有帮助。提前谢谢

我可以推荐两件事:

  • 不要在
    DocumentComplete
    事件时执行代码,而要在DOM事件时执行
  • <> LI>确保你的网页在 WebBuffer < /C>中的行为与在完全Internet Explorer浏览器中的方式相同,请考虑实现.
[编辑]根据代码的结构,还有一个建议。显然,您执行了一系列导航/句柄
DocumentComplete
操作。为此,使用
async/await
可能更自然、更容易。下面是一个这样做的示例,有无
async/await
。它还说明了如何处理
onload

async Task DoNavigationAsync()
{
    bool documentComplete = false;
    TaskCompletionSource<bool> onloadTcs = null;

    WebBrowserDocumentCompletedEventHandler handler = delegate 
    {
        if (documentComplete)
            return; // attach to onload only once per each Document
        documentComplete = true;

        // now subscribe to DOM onload event
        this.wb.Document.Window.AttachEventHandler("onload", delegate
        {
            // each navigation has its own TaskCompletionSource
            if (onloadTcs.Task.IsCompleted)
                return; // this should not be happening

            // signal the completion of the page loading
            onloadTcs.SetResult(true);
        });
    };

    // register DocumentCompleted handler
    this.wb.DocumentCompleted += handler;

    // Navigate to http://www.example.com?i=1
    documentComplete = false;
    onloadTcs = new TaskCompletionSource<bool>();
    this.wb.Navigate("http://www.example.com?i=1");
    await onloadTcs.Task;
    // the document has been fully loaded, you can access DOM here
    MessageBox.Show(this.wb.Document.Url.ToString());

    // Navigate to http://example.com?i=2
    // could do the click() simulation instead

    documentComplete = false;
    onloadTcs = new TaskCompletionSource<bool>(); // new task for new navigation
    this.wb.Navigate("http://example.com?i=2");
    await onloadTcs.Task;
    // the document has been fully loaded, you can access DOM here
    MessageBox.Show(this.wb.Document.Url.ToString());

    // no more navigation, de-register DocumentCompleted handler
    this.wb.DocumentCompleted -= handler;
}
注意,在这两种情况下,它仍然是一段返回对象的异步代码。以下是如何处理此类任务完成的示例:

private void Form1_Load(object sender, EventArgs e)
{
    DoNavigationAsync().ContinueWith(_ => {
        MessageBox.Show("Navigation complete!");
    }, TaskScheduler.FromCurrentSynchronizationContext());
}

在这里使用的好处是
DoNavigationAsync
是一种独立的方法。它可以重用,并且不会干扰父对象(在本例中为主窗体)的状态。

实际上,我已经实现了功能控件,因为这是我的问题:),我不确定,关于DOM onload事件,因为我需要完成网页事件的下载来实现单击?还是?哦。。我应该检查一下,我确实觉得我以前和@Jim交谈过:]请随意尝试我链接的,
onload
确实会在页面完全加载(包括任何帧)时被触发。此方法是一种更可靠的方法,可以确保页面已完成自己对
onload
onreadystatechange
DOM事件的处理。您是否可以解释一下,因为您注册了DocumentCompleted事件并在其中附加了AttacheVenthandler您认为我执行了一系列DocumentComplete操作是正确的。我是针对.NET4开发的,所以不确定async/await是否可用。另外,奇怪的是,通过事件处理,我可以在一台电脑上工作,而不能在另一台电脑上工作。因此,根据您的经验,async/await是一个更健壮的解决方案吗?功能控制对我很有用。谢谢
private void Form1_Load(object sender, EventArgs e)
{
    DoNavigationAsync().ContinueWith(_ => {
        MessageBox.Show("Navigation complete!");
    }, TaskScheduler.FromCurrentSynchronizationContext());
}