/// <summary>
    /// 设计成一个exe,解决WebBrowser控件内存泄漏的问题.
    /// </summary>
    public partial class MainForm : Form
    {
        /// <summary>
        /// 是否处理完成
        /// </summary>
        private bool isCompleted; //webBrowser只能运行在UI线程上,所以这里不用信号通知,而用一个变量,不断检查这个变量的状态

        /// <summary>
        /// 处理结果
        /// </summary>
        private List<RowData> executeResult = new List<RowData>();

        private static MainForm instance = new MainForm();
        /// <summary>
        /// 单件实例
        /// </summary>
        public static MainForm Instance { get { return instance; } }

        private MainForm()
        {
            InitializeComponent();
            webBrowser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowser_DocumentCompleted);
        }

        private void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            if (this.webBrowser.ReadyState != WebBrowserReadyState.Complete)
                return;

            var txt = webBrowser.Document.Body.InnerText;
            var html = webBrowser.Document.Body.InnerHtml;
            if (webBrowser.Document.Title == "选择")
            {
                var items = ExtractData(html);
                executeResult.AddRange(items);
                isCompleted = true;
            }
        }

        private List<RowData> ExtractData(string html)
        {
            HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
            doc.LoadHtml(html);

            HtmlAgilityPack.HtmlNode node = doc.GetElementbyId("div");
            var trNodes = node.SelectNodes("tbody/tr");

            List<RowData> rows = new List<RowData>();
            foreach (var trNode in trNodes)
            {
                var tdNode = trNode.SelectNodes("td/div");
                RowData row = new RowData();
                rows.Add(row);

                row.航班 = tdNode[0].InnerText;
                row.出发时间 = tdNode[1].InnerText;
                row.到达时间 = tdNode[2].InnerText;
                row.机场 = tdNode[3].InnerText;
                row.机型 = tdNode[4].InnerText;
                row.头等 = tdNode[5].InnerText;
                row.公务 = tdNode[6].InnerText;
                row.全价 = tdNode[7].InnerText;
                row.折扣 = tdNode[8].InnerText;
                row.特价 = tdNode[9].InnerText;
            }

            return rows;
        }

        /// <summary>
        /// 查询数据
        /// </summary>
        /// <param name="fromCity">出发城市代码</param>
        /// <param name="toCity">到达城市代码</param>
        /// <param name="date">出发日期</param>
        /// <param name="timeout">超时时间</param>
        /// <returns>机票信息</returns>
        [MethodImpl(MethodImplOptions.Synchronized)]
        public List<RowData> Query(string fromCity, string toCity, DateTime date, TimeSpan timeout)
        {
            isCompleted = false;
            executeResult.Clear();

            string urlTemplate = "http://www.xxx.com";
            string url = string.Format(urlTemplate, fromCity, date.Month, date.Day, date.Year, toCity);
            Navigate(url);

            DateTime startTime = DateTime.Now;
            //未处理完,且没有超时,则等待
            while (!isCompleted && startTime.Add(timeout) > DateTime.Now)
            {
                Thread.Sleep(100);
                Application.DoEvents();
            }

            return executeResult;
        }

        private void Navigate(string url)
        {
            if (InvokeRequired)
            {
                BeginInvoke(new Action<string>(Navigate), url);
                return;
            }

            webBrowser.Navigate(url);
        }
    }

    /// <summary>
    /// 对应到页面上的每一行数据
    /// 不喜欢中文请自行修改
    /// </summary>
    public class RowData
    {
        public string 航班 { get; set; }
        public string 出发时间 { get; set; }
        public string 到达时间 { get; set; }
        public string 机场 { get; set; }
        public string 机型 { get; set; }
        public string 头等 { get; set; }
        public string 公务 { get; set; }
        public string 全价 { get; set; }
        public string 折扣 { get; set; }
        public string 特价 { get; set; }
    }
posted on 2013-09-10 17:42  xiaowy  阅读(4374)  评论(0编辑  收藏  举报