• [转]C# 中使用System.Net.Http.HttpClient 模拟登录博客园


    一、 System.Net.Http .HttpClient简介

    System.Net.Http 是微软.net4.5中推出的HTTP 应用程序的编程接口, 微软称之为“现代化的 HTTP 编程接口”, 主要提供如下内容:

    1. 用户通过 HTTP 使用现代化的 Web Service 的客户端组件;

    2. 能够同时在客户端与服务端同时使用的 HTTP 组件(比如处理 HTTP 标头和消息), 为客户端和服务端提供一致的编程模型。

    个人看来是抄袭 apache http client ,目前网上用的人好像不多, 个人认为使用httpclient最大的好处是:不用自己管理cookie,只要负责写好请求即可。

    由于网上资料不多,这里借登录博客园网站做个简单的总结其get和post请求的用法。

    查看微软的api可以发现其属性方法: http://msdn.microsoft.com/zh-cn/library/system.net.http.httpclient.aspx

    由其api可以看出如果想 设置请求头 只需要在 DefaultRequestHeaders 里进行设置

    创建httpcliet可以直接new HttpClient()

    发送请求 可以按发送方式分别调用其方法,如 get调用 GetAsync(Uri) , post调用 PostAsync(Uri, HttpContent) ,其它依此类推。。。

    二、实例(模拟post登录博客园)

    首先,需要说明的是, 本实例环境是win7 64位+vs 2013+ .net 4.5框架。

    1.使用vs2013新建一个控制台程序,或者窗体程序,如下图所示:

    2.必须引入System.Net.Http框架,否则将不能使用httpclient

    3.实现代码

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Net.Http;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Threading.Tasks;
    
    namespace ClassLibrary1
    {
    	public class Class1
    	{
    		private static String dir = @"C:work";
    
    		/// <summary>
    		/// 写文件到本地
    		/// </summary>
    		/// <param name="fileName"></param>
    		/// <param name="html"></param>
    		public static void Write(string fileName, string html)
    		{
    			try
    			{
    				FileStream fs = new FileStream(dir + fileName, FileMode.Create);
    				StreamWriter sw = new StreamWriter(fs, Encoding.Default);
    				sw.Write(html);
    				sw.Close();
    				fs.Close();
    
    			}catch(Exception ex){
    				Console.WriteLine(ex.StackTrace);
    			}
    		   
    		}
    
    		/// <summary>
    		/// 写文件到本地
    		/// </summary>
    		/// <param name="fileName"></param>
    		/// <param name="html"></param>
    		public static void Write(string fileName, byte[] html)
    		{
    			try
    			{
    				File.WriteAllBytes(dir + fileName, html);
    			}
    			catch (Exception ex)
    			{
    				Console.WriteLine(ex.StackTrace);
    			}
    			
    		}
    
    		/// <summary>
    		/// 登录博客园
    		/// </summary>
    		public static void LoginCnblogs()
    		{
    			HttpClient httpClient = new HttpClient();
    			httpClient.MaxResponseContentBufferSize = 256000;
    			httpClient.DefaultRequestHeaders.Add("user-agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.143 Safari/537.36");
    			String url = "http://passport.cnblogs.com/login.aspx";
    			HttpResponseMessage response = httpClient.GetAsync(new Uri(url)).Result;
    			String result = response.Content.ReadAsStringAsync().Result;
    
    			String username = "hi_amos";
    			String password = "密码";
    
    			do
    			{
    				String __EVENTVALIDATION = new Regex("id="__EVENTVALIDATION" value="(.*?)"").Match(result).Groups[1].Value;
    				String __VIEWSTATE = new Regex("id="__VIEWSTATE" value="(.*?)"").Match(result).Groups[1].Value;
    				String LBD_VCID_c_login_logincaptcha = new Regex("id="LBD_VCID_c_login_logincaptcha" value="(.*?)"").Match(result).Groups[1].Value;
    
    				//图片验证码
    				url = "http://passport.cnblogs.com" + new Regex("id="c_login_logincaptcha_CaptchaImage" src="(.*?)"").Match(result).Groups[1].Value;
    				response = httpClient.GetAsync(new Uri(url)).Result;
    				Write("amosli.png", response.Content.ReadAsByteArrayAsync().Result);
    				
    				Console.WriteLine("输入图片验证码:");
    				String imgCode = "wupve";//验证码写到本地了,需要手动填写
    				imgCode =  Console.ReadLine();
    
    				//开始登录
    				url = "http://passport.cnblogs.com/login.aspx";
    				List<KeyValuePair<String, String>> paramList = new List<KeyValuePair<String, String>>();
    				paramList.Add(new KeyValuePair<string, string>("__EVENTTARGET", ""));
    				paramList.Add(new KeyValuePair<string, string>("__EVENTARGUMENT", ""));
    				paramList.Add(new KeyValuePair<string, string>("__VIEWSTATE", __VIEWSTATE));
    				paramList.Add(new KeyValuePair<string, string>("__EVENTVALIDATION", __EVENTVALIDATION));
    				paramList.Add(new KeyValuePair<string, string>("tbUserName", username));
    				paramList.Add(new KeyValuePair<string, string>("tbPassword", password));
    				paramList.Add(new KeyValuePair<string, string>("LBD_VCID_c_login_logincaptcha", LBD_VCID_c_login_logincaptcha));
    				paramList.Add(new KeyValuePair<string, string>("LBD_BackWorkaround_c_login_logincaptcha", "1"));
    				paramList.Add(new KeyValuePair<string, string>("CaptchaCodeTextBox", imgCode));
    				paramList.Add(new KeyValuePair<string, string>("btnLogin", "登  录"));
    				paramList.Add(new KeyValuePair<string, string>("txtReturnUrl", "http://home.cnblogs.com/"));
    				response = httpClient.PostAsync(new Uri(url), new FormUrlEncodedContent(paramList)).Result;
    				result = response.Content.ReadAsStringAsync().Result;
    				Write("myCnblogs.html",result);
    			} while (result.Contains("验证码错误,麻烦您重新输入"));
    
    			Console.WriteLine("登录成功!");
    			
    			//用完要记得释放
    			httpClient.Dispose();
    		}
    
    		public static void Main()
    		{
    			  LoginCnblogs();
    		}
    
    }

    代码分析:

    首先,从Main函数开始,调用LoginCnblogs方法;

    其次,使用GET方法:

    HttpResponseMessage response = httpClient.GetAsync(new Uri(url)).Result;
     String result = response.Content.ReadAsStringAsync().Result;

    再者,使用POST方法:

      List<KeyValuePair<String, String>> paramList = new List<KeyValuePair<String, String>>();
                    paramList.Add(new KeyValuePair<string, string>("__EVENTTARGET", ""));
      ....
                    response = httpClient.PostAsync(new Uri(url), new FormUrlEncodedContent(paramList)).Result;
                    result = response.Content.ReadAsStringAsync().Result;

    最后, 注意其返回值可以是string,也可以是byte[],和stream的方式,这里看你需要什么吧。

    4.登录成功后的截图

    1).使用浏览器登录后的截图:

    2).使用Httpcliet登录后的截图:

    总结,可以发现C#中HttpClient的用法和Java中非常相似。

    (由于源网站布局不好看,所以转过来)转自http://www.tuicool.com/articles/rmiqYz

  • 相关阅读:
    css之布局
    css之浮动
    白扯之聊聊我们的情怀
    Vue之指令
    Vue之vue.js声明式渲染
    AJAX经常遇到的那些问题
    HTTP之cookie技术
    正则表达式资料
    require.js资料
    AMD 和 CMD 的区别
  • 原文地址:https://www.cnblogs.com/liuxinqi/p/6223106.html
Copyright © 2020-2023  润新知