• 采集程序需要保存登录后获取的cookie


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

  • 相关阅读:
    小程序开发日志-1、小程序自带的日志功能
    java判断List里面的值是否存在重复元素
    java给List<String>批量赋值方法
    (转)post请求携带cookie时配置跨域问题(withCredentials设置)
    redis远程连接不上,配置redis远程连接
    Velocity判断是否为空(Velocity基本语法)
    mysql设置权限,添加远程访问用户
    java 接收邮件时附件中文乱码问题
    JAVA AES加解密问题(解密时出错)
    om.baomidou.mybatisplus.core.exceptions.MybatisPlusException: 该模式不能应用于非数据库字段!
  • 原文地址:https://www.cnblogs.com/wanglinglong/p/1557261.html
Copyright © 2020-2023  润新知