欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C# Http请求模拟登录

程序员文章站 2022-05-07 12:08:54
...

 工作原理
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;