您的位置:首页 > 其它

采集需要登录后的网页(重定向后cookie丢失问题)

2008-12-03 13:20 387 查看
 

   在采集需要登陆后访问的页面中,采集程序需要保存登录后获取的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

 

 

google_ad_client = "pub-9768854185654179";
/* 468x60, 创建于 09-2-12 */
google_ad_slot = "6840815711";
google_ad_width = 468;
google_ad_height = 60;

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐