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中非常相似,所以,說其抄襲確實不為過。

   


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM