在采集需要登陆后访问的页面中,采集程序需要保存登录后获取的cookie,由于有些网站登录验证成功后就将用户直接重定向到目标页,
如: Response.Redirect("/user/index.asp")
响应头部含如下参数
Location: /user/index.aspx
Set-Cookie: .ASPXAUTH=3DABFC1691FD31F16EFF68D55202130196135D8B3F0A8B630C956242FBBA802EDB912E0B84D6601A6F425824DA1C28AFBDF04E6B4D0CA6E7D7EBB7DD2A212F5FFFF2921DF35CE098F603CE31E56D71AD68CC23117123E11AB8323AD86B648665; expires=Thu, 04-Dec-2008 02:59:15 GMT; path=/; HttpOnly
这样在使用WebClient时,不能捕捉到需要的cookie,这个时候就需要使用HttpWebRequest(WebRequest针对http协议的实现)
获取cookieContainer
---------------------------------------
private System.Net.CookieContainer GetCookieContainer(string logUrl,byte[] data)
{
HttpWebRequest request = HttpWebRequest.Create(logUrl) as HttpWebRequest;
request.AllowAutoRedirect = false;//禁止自动重定向
request.Method = "Post"; //使用post方法
request.ContentType = "application/x-www-form-urlencoded";//form提交时使用urlencode
request.ContentLength = data.Length;
request.CookieContainer = new CookieContainer();
Stream uploadStream=request.GetRequestStream();
uploadStream.Write(data, 0, data.Length);
uploadStream.Close();
HttpWebResponse resposne = request.GetResponse() as HttpWebResponse;
resposne.Close();
return request.CookieContainer;//反会获取的cookieContainer
}
//登录后获取cookie再进行数据采集,需要导如System.IO,System.Net,System.Web等命名空间
-------------------------------------------------
string formData=@"Username=xxxx&Password=dafa34@234";//登录页面表单字段
//使用gb2312进行Url编码
formData= HttpUtility.UrlEncode(formData,Encoding.GetEncoding("gb2312"));
//编码为字节数据
byte[] data = Encoding.GetEncoding("gb2312").GetBytes(formData);
//是需要登陆后获取的页面(数据采集页)
Uri dataUri = new Uri("http://wow52.cn/admin/article.aspx");
HttpWebRequest request = WebRequest.Create(dataUri) as HttpWebRequest;
//设置来路,有些站点会检测访问来路来判断是否为盗链等.
//使用WebRequest时你无法直接使用 request.Hands.Add("Referer","http://www.wow52.cn/log.aspx")
//来添加标头
request.Referer="http://www.wow52.cn/log.aspx";
//一些其他设置
//request.Accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-silverlight, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, */*";
//request.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)";
request.Method = "GET";
//登录页地址,需要特别注意的是这个uri的域名必须要与上面一致
//使用www.wow52.cn获取的cookieContainer只有在域名为www.wow52.cn时才会被附加上
//对一些使用了二级域名的站点,各数据页二级域名各不相同的,可以将Cookie逐个取出
//再拼接起来,如: cookieName1=cookieValue1;cookieName2=cookieValue2;...
//将拼写后的字符串添加到Request.Headers中如:request.Headers.Add("Cookie", "拼接串");
Uri logUri = new Uri("http://www.wow52.cn/log.aspx"); //这里设置为http://www.wow52.cn/区别上面dataUri的wow52.cn
//调用上文的GetCookieContainer函数
CookieContainer container = GetCookieContainer(logUri.ToString(), data);
//判断是否是同个域名(主机名)
if (Uri.Compare(dataUri, logUri, UriComponents.Host, UriFormat.SafeUnescaped, StringComparison.OrdinalIgnoreCase) != 0)
{
//逐个取出cookie并更改domain后,添加到request.CookieContainer中
CookieCollection cookies = container.GetCookies(logUri);
request.CookieContainer = new CookieContainer();
foreach (Cookie cookie in cookies)
{
cookie.Domain = dataUri.Host; //使用目标数据页的主机部分
request.CookieContainer.Add(cookie);
}
}
else //domain相同
{
request.CookieContainer = container;
}
//获取响应数据
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding("gb2312"));
string html = sr.ReadToEnd();
response.Close();
txtMsg.Text = html; //txtMsg是文本框
---------------------------
注意,
1.上面代码是直接从vs2005复制过来的,没加格式化,方便于直接复制回去,
2.一般的数据采集下使用WebClient比较方便,也可以一起使用WebClient跟WebRequest.
3.WebRequest.AllowAutoRedirect=false;属性 来防止自动重定向
4.WebRequest 想设置Referer 标头时使用 WebRequest.Referer="xxxx" ,直接WebRequest.Headers.Add是不行的
不过使用webClient时可以这么做.
5.注意上面的编码post数据一般要先进行urlEncode,并且指明
request.ContentType = "application/x-www-form-urlencoded";
webClient时使用 webClient.Headers.Add("Content-Type","application/x-www-form-urlencode");
另外在将数据转化成byte[] data(字节数组时)请确认网站使用的编码是utf-8还是gb2312或其他,同样获取返会的数据后(指本类型的),也要根据站点的编码进行转化(到字符串)
6.上面使用formdata是虚拟的,呵呵,防止你黑了我的站(^_^),你如果要测试,请自己另外找个站点,另外.net表单提交时会有一些状态信息,这些你可以通过一向代理工具来获取,并分析得出需要的post数据格式.
另外对于带图片验证码的登录,一般我们在使用WebRequest下载图片时需要同时保存下载图片时的临时SessionID(也是cookie),在提交表单时要将这个SessionID数据(cookie)附加到标头上,这样就可以通过验证,至于图片识别,一般使用图片框显示后人工识别(通用情况下).
参考资料
HttpWebRequest