1、打开查询网页
如http://www.skyteamcargo.com/en/tracking/,该页面有两个文本框,供用户输入业务代码,如180-36898035,
2、 然后单击“Go”按钮
现在要求以上步骤都用程序自动实现,并把查询结果提取出来,以备后面进一步处理。 要完成这样的功能,首先要解决以下几个问题:
能够用程序在后台将数据Post到目标网页
能接收到对方返回的HTML结果页面
能够分析该页面,并将需要的结果提取出来
经过一番研究和实验,我解决了以上几个问题,下面分别描述。 1.用程序将指定数据Post到目标网页,并接收结果网页 我先用网络嗅探器来捕获用IE手工查询时浏览器和对方网页的HTTP协议交互过程,这里推荐用Ultra Network Sniffer,它有个Connection Monitor功能,可以监视某个程序的所有连接,这样就避免了其他无关数据包的干扰。如图
当在查询页面里输入数据后,点击“Go”按钮,嗅探器捕捉到的数据包如下图
请注意第三行,有一个Post数据包,这个就是我们需要的,
awbpre=180&awbnum=36898035&x=17&y=9
很显然,180和36898035是可以替换的,而且要注意的是发送的目标网页不再是我们在浏览器里直接输入的初始页面http://www.skyteamcargo.com/en/tracking/了 下面我们用程序来发送这段数据,代码如下
---------------------
public static string GetPage(string url, string postData, string encodeType, out string err)
{
Stream outstream = null;
Stream instream = null;
StreamReader sr = null;
HttpWebResponse response = null;
HttpWebRequest request = null;
Encoding encoding = Encoding.GetEncoding(encodeType);
byte[] data = encoding.GetBytes(postData);
// 准备请求...
try
{
// 设置参数
request = WebRequest.Create(url) as HttpWebRequest;
CookieContainer cookieContainer = new CookieContainer();
request.CookieContainer = cookieContainer;
request.AllowAutoRedirect = true;
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
outstream = request.GetRequestStream();
outstream.Write(data, 0, data.Length);
outstream.Close();
//发送请求并获取相应回应数据
response = request.GetResponse() as HttpWebResponse;
//直到request.GetResponse()程序才开始向目标网页发送Post请求
instream = response.GetResponseStream();
sr = new StreamReader(instream, encoding);
//返回结果网页(html)代码
string content = sr.ReadToEnd();
err = string.Empty;
return content;
}
catch (Exception ex)
{
err = ex.Message;
return string.Empty;
}
}
--------------------------
谈几点要注意的问题: 如果你需要保留SessionID,则在向下一个页面发送请求之前将前一个request返回的cookieContainer赋值给新的request,因为在cookieContainer中保留了一个叫做ASPNETSessionID的Cookie。 如果你Post的目标页面是ASP.NET页面,则一般在要提交的Form里都有一个__ViewState隐藏Input字段,一个服务器返回的网页源码的ViewState的例子如下,
--------------------------
-------------------------
然而在嗅探器中捕捉到的Post数据是:
__VIEWSTATE=dDwtMzg4MDA0NzA7Oz7%2BjHQ0vF37%2Fga2CitRkQ3sfg%2BePg%3D%3D&UserName=admin&Password=123&Submit=Button0
请大家注意,这里ViewState的数据和前面的有点不一样,差别是其中的”+/=”等符号都被转成了%2B,%2F,%3D等,这其实将ViewState的值进行了URL编码,大家可以用System.Web.HttpUtility.UrlEncode()方法来做这种转换 当然,如果你只需要对页面做一次性访问,则大可不必理会这些,只用根据嗅探器捕获的结果来发送数据就可以了,但是如果你需要根据页面返回的ViewState值动态处理,则需要注意这一点。