页面未加载并挂起在Awesomium中

时间:2015-01-13 07:39:07

标签: c# xpath loading webpage awesomium

我需要帮助才能完全加载页面。我正在尝试在Dassault Enovia PLM系统中自动搜索。我可以在Chris - How to login...的帮助下成功登录该网站,然后导航搜索页面,但搜索页面未完全加载并挂起。 以下是我的源代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Awesomium.Core;
using System.Threading;

namespace Awesom
{
    class Program2
    {
        dynamic document = null;

        public static void Main(String[] args)
        {
            Program2 pg = new Program2();

            Console.WriteLine("Started....");

            WebView wv = WebCore.CreateWebView(1024, 600);

            wv.Source = new Uri("http://somecompany.app.com/ematrix/emxLogin.jsp");

            FrameEventHandler handler = null;
            handler = (s, e) =>
            {
                if (e.IsMainFrame)
                {
                    // we have finished loading main page,
                    // let's unhook ourselves
                    wv.LoadingFrameComplete -= handler;

                    //LoginAndTakeScreenShot(wv);
                    pg.LoginAndTakeScreenShot1(wv);
                }
            };

            wv.LoadingFrameComplete += handler;

            WebCore.Run();
        }


        private void LoginAndTakeScreenShot1(WebView wv)
        {
            document = (JSObject)wv.ExecuteJavascriptWithResult("document");
            using (document)
            {
                String userInput = @"//*[@id=""divLogin""]/form/table/tbody/tr[2]/td/table/tbody/tr/td[3]/div/div/input";

                String userNameXpath = userInput + "[1]" ;

                var username = document.evaluate(userNameXpath, document, null, 9, null).singleNodeValue;
                username.value = "ffffAddd";

                String passwordXPath = userInput + "[2]";

                var password = document.evaluate(passwordXPath, document, null, 9, null).singleNodeValue;
                password.value = "aPassword";

                int i = 0;

                FrameEventHandler handler = null;
                handler = (sender, args) =>
                {
                    //BitmapSurface img = (BitmapSurface)wv.Surface;
                    //img.SaveToPNG(String.Format("loading{0}.png", ++i), true);

                    if (args.IsMainFrame)
                    {
                        if (!wv.IsLoading)
                        {
                            wv.LoadingFrameComplete -= handler;

                            BitmapSurface surface = (BitmapSurface)wv.Surface;
                            Thread.Sleep(30000);
                            surface.SaveToPNG("result.png", true);
                            OpenSearchPage(wv);

                            //WebCore.Shutdown();
                        }
                    }
                };

                wv.LoadingFrameComplete += handler;

                String loginButtonXPath = userInput + "[3]";

                var loginButton = document.evaluate(loginButtonXPath, document, null, 9, null).singleNodeValue;
                loginButton.click();
            }
        }

        private void OpenSearchPage(WebView wv)
        {
            using (document)
            {
                int i = 0;

                FrameEventHandler handler = null;
                handler = (sender, args) =>
                {
                    BitmapSurface img = (BitmapSurface)wv.Surface;
                    img.SaveToPNG(String.Format("loading{0}.png", ++i), true);
                    Console.WriteLine("Iteration {0}", i);

                    bool MainFrameLoaded = args.IsMainFrame;

                    //After 4 the iteration, Awesomium hangs

                    if (MainFrameLoaded && !wv.IsLoading)
                    {
                        wv.LoadingFrameComplete -= handler;
                        BitmapSurface surface = (BitmapSurface)wv.Surface;
                        Thread.Sleep(30000);
                        surface.SaveToPNG("search.png", true);
                        WebCore.Shutdown();
                    }
                };

                //Search Page URL

                wv.Source = new Uri("http://somecompany.app.com/ematrix/common/emxFullSearch.jsp?field=TYPES%3Dtype_Part%3APOLICY%3Dpolicy_ECPart%2Cpolicy_DevelopmentPart&showInitialResults=false&table=ENCPartSearchResult&selection=multiple&toolbar=ENCPartSearchToolbar&freezePane=ActiveECRECO%2CName&HelpMarker=emxhelpfullsearch&formInclusionList=PRT_DESCRIPTION&suiteKey=EngineeringCentral&StringResourceFileId=emxEngineeringCentralStringResource&SuiteDirectory=engineeringcentral");

                wv.LoadingFrameComplete += handler;
            }
        }
    }
}

预计要加载的实际搜索页面如下所示,并在所有浏览器中按预期加载:

enter image description here

Awesomium中的负载如下:

enter image description here

任何人都可以帮助在Awesomium中按预期加载页面。

亲切的问候, 阿巴斯

1 个答案:

答案 0 :(得分:2)

经过一周的Awesomium探索,我得到了解决方案。 FrameEventArgs.IsMainFrame事件中的LoadingFrameComplete并不能保证所有页面的所有元素和框架都被加载,因此我们需要有一个机制来确保这一点。我已经选择了一个HTMLElement并继续检查该元素是否已经加载,在加载了所需的元素后,我得出结论,已经加载了所需的页面。 以下是适用于此问题的代码。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.CompilerServices;
using System.Reflection;
using System.Threading;
using System.IO;

using Awesomium.Core;

namespace AweSomiumExample
{
    class Program
    {
        WebView wv;
        int i = 0;
        int k = 0;
        dynamic PageReady;
        bool DocumentReady;

        public String login { get; private set; }
        public String passw { get; private set; }

        public static void Main(String[] args)
        {
            Program pg = new Program();
        }

        public Program()
        {
            wv = WebCore.CreateWebView(1024, 600);

            wv.Source = new Uri("http://somecompany.app.com/ematrix/emxLogin.jsp");

            login = "ffffAddd";
            passw = "aPassword";

            wv.LoadingFrameComplete += MainPageLoadingFrameComplete;
            wv.DocumentReady += OnDocumentReadyHandler;

            WebCore.Run();
        }

        private void MainPageLoadingFrameComplete(Object sender, FrameEventArgs e)
        {
            try
            {
                if (!e.IsMainFrame)
                {
                    wait();
                }
                else
                {
                    String userInput = @"//*[@id=""divLogin""]/form/table/tbody/tr[2]/td/table/tbody/tr/td[3]/div/div/input";
                    String userNameXpath = userInput + "[1]";
                    String passwordXPath = userInput + "[2]";
                    String loginButtonXPath = userInput + "[3]";

                    wv.LoadingFrameComplete -= MainPageLoadingFrameComplete;

                    dynamic xPathUserNameObj = GetXPathElement(userNameXpath);
                    using (xPathUserNameObj)
                    {
                        var username = xPathUserNameObj;
                        username.value = login;
                    }

                    dynamic xPathPasswordObj = GetXPathElement(passwordXPath);
                    using (xPathPasswordObj)
                    {
                        var password = xPathPasswordObj;
                        password.value = passw;
                    }

                    TakeScreenShot();

                    dynamic xPathLoginButtonObj = GetXPathElement(loginButtonXPath);
                    using (xPathLoginButtonObj)
                    {
                        var loginButton = xPathLoginButtonObj;

                        wv.LoadingFrameComplete += LoginFrameComplete;

                        loginButton.click();
                    }
                }
            }
            catch (Exception ex)
            {
                Log(ex.Message);
                wait();
            }
        }

        private void LoginFrameComplete(Object sender, FrameEventArgs e)
        {
            try
            {
                PageReady = (PageReady == null) ? GetXPathElement(@"//*[@id=""SearchIcon""]") : PageReady;
                if (PageReady != null)
                {
                    Log(String.Format("Running {0}", ++k));
                    wv.LoadingFrameComplete -= LoginFrameComplete;
                    TakeScreenShot();

                    wv.LoadingFrameComplete += SearchFrameComplete;

                    wv.Source = new Uri("http://somecompany.app.com/ematrix/common/emxFullSearch.jsp?field=TYPES%3Dtype_Part%3APOLICY%3Dpolicy_ECPart%2Cpolicy_DevelopmentPart&showInitialResults=false&table=ENCPartSearchResult&selection=multiple&toolbar=ENCPartSearchToolbar&freezePane=ActiveECRECO%2CName&HelpMarker=emxhelpfullsearch&formInclusionList=PRT_DESCRIPTION&suiteKey=EngineeringCentral&StringResourceFileId=emxEngineeringCentralStringResource&SuiteDirectory=engineeringcentral");

                    wait();
                    PageReady = null;
                }
                else
                {
                    wait();
                }
            }
            catch (Exception ex)
            {
                Log(ex.Message);
                wait();
            }
        }

        private void SearchFrameComplete(Object sender, FrameEventArgs e)
        {
            try
            {
                PageReady = (PageReady == null) ? GetXPathElement(@"//*[@id=""NAME""]") : PageReady;
                if (PageReady != null)
                {
                    Log(String.Format("Running {0}", ++k));
                    wv.LoadingFrameComplete -= LoginFrameComplete;
                    TakeScreenShot();

                    Log("Success");
                    TakeScreenShot("Final");
                    wv.LoadingFrameComplete -= SearchFrameComplete;
                    wv.DocumentReady -= OnDocumentReadyHandler;
                    WebCore.Shutdown();
                }
                else
                {
                    TakeScreenShot("SearchScreen");
                    wait();
                }
            }
            catch (Exception ex)
            {
                Log(ex.Message);
                wait();
            }
        }

        private void OnDocumentReadyHandler(Object Sender, DocumentReadyEventArgs e)
        {
            Log(String.Format("Running {0}", ++k));
            if (e != null && e.ReadyState == DocumentReadyState.Loaded)
            {
                TakeScreenShot("DocumentReady_True");
                Log("DocumentReady = true");
                DocumentReady = true;
            }
            else
            {
                TakeScreenShot("DocumentReady_False");
                Log("DocumentReady = false");
                DocumentReady = false;
                //WebCore.Run();
            }
        }

        private dynamic GetXPathElement(String xpath)
        {
            try
            {
                if (wv.IsDocumentReady == false)
                {
                    return null;
                }

                String xpathString = String.Format(@"document.evaluate('{0}',document,null,9,null);", xpath);
                dynamic dc = (JSObject)wv.ExecuteJavascriptWithResult(xpathString);
                if (dc != null && dc is JSObject)
                {
                    using (dc)
                    {
                        dynamic SingleNodeObj = dc.singleNodeValue;
                        if (SingleNodeObj != null && SingleNodeObj is JSObject)
                        {
                            return SingleNodeObj;
                        }
                        else
                        {
                            return null;
                        }
                    }
                }
                else
                {
                    return null;
                }
            }
            catch (Exception ex)
            {
                Log(ex.Message);
                return null;
            }

        }

        private void TakeScreenShot(String Name = "Image")
        {
            //Thread.Sleep(3000);
            BitmapSurface surface = (BitmapSurface)wv.Surface;
            surface.SaveToPNG(String.Format("{0}_{1}.png", ++i, Name), true);
            Log(String.Format("ScreenShot Taken {0}", i));
        }

        private static void Log(string text,
                        [CallerFilePath] string file = "",
                        [CallerMemberName] string member = "",
                        [CallerLineNumber] int line = 0)
        {
            Console.WriteLine("{0}_{1}({2}): {3}", Path.GetFileName(file), member, line, text);
        }

        private void wait(int waitTime = 10000)
        {
            Log(String.Format("Wait {0} seconds for the page to load", (int)(waitTime / 1000)));
            Thread.Sleep(waitTime);
        }
    }
}

结果页面已加载: enter image description here