博客园  :: 联系 :: 管理

【转】关于wininet, WebBrowser, WebClient, HttpWebRequest

Posted on 2011-07-01 17:41  独孤雁  阅读(719)  评论(0编辑  收藏  举报

-------------------------------------------------------------------------------------------------------------

WebClient

WebClient
Mircsoft在dotnet1.1框架下提供的向 URI 标识的资源发送数据和从 URI 标识的资源接收数据的公共方法。
通过这个类,大家可以在脱离浏览器的基础上模拟浏览器对互联网上的资源的访问和发送信息。
WebClient类不能被继承,在dotnet1.1框架中已经为我们提供了WebRequest和WebResponse两个强大的类来
处理向URI标示的资源和获取数据了。然后,不足的是利用WebRequest和WebResponse时设置过于复杂。
使用起来颇为费劲。于是乎有了现在的WebClient,WebClient其实可以理解为对WebRequest和WebResponse等
协作的封装。它使人们使用起来更加简单方便,然后它也有先天不足的地方。那就是缺少对cookies/session的
支持,用户无法对是否自动url转向的控制,还有就是缺少对代理服务器的支持。关于session/url转向控制/代理
服务器的使用我将在以后关于WebRequest/WebResponse的话题里面向大家介绍。下面先给大家简单介绍一
下WebClinet类。

类名:WebClient
命名空间System.Net.WebClient

公共构造函数

WebClient 构造函数 初始化 WebClient 类的新实例。

公共属性

BaseAddress 获取或设置 WebClient 发出请求的基 URI。
Container(从 Component 继承) 获取 IContainer,它包含 Component
Credentials 获取或设置用于对向 Internet 资源的请求进行身份验证的网络凭据。
Headers 获取或设置与请求关联的标头名称/值对集合。
QueryString 获取或设置与请求关联的查询名称/值对集合。
ResponseHeaders 获取与响应关联的标头名称/值对集合。
Site(从 Component 继承) 获取或设置 ComponentISite

公共方法

CreateObjRef(从 MarshalByRefObject 继承) 创建一个对象,该对象包含生成用于与远程对象进行通讯的代理所需的全部相关信息。
Dispose(从 Component 继承) 已重载。释放由 Component 占用的资源。
DownloadData 从具有指定 URI 的资源下载数据。
DownloadFile 从具有指定 URI 的资源将数据下载到本地文件。
Equals(从 Object 继承) 已重载。确定两个 Object 实例是否相等。
GetHashCode(从 Object 继承) 用作特定类型的哈希函数,适合在哈希算法和数据结构(如哈希表)中使用。
GetLifetimeService(从 MarshalByRefObject 继承) 检索控制此实例的生存期策略的当前生存期服务对象。
GetType(从 Object 继承) 获取当前实例的 Type
InitializeLifetimeService(从 MarshalByRefObject 继承) 获取控制此实例的生存期策略的生存期服务对象。
OpenRead 为从具有指定 URI 的资源下载的数据打开一个可读的流。
OpenWrite 已重载。打开一个流以将数据写入具有指定 URI 的资源。
ToString(从 Object 继承) 返回表示当前 ObjectString
UploadData 已重载。将数据缓冲区上载到具有指定 URI 的资源。
UploadFile 已重载。将本地文件上载到具有指定 URI 的资源。
UploadValues 已重载。将名称/值集合上载到具有指定 URI 的资源。


从上表中我们可以看到WebClient提供四种将数据上载到资源的方法:
  • OpenWrite 返回一个用于将数据发送到资源的 Stream
  • UploadData 将字节数组发送到资源并返回包含任何响应的字节数组。
  • UploadFile 将本地文件发送到资源并返回包含任何响应的字节数组。
  • UploadValuesNameValueCollection 发送到资源并返回包含任何响应的字节数组。

另外WebClient还提供三种从资源下载数据的方法:


下面我们将通过一个简单的应用程序来测试WebClient的最简单用法作为本小节的结束让大家对WebClient有个初步的认识

例子1:利用WebClient实现对博客园首页的访问

首先我们用HttpLook对这次访问进行分析,为了方便分析我特别将浏览器对图片的访问去掉 让我们能看到更简便的分析结果

我们可以看到整个过程中我们发起了4次资源请求,其中第一次是对博客园首页进行访问
第二次访问的是样式表文件,第三和四次访问的是js脚本。
我们点击第一项可以看见关于这次资源访问的http头部信息,所谓http头部就是我们不能看见的浏览器和远程服务器传递的一些不可见元素。

1GET/HTTP/1.1
2Accept:image/gif,image/x-xbitmap,image/jpeg,image/pjpeg,application/x-shockwave-flash,application/vnd.ms-excel,application/vnd.ms-powerpoint,application/msword,*/*
3Accept-Language:zh-cn
4UA-CPU:x86
5Accept-Encoding:gzip,deflate
6User-Agent:Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.2;SV1;.NETCLR1.1.4322;.NETCLR2.0.50727)
7Host:www.cnblogs.com
8Connection:Keep-Alive
9Cookie:.DottextCookie=(隐藏)

这些http信息包含了浏览器访问的过程。其中
第一行:请求地址的相对路径和使用协议 相对路径为/ 协议采用http1.1
第二行:表示我们请求的资源种类。
第三行:我们的语言是简体中文。
第四行:我们使用的cup结构。这个http头在一般的网页中并不过见。估计是博客园的一次调查??
第五行:标示采用gzip方式压缩html编码进行传递。只有一些浏览器支持的gzip解压缩时采用这种方式传递文本。由于我们
要写的程序不具备gzi解压缩的能力 所以我们不考虑使用这种方式发送请求。
第六行:浏览器说明
第七行:当前主机地址
第八行:连接请求状态
第九行:cookies信息

我在新建的应用程序里面利用WebClient来实现这了一过程。


下面我将就关键实现做一些解释

1WebClient_client=newWebClient();
2_client.BaseAddress="http://www.cnblogs.com";
3_client.Headers.Add("Accept","image/gif,image/x-xbitmap,image/jpeg,image/pjpeg,application/x-shockwave-flash,application/vnd.ms-excel,application/vnd.ms-powerpoint,application/msword,*/*");
4_client.Headers.Add("Accept-Language","zh-cn");
5_client.Headers.Add("UA-CPU","x86");
6//_client.Headers.Add("Accept-Encoding","gzip,deflate");
7_client.Headers.Add("User-Agent","Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.2;SV1;.NETCLR1.1.4322;.NETCLR2.0.50727)");
8System.IO.StreamobjStream=_client.OpenRead("/");
9System.IO.StreamReader_read=newSystem.IO.StreamReader(objStream,System.Text.Encoding.UTF8);
10textBox1.Text=_read.ReadToEnd();


第一行:新建一个WebClient 实例_client
第二行~第七行:将上边捕捉到的Http头部放入到_client实例,注意第六行的被注释掉了。因为我们的程序无法进行gzip解码所以如果这样请求
获得的资源可能无法解码。当然我们可以给程序加入gzip处理的模块 那是题外话了。
第八行:利用_client.OpenRead(string URI)的方法获取网上资源的Stream
第九行:利用StreamReader将Stream用我们需要的编码方法去解析。这里使用了UTF8。对应不同的网站可以使用Default等不同的解码方法。
第十行:将我们解码后的内容放到textBox1里面显示出来

好了 大致关于WebClient的介绍就到这里了。以后将为大家陆续介绍WebClient的各种属性和方法。
利用WebClient做个资源小偷其实是很简单的,所以大家一定要防盗链阿!!!

本段内容来自:http://wangdetian168.javaeye.com/blog/388701

-------------------------------------------------------------------------------------------------------------

HttpWebRequest类,隶属于System.Net

HttpWebRequest类有什么作用?

以下摘自MSDN,对于HttpWebRequest类的描述

备注

HttpWebRequest 类对 WebRequest 中定义的属性和方法提供支持,也对使用户能够直接与使用 HTTP 的服务器交互的附加属性和方法提供支持。

不要使用 HttpWebRequest 构造函数。使用 System.Net.WebRequest.Create 方法初始化新的 HttpWebRequest 对象。如果统一资源标识符 (URI) 的方案是 http:// https://,则 Create 返回 HttpWebRequest 对象。

GetResponse 方法向 RequestUri 属性中指定的资源发出同步请求并返回包含该响应的 HttpWebResponse。可以使用 BeginGetResponse EndGetResponse 方法对资源发出异步请求。

当要向资源发送数据时,GetRequestStream 方法返回用于发送数据的 Stream 对象。BeginGetRequestStream EndGetRequestStream 方法提供对发送数据流的异步访问。

对于使用 HttpWebRequest 的客户端验证身份,客户端证书必须安装在当前用户的“我的证书”存储区中。

如果在访问资源时发生错误,则 HttpWebRequest 类将引发 WebExceptionWebException.Status 属性包含指示错误源的 WebExceptionStatus 值。当 WebException.Status WebExceptionStatus.ProtocolError 时,Response 属性包含从资源接收的 HttpWebResponse

HttpWebRequest 将发送到 Internet 资源的公共 HTTP 标头值公开为属性,由方法或系统设置;下表包含完整列表。可以将 Headers 属性中的其他标头设置为名称/值对。注意,服务器和缓存在请求期间可能会更改或添加标头。

 

 

 

 

个人理解,HttpWebRequest类可以帮助我们不需要通过浏览器就可以获取我们所需要的页面内容,主要表现在如自动登录自动发布,或者一些基于Web的软件外挂

 

 

运用HttpWebRequest类,总体可以概括成以下几步:
第一步找出需要提交的数据;第二步访问该页面,取出页面的一些动态信息(如:隐藏域,验证码等信息);第三步组成Post的数据并发送请求;第四步分析返回的HTML并显示结果

 

首先,让我们了解一下表单提交数据的两种形式:

        FORM元素的enctype属性指定了表单数据向服务器提交时所采用的编码类型,默认的缺省值是“application/x-www-form-urlencoded”,后跟页面编码格式,如:UTF-8,GB2312等。

然而,在向服务器发送大量的文本、包含非ASCII字符的文本或二进制数据时这种编码方式效率很低。

在文件上载时,所使用的编码类型应当是“multipart/form-data”,它既可以发送文本数据,也支持二进制数据上载。

         Browser端<form>表单的ENCTYPE属性值为multipart/form-data,它告诉我们传输的数据要用到多媒体传输 协议,由于多媒体传输的都是大量的数据,所以规定上传文件必须是post方法,<input>的type属性必须是file。

 

 

我们再了解一下,通过哪些工具可以截取我们向页面提交的数据

下面以http:www.toocle.com这个网站的登录为例:在首页,输入用户名和密码,然后登录。

这里是用IE HTTPAnalyzer V3这个工具抓的包



这里介绍几款网络数据抓包工具:

1.IE HTTPAnalyzer V3

2.HttpWatch

3.Fiddler

 

 

知道了要向页面提交哪些数据之后,就要来构造我们的POST数据

如:上面的示例构造数据流应该是:“returl=&username=gangx6&password=gangx20&f1=Login&f=login1”,数据流的格式,是以参数名=参数值然后跟连接符号&

      //预览网址
string preUrl = "
http://www.toocle.com/";
//处理网址
string actionUrl = "
http://www.toocle.com/member/index.cgi";
string userName = textBox1.Text.ToString();
string userPwd = textBox2.Text.ToString();
//Post数据流
string content = "returl=&username=" + userName + "&password=" + userPwd + "&f1=Login&f=login1";


 

然后对HttpWebRequest类的其他成员赋值:

      httpRequest = (HttpWebRequest)WebRequest.Create(actionUrl);
//允许跳转
httpRequest.AllowAutoRedirect = true;
//是否保持连接
httpRequest.KeepAlive = true;
//设置 Accept HTTP 标头的值
httpRequest.Accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash"
//设置 User-agentHTTP 标头的值,主要是浏览器类型
httpRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0)"
//表单提交类型,上面有提到
httpRequest.ContentType = "application/x-www-form-urlencoded";
//数据是POST上去的,当然还有GET方式
httpRequest.Method = "POST";
//设置 RefererHTTP 标头的值,其实也就是来源了,有的网站禁止从外部提交数据就是通过它来判断的
httpRequest.Referer = preUrl;


 

 

最后,获取返回的流Response,然后我们再作其他处理。

      //返回来自 Internet 资源的响应
HttpWebResponse response = (HttpWebResponse)httpRequest.GetResponse();
//将响应放到Stream里
Stream responseStream = response.GetResponseStream();
StreamReader responseReader = new StreamReader(responseStream)
//得到我们要的结果
result = responseReader.ReadToEnd();

-------------------------------------------------------------------------------------------------------------