/// <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; }
}