c# HttpWebRequest与HttpWebResponse 绝技
来源:互联网 发布:nginx反向代理socket 编辑:程序博客网 时间:2024/06/06 06:53
在线测试工具http://www.sufeinet.com/thread-3690-1-1.html
原文地址:http://www.sufeinet.com/thread-6-1-1.html
c# HttpWebRequest与HttpWebResponse 绝技如果你想做一些,抓取,或者是自动获取的功能,那么就跟我一起来学习一下Http请求吧。
本文章会对Http请求时的Get和Post方式进行详细的说明,
在请求时的参数怎么发送,怎么带Cookie,怎么设置证书,怎么解决 编码等问题,进行一步一步的解决。
* 如果要使用中间的方法的话,可以访问我的帮助类完全免费开源:
这个类是专门为HTTP的GET和POST请求写的,解决了编码,证书,自动带Cookie等问题。
C# HttpHelper,帮助类,真正的Httprequest请求时无视编码,无视证书,无视Cookie,网页抓取
1.第一招,根据URL地址获取网页信息
先来看一下代码
get方法
[C#] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
public
static
string
GetUrltoHtml(
string
Url,
string
type)
{
try
{
System.Net.WebRequest wReq = System.Net.WebRequest.Create(Url);
// Get the response instance.
System.Net.WebResponse wResp = wReq.GetResponse();
System.IO.Stream respStream = wResp.GetResponseStream();
// Dim reader As StreamReader = New StreamReader(respStream)
using
(System.IO.StreamReader reader =
new
System.IO.StreamReader(respStream, Encoding.GetEncoding(type)))
{
return
reader.ReadToEnd();
}
}
catch
(System.Exception ex)
{
//errorMsg = ex.Message;
}
return
""
;
}
post方法
[C#] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
///<summary>
///采用https协议访问网络
///</summary>
///<param name="URL">url地址</param>
///<param name="strPostdata">发送的数据</param>
///<returns></returns>
public
string
OpenReadWithHttps(
string
URL,
string
strPostdata,
string
strEncoding)
{
Encoding encoding = Encoding.Default;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
request.Method =
"post"
;
request.Accept =
"text/html, application/xhtml+xml, */*"
;
request.ContentType =
"application/x-www-form-urlencoded"
;
byte
[] buffer = encoding.GetBytes(strPostdata);
request.ContentLength = buffer.Length;
request.GetRequestStream().Write(buffer, 0, buffer.Length);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using
( StreamReader reader =
new
StreamReader(response.GetResponseStream(), System.Text.Encoding.GetEncoding(strEncoding)))
{
return
reader.ReadToEnd();
}
}
这招是入门第一式, 特点:
1.最简单最直观的一种,入门课程。
2.适应于明文,无需登录,无需任何验证就可以进入的页面。
3.获取的数据类型为HTML文档。
4.请求方法为Get/Post
2.第二招,根据URL地址获取需要验证证书才能访问的网页信息
先来看一下代码
get方法
[C#] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
/回调验证证书问题
public
bool
CheckValidationResult(
object
sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{
// 总是接受
return
true
;
}
/// <summary>
/// 传入URL返回网页的html代码
/// </summary>
/// <param name="Url">URL</param>
/// <returns></returns>
public
string
GetUrltoHtml(
string
Url)
{
StringBuilder content =
new
StringBuilder();
try
{
//这一句一定要写在创建连接的前面。使用回调的方法进行证书验证。
ServicePointManager.ServerCertificateValidationCallback =
new
System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);
// 与指定URL创建HTTP请求
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
//创建证书文件
X509Certificate objx509 =
new
X509Certificate(Application.StartupPath +
"\\123.cer"
);
//添加到请求里
request.ClientCertificates.Add(objx509);
// 获取对应HTTP请求的响应
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
// 获取响应流
Stream responseStream = response.GetResponseStream();
// 对接响应流(以"GBK"字符集)
StreamReader sReader =
new
StreamReader(responseStream, Encoding.GetEncoding(
"utf-8"
));
// 开始读取数据
Char[] sReaderBuffer =
new
Char[256];
int
count = sReader.Read(sReaderBuffer, 0, 256);
while
(count > 0)
{
String tempStr =
new
String(sReaderBuffer, 0, count);
content.Append(tempStr);
count = sReader.Read(sReaderBuffer, 0, 256);
}
// 读取结束
sReader.Close();
}
catch
(Exception)
{
content =
new
StringBuilder(
"Runtime Error"
);
}
return
content.ToString();
}
post方法
[C#] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
//回调验证证书问题
public
bool
CheckValidationResult(
object
sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{
// 总是接受
return
true
;
}
///<summary>
///采用https协议访问网络
///</summary>
///<param name="URL">url地址</param>
///<param name="strPostdata">发送的数据</param>
///<returns></returns>
public
string
OpenReadWithHttps(
string
URL,
string
strPostdata,
string
strEncoding)
{
// 这一句一定要写在创建连接的前面。使用回调的方法进行证书验证。
ServicePointManager.ServerCertificateValidationCallback =
new
System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);
Encoding encoding = Encoding.Default;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
//创建证书文件
X509Certificate objx509 =
new
X509Certificate(Application.StartupPath +
"\\123.cer"
);
//加载Cookie
request.CookieContainer =
new
CookieContainer();
//添加到请求里
request.ClientCertificates.Add(objx509);
request.Method =
"post"
;
request.Accept =
"text/html, application/xhtml+xml, */*"
;
request.ContentType =
"application/x-www-form-urlencoded"
;
byte
[] buffer = encoding.GetBytes(strPostdata);
request.ContentLength = buffer.Length;
request.GetRequestStream().Write(buffer, 0, buffer.Length);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using
(StreamReader reader =
new
StreamReader(response.GetResponseStream(), System.Text.Encoding.GetEncoding(strEncoding)))
{
return
reader.ReadToEnd();
}
}
这招是学会算是进了大门了,凡是需要验证证书才能进入的页面都可以使用这个方法进入,我使用的是证书回调验证的方式,证书验证是否通过在客户端验证,这样的话我们就可以使用自己定义一个方法来验证了,有的人会说那也不清楚是怎么样验证的啊,其它很简单,代码是自己写的为什么要那么难为自己呢,直接返回一个True不就完了,永远都是验证通过,这样就可以无视证书的存在了, 特点:
1.入门前的小难题,初级课程。
2.适应于无需登录,明文但需要验证证书才能访问的页面。
3.获取的数据类型为HTML文档。
4.请求方法为Get/Post
3.第三招,根据URL地址获取需要登录才能访问的网页信息
我们先来分析一下这种类型的网页,需要登录才能访问的网页,其它呢也是一种验证,验证什么呢,验证客户端是否登录,是否具用相应的凭证,需要登录的都要验证SessionID这是每一个需要登录的页面都需要验证的,那我们怎么做的,我们第一步就是要得存在Cookie里面的数据包括SessionID,那怎么得到呢,这个方法很多,使用ID9或者是火狐浏览器很容易就能得到,可以参考我的文章
提供一个网页抓取hao123手机号码归属地的例子 这里面针对ID9有详细的说明。
如果我们得到了登录的Cookie信息之后那个再去访问相应的页面就会非常的简单了,其它说白了就是把本地的Cookie信息在请求的时候捎带过去就行了。
看代码
get方法
[C#] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
/// <summary>
/// 传入URL返回网页的html代码带有证书的方法
/// </summary>
/// <param name="Url">URL</param>
/// <returns></returns>
public
string
GetUrltoHtml(
string
Url)
{
StringBuilder content =
new
StringBuilder();
try
{
// 与指定URL创建HTTP请求
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
request.UserAgent =
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; BOIE9;ZHCN)"
;
request.Method =
"GET"
;
request.Accept =
"*/*"
;
//如果方法验证网页来源就加上这一句如果不验证那就可以不写了
request.Referer =
"http://sufei.cnblogs.com"
;
CookieContainer objcok =
new
CookieContainer();
objcok.Add(
new
Uri(
"http://sufei.cnblogs.com"
),
new
Cookie(
"键"
,
"值"
));
objcok.Add(
new
Uri(
"http://sufei.cnblogs.com"
),
new
Cookie(
"键"
,
"值"
));
objcok.Add(
new
Uri(
"http://sufei.cnblogs.com"
),
new
Cookie(
"sidi_sessionid"
,
"360A748941D055BEE8C960168C3D4233"
));
request.CookieContainer = objcok;
//不保持连接
request.KeepAlive =
true
;
// 获取对应HTTP请求的响应
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
// 获取响应流
Stream responseStream = response.GetResponseStream();
// 对接响应流(以"GBK"字符集)
StreamReader sReader =
new
StreamReader(responseStream, Encoding.GetEncoding(
"gb2312"
));
// 开始读取数据
Char[] sReaderBuffer =
new
Char[256];
int
count = sReader.Read(sReaderBuffer, 0, 256);
while
(count > 0)
{
String tempStr =
new
String(sReaderBuffer, 0, count);
content.Append(tempStr);
count = sReader.Read(sReaderBuffer, 0, 256);
}
// 读取结束
sReader.Close();
}
catch
(Exception)
{
content =
new
StringBuilder(
"Runtime Error"
);
}
return
content.ToString();
}
post方法。
[C#] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
///<summary>
///采用https协议访问网络
///</summary>
///<param name="URL">url地址</param>
///<param name="strPostdata">发送的数据</param>
///<returns></returns>
public
string
OpenReadWithHttps(
string
URL,
string
strPostdata)
{
Encoding encoding = Encoding.Default;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
request.Method =
"post"
;
request.Accept =
"text/html, application/xhtml+xml, */*"
;
request.ContentType =
"application/x-www-form-urlencoded"
;
CookieContainer objcok =
new
CookieContainer();
objcok.Add(
new
Uri(
"http://sufei.cnblogs.com"
),
new
Cookie(
"键"
,
"值"
));
objcok.Add(
new
Uri(
"http://sufei.cnblogs.com"
),
new
Cookie(
"键"
,
"值"
));
objcok.Add(
new
Uri(
"http://sufei.cnblogs.com"
),
new
Cookie(
"sidi_sessionid"
,
"360A748941D055BEE8C960168C3D4233"
));
request.CookieContainer = objcok;
byte
[] buffer = encoding.GetBytes(strPostdata);
request.ContentLength = buffer.Length;
request.GetRequestStream().Write(buffer, 0, buffer.Length);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader reader =
new
StreamReader(response.GetResponseStream(), System.Text.Encoding.GetEncoding(
"utf-8"
));
return
reader.ReadToEnd();
}
特点:
1.还算有点水类型的,练习成功后可以小牛一把。
2.适应于需要登录才能访问的页面。
3.获取的数据类型为HTML文档。
4.请求方法为Get/Post
总结一下,其它基本的技能就这几个部分,如果再深入的话那就是基本技能的组合了
比如,
1. 先用Get或者Post方法登录然后取得Cookie再去访问页面得到信息,这种其它也是上面技能的组合,
这里需要以请求后做这样一步
[code=csharp]response.Cookies[/code]这就是在你请求后可以得到当次Cookie的方法,直接取得返回给上一个方法使用就行了,上面我们都是自己构造的,在这里直接使用这个Cookie就可以了。
2.如果我们碰到需要登录而且还要验证证书的网页怎么办,其它这个也很简单把我们上面的方法综合 一下就行了
如下代码这里我以Get为例子Post例子也是同样的方法
[C#] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
/// <summary>
/// 传入URL返回网页的html代码
/// </summary>
/// <param name="Url">URL</param>
/// <returns></returns>
public
string
GetUrltoHtml(
string
Url)
{
StringBuilder content =
new
StringBuilder();
try
{
//这一句一定要写在创建连接的前面。使用回调的方法进行证书验证。
ServicePointManager.ServerCertificateValidationCallback =
new
System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);
// 与指定URL创建HTTP请求
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
//创建证书文件
X509Certificate objx509 =
new
X509Certificate(Application.StartupPath +
"\\123.cer"
);
//添加到请求里
request.ClientCertificates.Add(objx509);
CookieContainer objcok =
new
CookieContainer();
objcok.Add(
new
Uri(
"http://www.cnblogs.com"
),
new
Cookie(
"键"
,
"值"
));
objcok.Add(
new
Uri(
"http://www.cnblogs.com"
),
new
Cookie(
"键"
,
"值"
));
objcok.Add(
new
Uri(
"http://www.cnblogs.com"
),
new
Cookie(
"sidi_sessionid"
,
"360A748941D055BEE8C960168C3D4233"
));
request.CookieContainer = objcok;
// 获取对应HTTP请求的响应
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
// 获取响应流
Stream responseStream = response.GetResponseStream();
// 对接响应流(以"GBK"字符集)
StreamReader sReader =
new
StreamReader(responseStream, Encoding.GetEncoding(
"utf-8"
));
// 开始读取数据
Char[] sReaderBuffer =
new
Char[256];
int
count = sReader.Read(sReaderBuffer, 0, 256);
while
(count > 0)
{
String tempStr =
new
String(sReaderBuffer, 0, count);
content.Append(tempStr);
count = sReader.Read(sReaderBuffer, 0, 256);
}
// 读取结束
sReader.Close();
}
catch
(Exception)
{
content =
new
StringBuilder(
"Runtime Error"
);
}
return
content.ToString();
}
3.如果我们碰到那种需要验证网页来源的方法应该怎么办呢,这种情况其它是有些程序员会想到你可能会使用程序,自动来获取网页信息,为了防止就使用页面来源来验证,就是说只要不是从他们所在页面或是域名过来的请求就不接受,有的是直接验证来源的IP,这些都可以使用下面一句来进入,这主要是这个地址是可以直接伪造的
[C#] 纯文本查看 复制代码
01
request.Referer = <a href=
"http://sufei.cnblogs.com"
>[url=http://sufei.cnblogs.com/]http://sufei.cnblogs.com[/url]</a>;
呵呵其它很简单因为这个地址可以直接修改。但是如果服务器上验证的是来源的URL那就完了,我们就得去修改数据包了,这个有点难度暂时不讨论。
4.提供一些与这个例子相配置的方法
过滤HTML标签的方法
URL转化的方法[C#] 纯文本查看 复制代码0102030405060708091011121314151617181920
/// <summary>
/// 过滤html标签
/// </summary>
/// <param name="strHtml">html的内容</param>
/// <returns></returns>
public
static
string
StripHTML(
string
stringToStrip)
{
// paring using RegEx //
stringToStrip = Regex.Replace(stringToStrip,
"</p(?:\\s*)>(?:\\s*)<p(?:\\s*)>"
,
"\n\n"
, RegexOptions.IgnoreCase | RegexOptions.Compiled);
stringToStrip = Regex.Replace(stringToStrip, "
", "
\n", RegexOptions.IgnoreCase | RegexOptions.Compiled);
stringToStrip = Regex.Replace(stringToStrip,
"\""
,
"''"
, RegexOptions.IgnoreCase | RegexOptions.Compiled);
stringToStrip = StripHtmlXmlTags(stringToStrip);
return
stringToStrip;
}
private
static
string
StripHtmlXmlTags(
string
content)
{
return
Regex.Replace(content,
"<[^>]+>"
,
""
, RegexOptions.IgnoreCase | RegexOptions.Compiled);
}
[C#] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
#region 转化 URL
public
static
string
URLDecode(
string
text)
{
return
HttpUtility.UrlDecode(text, Encoding.Default);
}
public
static
string
URLEncode(
string
text)
{
return
HttpUtility.UrlEncode(text, Encoding.Default);
}
#endregion
提供一个实际例子,这个是使用IP138来查询手机号码归属地的方法,其它在我的上一次文章里都有,在这里我再放上来是方便大家阅读,这方面的技术其它研究起来很有意思,希望大家多提建议,我相信应该还有更多更好,更完善的方法,在这里给大家提供一个参考吧。感谢支持
上例子
[C#] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/// <summary>
/// 输入手机号码得到归属地信息
/// </summary>
/// <param name="number">手机号码</param>
/// <returns>数组类型0为归属地,1卡类型,2区 号,3邮 编</returns>
public
static
string
[] getTelldate(
string
number)
{
try
{
string
strSource = GetUrltoHtml(
"http://www.ip138.com:8080/search.asp?action=mobile&mobile="
+ number.Trim());
//归属地
strSource = strSource.Substring(strSource.IndexOf(number));
strSource = StripHTML(strSource);
strSource = strSource.Replace(
"\r"
,
""
);
strSource = strSource.Replace(
"\n"
,
""
);
strSource = strSource.Replace(
"\t"
,
""
);
strSource = strSource.Replace(
" "
,
""
);
strSource = strSource.Replace(
"-->"
,
""
);
string
[] strnumber = strSource.Split(
new
string
[] {
"归属地"
,
"卡类型"
,
"邮 编"
,
"区 号"
,
"更详细"
,
"卡号"
}, StringSplitOptions.RemoveEmptyEntries);
string
[] strnumber1 =
null
;
if
(strnumber.Length > 4)
{
strnumber1 =
new
string
[] { strnumber[1].Trim(), strnumber[2].Trim(), strnumber[3].Trim(), strnumber[4].Trim() };
}
return
strnumber1;
}
catch
(Exception)
{
return
null
;
}
}
这个例子写是不怎么样,些地方是可以简化的,这个接口而且可以直接使用Xml得到,但我在这里的重点是让一些新手看看方法和思路风凉啊,呵呵
第四招,通过Socket访问[C#] 纯文本查看 复制代码010203040506070809101112131415161718192021222324252627282930313233343536373839404142434445464748///<summary>
/// 请求的公共类用来向服务器发送请求
///</summary>
///<param name="strSMSRequest">发送请求的字符串</param>
///<returns>返回的是请求的信息</returns>
private
static
string
SMSrequest(
string
strSMSRequest)
{
byte
[] data =
new
byte
[1024];
string
stringData =
null
;
IPHostEntry gist = Dns.GetHostByName(
"www.110.cn"
);
IPAddress ip = gist.AddressList[0];
//得到IP
IPEndPoint ipEnd =
new
IPEndPoint(ip, 3121);
//默认80端口号
Socket socket =
new
Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//使用tcp协议 stream类型
try
{
socket.Connect(ipEnd);
}
catch
(SocketException ex)
{
return
"Fail to connect server\r\n"
+ ex.ToString();
}
string
path = strSMSRequest.ToString().Trim();
StringBuilder buf =
new
StringBuilder();
//buf.Append("GET ").Append(path).Append(" HTTP/1.0\r\n");
//buf.Append("Content-Type: application/x-www-form-urlencoded\r\n");
//buf.Append("\r\n");
byte
[] ms = System.Text.UTF8Encoding.UTF8.GetBytes(buf.ToString());
//提交请求的信息
socket.Send(ms);
//接收返回
string
strSms =
""
;
int
recv = 0;
do
{
recv = socket.Receive(data);
stringData = Encoding.ASCII.GetString(data, 0, recv);
//如果请求的页面meta中指定了页面的encoding为gb2312则需要使用对应的Encoding来对字节进行转换()
strSms = strSms + stringData;
//strSms += recv.ToString();
}
while
(recv != 0);
socket.Shutdown(SocketShutdown.Both);
socket.Close();
return
strSms;
}
0 0
- c# HttpWebRequest与HttpWebResponse 绝技
- c# HttpWebRequest与HttpWebResponse 绝技
- c# HttpWebRequest与HttpWebResponse 绝技
- c# HttpWebRequest与HttpWebResponse 绝技
- c# HttpWebRequest与HttpWebResponse 绝技
- c# HttpWebRequest与HttpWebResponse
- c# HttpWebRequest与HttpWebResponse
- c# HttpWebRequest与HttpWebResponse
- C#中HttpWebRequest与HttpWebResponse的使用方法
- C#中HttpWebRequest与HttpWebResponse的使用方法
- C#中HttpWebRequest与HttpWebResponse的使用方法
- C#中HttpWebRequest与HttpWebResponse的使用方法
- C# HttpWebRequest 绝技
- C# HttpWebRequest 绝技
- c# HttpWebRequest与HttpWebResponse请求网页和返回网页教程
- HttpWebRequest 与 HttpWebResponse用法 小记
- httpwebrequest/httpwebresponse
- 使用HttpWebRequest与HttpWebResponse抓取网页数据
- 文章标题
- 继承
- 【实例分析】泰坦尼克之灾
- Java中的类--方法--变量等
- 深入理解计算机系统(CSAPP)课程实验bomb程序炸弹实验日志(phase_4)
- c# HttpWebRequest与HttpWebResponse 绝技
- 方法,数组,面向对象思想
- [学习笔记]设计模式[a]-{状态模式}
- Python3 (入门6) 库的打包与安装
- 织梦dedecms栏目添加自定义字段
- poj 2976 Dropping tests 01分数规划
- h5表单实例
- 跨 html 消息传递
- socket accept后的fd是否占用新端口