• C# 中使用System.Net.Http.HttpClient 模拟登录博客园 (GET/POST)


    以下内容仅供学习交流使用,请勿做他用,否则后果自负。

     

    一、 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中非常相似,所以,说其抄袭确实不为过。

       

  • 相关阅读:
    Django基础命令
    ubuntu中python项目独立的虚拟环境
    Springboot项目的小问题
    redis
    ubuntu系统根目录下各个目录用途说明
    SpringBoot 在IDEA中实现热部署
    SpringBoot访问不到webapp下的内容
    httpServeltRequest和Model传值的区别
    map的输出
    主流框架排名
  • 原文地址:https://www.cnblogs.com/amosli/p/3918538.html
Copyright © 2020-2023  润新知