亨利.王

使用WebClient HttpWebRequest 的高级应用,获取带验证的session下载权限

很多网站的下载是带用户验证的,这样以前方便的webclient.download方法就没法请求到目标数据了。HttpWebRequest .GetResponse同样不可以。

这里为这两个组件提供两个可用的验证下载,思路都是利用webbrowser获得cookie信息然后构造成合法的cookie传给两个组件,从而提供下载权限。

其中HttpWebRequest 的实现是比较容易的,因为HttpWebRequest 自身支持设置CookieContainer信息。所以第一种的实现如下模块:

CookieContainer myCookieContainer = new CookieContainer();

//这里构造我们自己的      CookieContainer      

               string cookieStr = webBrowser1.Document.Cookie;
             string[] cookstr = cookieStr.Split(';');
             foreach (string str in cookstr)
             {
                 string[] cookieNameValue = str.Split('=');
                 Cookie ckk = new Cookie(cookieNameValue[0].Trim().ToString(), cookieNameValue[1].Trim().ToString());
               
                 ckk.Domain =" www.xxx.com";//必须写对
                 myCookieContainer.Add(ckk);

              }

//下边将构造好的cookie传给HttpWebRequest对象,并构造输出流读取下载信息

string actionUrl = "http://10.1.1.78/file.php/12/esd1005/20100510AM/000.asf";

HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(actionUrl);

//传递CookieContainer

httpRequest.CookieContainer = myCookieContainer;


HttpWebResponse response = (HttpWebResponse)httpRequest.GetResponse();

////将响应放到Stream里
Stream responseStream = response.GetResponseStream();
StreamReader responseReader = new StreamReader(responseStream);

这样就获取到网站返回的输出流了,并放入了StreamReader中,怎么处置大家都知道了。

下边说WebClient对象,仔细研究一下,这个对象很有点意思,它每次发起请求并不保存自己原来的cookie,所以它本身也不能设置 CookieContainer属性,这就很让人不耐烦了。后来在csdn中看到一个更有意思的事,它发送请求时利用了使用GetWebRequest方 法返回了WebRequest对象。什么意思呢?如果这个方法获取的WebRequest是HttpWebRequest我们就可以在这个方法里加入 CookieContainer对象了,在进一步说,可以重写次方法让其保持cookie信息。

重写代码如下:

public class HttpClient : WebClient
    {
        // Cookie 容器
        private CookieContainer cookieContainer;

        /**/
        /// <summary>
        /// 创建一个新的 WebClient 实例。
        /// </summary>
        public HttpClient()
        {
            this.cookieContainer = new CookieContainer();
        }

        /**/
        /// <summary>
        /// 创建一个新的 WebClient 实例。
        /// </summary>
        /// <param name="cookie">Cookie 容器</param>
        public HttpClient(CookieContainer cookies)
        {
            this.cookieContainer = cookies;
        }

        /**/
        /// <summary>
        /// Cookie 容器
        /// </summary>
        public CookieContainer Cookies
        {
            get { return this.cookieContainer; }
            set { this.cookieContainer = value; }
        }

        /**/
        /// <summary>
        /// 返回带有 Cookie 的 HttpWebRequest。
        /// </summary>
        /// <param name="address"></param>
        /// <returns></returns>
        protected override WebRequest GetWebRequest(Uri address)
        {
            WebRequest request = base.GetWebRequest(address);
            if (request is HttpWebRequest)
            {
                HttpWebRequest httpRequest = request as HttpWebRequest;
                httpRequest.CookieContainer = cookieContainer;
            }
            return request;
        }

    }

这样我们以后就可以直接引用

HttpClient对象来使用webclient,不难看出HttpClient继承了WebCilent,并加入了初始化cookie的构造函 数,什么意思呢?我们就可以直接在构造HttpClient对象时将我们刚才获取的cookieContainer传给该对象。然后就可以直接获取到用户 验证的下载权限了额。

其实道理很简单,有人说还可以使用webclient的Header的add方法添加cookie,但是烨炫觉得那样依然不妥,因为测试中直接在原来的webclient对象的头部添加cookie字段,是无效的,因为发送请求时cookie又被重置了的。。。

说的有点乱,都是烨炫自己写程序中遇到的一些问题和解决方案,如果对您有帮助,烨炫会很荣幸,又错误或不妥的地方也请您指出大家一起讨论~

作者:烨炫

烨炫原创文章,转载任意,但请注明出处~~
本文原始地址:http://hi.baidu.com/rabby163/blog/item/7e7008507601297184352444.html

posted on 2011-07-13 17:51  亨利.王  阅读(1262)  评论(1编辑  收藏  举报

导航