C# Http请求模拟登录

 工作原理
1.通过chrome或firefox等工具的NetWork面板,跟踪到请求过程中传递的 Request Headers
2.将Request Headers 附加到请求,DoRequest的headers参数
3.通过chrome或firefox等工具的NetWork面板,跟踪到请求过程中传递的 Form Data
4.将Form Data 附加到请求中,DoRequest的content参数
5.请求成功后,将HttpResponseHeader.SetCookie记录到CookieDic集合。
6.下次请求时,附加上第3步的CookieDic集合,即可模拟登录后操作。 

封装代码

using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;

namespace RC.Software.Travel
{
    /// <summary>
    /// Http请求封装类,用于模拟登录等操作
    /// 工作原理:
    /// 1.通过chrome的NetWork面板,跟踪到请求过程中传递的 Request Headers
    /// 2.将Request Headers 附加到请求。
    /// 3.请求成功后,将HttpResponseHeader.SetCookie记录下来。
    /// 4.下次请求时,附加上第3步的cookie,即可模拟登录后操作。 
    /// </summary>
    public class HttpRequestHelper
    {
        /// <summary>
        ///     cookie集合,用于模拟登陆
        /// </summary>
        private static readonly Dictionary<string, Cookie> CookieDic = new Dictionary<string, Cookie>();

        /// <summary>
        ///     Http请求
        /// </summary>
        /// <param name="url"></param>
        /// <param name="method"></param>
        /// <param name="headers"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        public static string DoRequest(string url, string method, string headers, string content)
        {
            var request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = method;
            if (method.Equals("GET", StringComparison.InvariantCultureIgnoreCase))
            {
                request.MaximumAutomaticRedirections = 100;
                request.AllowAutoRedirect = false;
            }

            #region 1.设置Http头部

            if (!string.IsNullOrWhiteSpace(headers))
            {
                var hsplit = headers.Split(new[] { "\n" }, StringSplitOptions.RemoveEmptyEntries);
                foreach (var item in hsplit)
                    if (!item.StartsWith(":"))
                    {
                        var kv = item.Split(':');
                        if (kv.Length == 2)
                        {
                            var key = kv[0].Trim();
                            var value = string.Join(":", kv.Skip(1)).Trim();

                            #region  设置http头

                            switch (key.ToLower())
                            {
                                case "accept":
                                    {
                                        request.Accept = value;
                                        break;
                                    }
                                case "host":
                                    {
                                        request.Host = value;
                                        break;
                                    }
                                case "connection":
                                    {
                                        if (value == "keep-alive")
                                            request.KeepAlive = true;
                                        else
                                            request.KeepAlive = false; //just test
                                        break;
                                    }
                                case "content-type":
                                    {
                                        request.ContentType = value;
                                        break;
                                    }

                                case "user-agent":
                                    {
                                        request.UserAgent = value;
                                        break;
                                    }
                                case "referer":
                                    {
                                        request.Referer = value;
                                        break;
                                    }
                                case "content-length":
                                    {
                                        request.ContentLength = Convert.ToInt64(value);
                                        break;
                                    }
                                case "expect":
                                    {
                                        request.Expect = value;
                                        break;
                                    }
                                case "if-modified-since":
                                    {
                                        request.IfModifiedSince = Convert.ToDateTime(value);
                                        break;
                                    }
                                case "cookie":
                                    {
                                        var cc = new CookieCollection();
                                        var cookieString = value;
                                        if (!string.IsNullOrWhiteSpace(cookieString))
                                        {
                                            var spilit = cookieString.Split(';');
                                            foreach (var ci in spilit)
                                            {
                                                var arr = ci.Split('=');
                                                if (kv.Length == 2)
                                                    cc.Add(new Cookie(arr[0].Trim(), arr[1].Trim()));
                                            }
                                        }
                                    }
                                    break;
                            }

                            #endregion
                        }
                    }
            }

            #endregion

            #region 2.设置cookie

            request.Headers[HttpRequestHeader.Cookie] = GetCookieStr();

            #endregion

            #region 3.发送请求数据

            if (!string.IsNullOrWhiteSpace(content))
            {
                var data = Encoding.UTF8.GetBytes(content);
                request.ContentLength = data.Length;
                using (var stream = request.GetRequestStream())
                {
                    stream.Write(data, 0, data.Length);
                    stream.Close();
                }
            }

            #endregion

            var response = (HttpWebResponse)request.GetResponse();

            #region 4.保存cookie,用于下次请求

            var cookies = new CookieCollection();
            var s = response.Headers[HttpResponseHeader.SetCookie].Replace("HttpOnly,", "").Replace("httponly,", "");
            if (!string.IsNullOrWhiteSpace(s))
            {
                var spilit = s.Split(';');
                foreach (var item in spilit)
                {
                    var kv = item.Split('=');
                    if (kv.Length == 2)
                        cookies.Add(new Cookie(kv[0].Trim(), kv[1].Trim()));
                }
            }

            foreach (Cookie c in cookies)
                if (CookieDic.ContainsKey(c.Name))
                    CookieDic[c.Name] = c;
                else
                    CookieDic.Add(c.Name, c);

            #endregion

            var result = GetResponse(response);
            return Unicode2String(result);
        }

        /// <summary>
        ///     将Unicode转换为中文
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static string Unicode2String(string source)
        {
            return new Regex(@"\\u([0-9A-F]{4})", RegexOptions.IgnoreCase).Replace(
                source, x => string.Empty + Convert.ToChar(Convert.ToUInt16(x.Result("$1"), 16)));
        }

        /// <summary>
        ///     从HttpWebResponse读取响应文本
        /// </summary>
        /// <param name="response"></param>
        /// <returns></returns>
        private static string GetResponse(HttpWebResponse response)
        {
            var defaultEncode = Encoding.UTF8;
            var contentType = response.ContentType;
            if (contentType.ToLower().Contains("gb2312"))
                defaultEncode = Encoding.GetEncoding("gb2312");
            else if (contentType.ToLower().Contains("gbk"))
                defaultEncode = Encoding.GetEncoding("gbk");
            else if (contentType.ToLower().Contains("zh-cn")) defaultEncode = Encoding.GetEncoding("zh-cn");

            string responseBody;
            if (response.ContentEncoding.ToLower().Contains("gzip"))
                using (var stream = new GZipStream(response.GetResponseStream(), CompressionMode.Decompress))
                {
                    using (var reader = new StreamReader(stream))
                    {
                        responseBody = reader.ReadToEnd();
                    }
                }
            else if (response.ContentEncoding.ToLower().Contains("deflate"))
                using (var stream = new DeflateStream(response.GetResponseStream(), CompressionMode.Decompress))
                {
                    using (var reader = new StreamReader(stream, defaultEncode))
                    {
                        responseBody = reader.ReadToEnd();
                    }
                }
            else
                using (var stream = response.GetResponseStream())
                {
                    using (var reader = new StreamReader(stream, defaultEncode))
                    {
                        responseBody = reader.ReadToEnd();
                    }
                }

            return responseBody;
        }

        private static string GetCookieStr()
        {
            var sb = new StringBuilder();
            foreach (var item in CookieDic)
                if (!item.Value.Expired)
                {
                    if (sb.Length == 0)
                        sb.Append(item.Key).Append("=").Append(item.Value.Value);
                    else
                        sb.Append("; ").Append(item.Key).Append(" = ").Append(item.Value.Value);
                }

            return sb.ToString();
        }
    }
}

调用示例代码:

var userName = txtUserName.Text.Trim();
var pwd = txtPwd.Text.Trim();
var res = HttpRequestHelper.DoRequest(_loginUrl, "Post", txtHeaders.Text.Trim(), "passport=" + userName + "&password=" + pwd);
 txtResult.Text = res;

发布了438 篇原创文章 · 获赞 229 · 访问量 304万+

猜你喜欢

转载自blog.csdn.net/a497785609/article/details/88526220
今日推荐