C#的Http幫助類:HttpHelper
using System; using System.Collections.Generic; using System.Collections.Specialized; using System.IO; using System.IO.Compression; using System.Linq; using System.Net; using System.Net.Security; using System.Security.Cryptography.X509Certificates; using System.Text; using System.Text.RegularExpressions; using System.Collections; using HtmlAgilityPack;namespace XXX.Common.Helper { public class HttpHelper { public const string CharsetReg = @"(meta.?charset=""?(?<Charset>[^\s""'>]+)""?)|(xml.?encoding=""?(?<Charset>[^\s"">]+)""?)";
/// <summary> /// 獲取網頁的內容 /// </summary> /// <param name="url">Url</param> /// <param name="postData">Post的信息</param> /// <param name="cookies">Cookies</param> /// <param name="userAgent">瀏覽器標識</param> /// <param name="referer">來源頁</param> /// <param name="cookiesDomain">Cookies的Domian參數,配合cookies使用;為空則取url的Host</param> /// <param name="encode">編碼方式,用于解析html</param> /// <returns></returns> public static string GetHttpContent(string url, string postData = null, CookieContainer cookies = null, string userAgent = "", string referer = "", string cookiesDomain = "", Encoding encode = null) { try { HttpWebResponse httpResponse = null; if (!string.IsNullOrWhiteSpace(postData)) httpResponse = CreatePostHttpResponse(url, postData, cookies: cookies, userAgent: userAgent, referer: referer); else httpResponse = CreateGetHttpResponse(url, cookies: cookies, userAgent: userAgent, referer: referer); #region 根據Html頭判斷 string Content = null; //緩沖區長度 const int N_CacheLength = 10000; //頭部預讀取緩沖區,字節形式 var bytes = new List<byte>(); int count = 0; //頭部預讀取緩沖區,字符串 String cache = string.Empty; //創建流對象并解碼 Stream ResponseStream; switch (httpResponse.ContentEncoding.ToUpperInvariant()) { case "GZIP": ResponseStream = new GZipStream( httpResponse.GetResponseStream(), CompressionMode.Decompress); break; case "DEFLATE": ResponseStream = new DeflateStream( httpResponse.GetResponseStream(), CompressionMode.Decompress); break; default: ResponseStream = httpResponse.GetResponseStream(); break; } try { while ( !(cache.EndsWith("</head>", StringComparison.OrdinalIgnoreCase) || count >= N_CacheLength)) { var b = (byte)ResponseStream.ReadByte(); if (b < 0) //end of stream { break; } bytes.Add(b); count++; cache += (char)b; } if (encode == null) { try { if (httpResponse.CharacterSet == "ISO-8859-1" || httpResponse.CharacterSet == "zh-cn") { Match match = Regex.Match(cache, CharsetReg, RegexOptions.IgnoreCase | RegexOptions.Multiline); if (match.Success) { try { string charset = match.Groups["Charset"].Value; encode = Encoding.GetEncoding(charset); } catch { } } else encode = Encoding.GetEncoding("GB2312"); } else encode = Encoding.GetEncoding(httpResponse.CharacterSet); } catch { } } //緩沖字節重新編碼,然后再把流讀完 var Reader = new StreamReader(ResponseStream, encode); Content = encode.GetString(bytes.ToArray(), 0, count) + Reader.ReadToEnd(); Reader.Close(); } catch (Exception ex) { return ex.ToString(); } finally { httpResponse.Close(); } #endregion 根據Html頭判斷 //獲取返回的Cookies,支持httponly if (string.IsNullOrWhiteSpace(cookiesDomain)) cookiesDomain = httpResponse.ResponseUri.Host; cookies = new CookieContainer(); CookieCollection httpHeaderCookies = SetCookie(httpResponse, cookiesDomain); cookies.Add(httpHeaderCookies ?? httpResponse.Cookies); return Content; } catch { return string.Empty; } } /// <summary> /// 創建GET方式的HTTP請求 /// </summary> /// <param name="url"></param> /// <param name="timeout"></param> /// <param name="userAgent"></param> /// <param name="cookies"></param> /// <param name="referer"></param> /// <returns></returns> public static HttpWebResponse CreateGetHttpResponse(string url, int timeout = 60000, string userAgent = "", CookieContainer cookies = null, string referer = "") { HttpWebRequest request = null; if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase)) { //對服務端證書進行有效性校驗(非第三方權威機構頒發的證書,如自己生成的,不進行驗證,這里返回true) ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult); request = WebRequest.Create(url) as HttpWebRequest; //request.ProtocolVersion = HttpVersion.Version10; //http版本,默認是1.1,這里設置為1.0 } else { request = WebRequest.Create(url) as HttpWebRequest; } request.Referer = referer; request.Method = "GET"; //設置代理UserAgent和超時 if (string.IsNullOrWhiteSpace(userAgent)) userAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36"; request.UserAgent = userAgent; request.Timeout = timeout; request.KeepAlive = true; request.AllowAutoRedirect = true; if (cookies == null) cookies = new CookieContainer(); request.CookieContainer = cookies; return request.GetResponse() as HttpWebResponse; } /// <summary> /// 創建POST方式的HTTP請求 /// </summary> /// <param name="url"></param> /// <param name="postData"></param> /// <param name="timeout"></param> /// <param name="userAgent"></param> /// <param name="cookies"></param> /// <param name="referer"></param> /// <returns></returns> public static HttpWebResponse CreatePostHttpResponse(string url, string postData, int timeout = 60000, string userAgent = "", CookieContainer cookies = null, string referer = "") { HttpWebRequest request = null; //如果是發送HTTPS請求 if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase)) { ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult); request = WebRequest.Create(url) as HttpWebRequest; //request.ProtocolVersion = HttpVersion.Version10; } else { request = WebRequest.Create(url) as HttpWebRequest; } request.Referer = referer; request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; //設置代理UserAgent和超時 if (string.IsNullOrWhiteSpace(userAgent)) request.UserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36"; else request.UserAgent = userAgent; request.Timeout = timeout; request.KeepAlive = true; request.AllowAutoRedirect = true; if (cookies == null) cookies = new CookieContainer(); request.CookieContainer = cookies; //發送POST數據 if (!string.IsNullOrWhiteSpace(postData)) { byte[] data = Encoding.UTF8.GetBytes(postData); request.ContentLength = data.Length; using (Stream stream = request.GetRequestStream()) { stream.Write(data, 0, data.Length); } } //string[] values = request.Headers.GetValues("Content-Type"); return request.GetResponse() as HttpWebResponse; } /// <summary> /// 驗證證書 /// </summary> /// <param name="sender"></param> /// <param name="certificate"></param> /// <param name="chain"></param> /// <param name="errors"></param> /// <returns>是否驗證通過</returns> private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) { if (errors == SslPolicyErrors.None) return true; return false; } /// <summary> /// 根據response中頭部的set-cookie對request中的cookie進行設置 /// </summary> /// <param name="setCookie">The set cookie.</param> /// <param name="defaultDomain">The default domain.</param> /// <returns></returns> private static CookieCollection SetCookie(HttpWebResponse response, string defaultDomain) { try { string[] setCookie = response.Headers.GetValues("Set-Cookie"); // there is bug in it,the datetime in "set-cookie" will be sepreated in two pieces. List<string> a = new List<string>(setCookie); for (int i = setCookie.Length - 1; i > 0; i--) { if (a[i].Substring(a[i].Length - 3) == "GMT") { a[i - 1] = a[i - 1] + ", " + a[i]; a.RemoveAt(i); i--; } } setCookie = a.ToArray<string>(); CookieCollection cookies = new CookieCollection(); foreach (string str in setCookie) { NameValueCollection hs = new NameValueCollection(); foreach (string i in str.Split(';')) { int index = i.IndexOf("="); if (index > 0) hs.Add(i.Substring(0, index).Trim(), i.Substring(index + 1).Trim()); else switch (i) { case "HttpOnly": hs.Add("HttpOnly", "True"); break; case "Secure": hs.Add("Secure", "True"); break; } } Cookie ck = new Cookie(); foreach (string Key in hs.AllKeys) { switch (Key.ToLower().Trim()) { case "path": ck.Path = hs[Key]; break; case "expires": ck.Expires = DateTime.Parse(hs[Key]); break; case "domain": ck.Domain = hs[Key]; break; case "httpOnly": ck.HttpOnly = true; break; case "secure": ck.Secure = true; break; default: ck.Name = Key; ck.Value = hs[Key]; break; } } if (ck.Domain == "") ck.Domain = defaultDomain; if (ck.Name != "") cookies.Add(ck); } return cookies; } catch { return null; } } /// <summary> /// 遍歷CookieContainer /// </summary> /// <param name="cookieContainer"></param> /// <returns>List of cookie</returns> public static Dictionary<string, string> GetAllCookies(CookieContainer cookieContainer) { Dictionary<string, string> cookies = new Dictionary<string, string>(); Hashtable table = (Hashtable)cookieContainer.GetType().InvokeMember("m_domainTable", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.GetField | System.Reflection.BindingFlags.Instance, null, cookieContainer, new object[] { }); foreach (string pathList in table.Keys) { StringBuilder _cookie = new StringBuilder(); SortedList cookieColList = (SortedList)table[pathList].GetType().InvokeMember("m_list", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.GetField | System.Reflection.BindingFlags.Instance, null, table[pathList], new object[] { }); foreach (CookieCollection colCookies in cookieColList.Values) foreach (Cookie c in colCookies) _cookie.Append(c.Name + "=" + c.Value + ";"); cookies.Add(pathList, _cookie.ToString().TrimEnd(';')); } return cookies; } /// <summary> /// convert cookies string to CookieContainer /// </summary> /// <param name="cookies"></param> /// <returns></returns> public static CookieContainer ConvertToCookieContainer(Dictionary<string, string> cookies) { CookieContainer cookieContainer = new CookieContainer(); foreach (var cookie in cookies) { string[] strEachCookParts = cookie.Value.Split(';'); int intEachCookPartsCount = strEachCookParts.Length; foreach (string strCNameAndCValue in strEachCookParts) { if (!string.IsNullOrEmpty(strCNameAndCValue)) { Cookie cookTemp = new Cookie(); int firstEqual = strCNameAndCValue.IndexOf("="); string firstName = strCNameAndCValue.Substring(0, firstEqual); string allValue = strCNameAndCValue.Substring(firstEqual + 1, strCNameAndCValue.Length - (firstEqual + 1)); cookTemp.Name = firstName; cookTemp.Value = allValue; cookTemp.Path = "/"; cookTemp.Domain = cookie.Key; cookieContainer.Add(cookTemp); } } } return cookieContainer; } public static string BuildPostData(string htmlContent) { HtmlDocument htmlDoc = new HtmlDocument(); htmlDoc.LoadHtml(htmlContent); //Get the form node collection. HtmlNode htmlNode = htmlDoc.DocumentNode.SelectSingleNode("//form"); HtmlNodeCollection htmlInputs = htmlNode.SelectNodes("//input"); StringBuilder postData = new StringBuilder(); foreach (HtmlNode input in htmlInputs) { if(input.Attributes["value"] != null) postData.Append(input.Attributes["name"].Value + "=" + input.Attributes["value"].Value + "&"); } return postData.ToString().TrimEnd('&'); } }
}</pre>
本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!