HttpClient 應用案例揭破應用Discuss論壇登錄
阿新 • • 發佈:2019-05-17
style get 實現 esp bytearray sum web readonly mem
閑來無事,寫了一個對discuss論壇登錄的案例,初次上場按照以前的慣例沒成功,見過抓包分析discuss論壇成功完成,廢話不多說 直接上代碼。
1:winform 做客戶端,添加HttpClient的引用
初始化對象:
private const string BaseUrl = "替換為論壇地址"; private const string useAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36"; private readonly HttpClient httpClient; private readonly HttpClientHandler handler; private readonly string userName = "superadmin"; private readonly string passWord = "123456"; private readonly HtmlDocument htmlDoc; private BaiDuToken baiDuToken;public Form1() { InitializeComponent(); handler = new HttpClientHandler() { UseCookies = true, AllowAutoRedirect = true }; httpClient = new HttpClient(handler) { BaseAddress = new Uri(BaseUrl) }; httpClient.DefaultRequestHeaders.Add("user-agent", useAgent); httpClient.DefaultRequestHeaders.Add("Connection", "Keep-Alive"); httpClient.DefaultRequestHeaders.Add("Keep-Alive", "timeout=600"); httpClient.DefaultRequestHeaders.Add("Referer", $"{BaseUrl}member.php?mod=logging&action=login"); htmlDoc = new HtmlDocument(); }
2:具體方法
/// <summary> /// 獲取導航 /// </summary> /// <param name="fid"></param> /// <returns></returns> private string GetNav(int fid = 72) { return $"forum.php?mod=forumdisplay&fid={fid}"; } /// <summary> /// 百度ai token /// </summary> /// <returns></returns> private async Task<BaiDuToken> BaiDuTokenAsync() => await httpClient.GetAccessTokenAsync(); //百度ai 代碼 自我實現 /// <summary> /// 搜索字符 /// </summary> /// <param name="allStr"></param> /// <param name="firstStr"></param> /// <param name="lastStr"></param> /// <returns></returns> public string GetStringMid(string allStr, string firstStr, string lastStr) { int num = allStr.IndexOf(firstStr); int num2 = allStr.IndexOf(lastStr, num + firstStr.Length); if (num < 0 || num2 < 0) { return ""; } num += firstStr.Length; num2 -= num; if (num < 0 || num2 < 0) { return ""; } return allStr.Substring(num, num2); } /// <summary> /// 搜索字符 /// </summary> /// <param name="allStr"></param> /// <param name="firstStr"></param> /// <param name="lastStr"></param> /// <param name="regexCode"></param> /// <returns></returns> public List<string> GetStringMids(string allStr, string firstStr, string lastStr, string regexCode = "(.*?)") { List<string> list = new List<string>(); string pattern = $"{firstStr}{regexCode}{lastStr}"; Regex regex = new Regex(pattern); MatchCollection matchCollection = regex.Matches(allStr); for (int i = 0; i < matchCollection.Count; i++) { GroupCollection groups = matchCollection[i].Groups; for (int j = 1; j < groups.Count; j++) { string value = groups[j].Value; if (!string.IsNullOrEmpty(value)) { list.Add(value); } } } return list; } /// <summary> /// 響應html為字符串 /// </summary> /// <param name="url"></param> /// <returns></returns> private async Task<string> GetResponseStrAsync(string url) { return await (await GetResponseAsync(url))?.ReadAsStringAsync(); } /// <summary> /// 響應 /// </summary> /// <param name="url"></param> /// <returns></returns> private async Task<HttpContent> GetResponseAsync(string url) { HttpResponseMessage response = await httpClient.GetAsync(url); if (!response.IsSuccessStatusCode) { return null; } return response.Content;//具體結果 } private string seccode, loginhash, formhash; /// <summary> /// 獲取登錄相關參數 /// </summary> /// <returns></returns> private async Task GetformAsync() //獲取登錄相關參數 { string url = "member.php?mod=logging&action=login"; string html = await GetResponseStrAsync(url); seccode = GetStringMid(html, "seccode_", "\""); loginhash = GetStringMid(html, "loginhash=", "\""); formhash = GetStringMid(html, "<input type=\"hidden\" name=\"formhash\" value=\"", "\""); } /// <summary> /// 獲取驗證碼地址 /// </summary> /// <returns></returns> private async Task<string> GetupdateAsync()//獲取驗證碼地址 { string url = $"misc.php?mod=seccode&action=update&idhash={seccode}";//請求地址 string res = await GetResponseStrAsync(url); return GetStringMid(res, "width=\"100\" height=\"30\" src=\"", "\""); } private async void PictureBox1_Click(object sender, EventArgs e) { await GetImageAsync(); } private async void Form1_Load(object sender, EventArgs e) { await GetformAsync(); await GetImageAsync(); baiDuToken = await BaiDuTokenAsync(); } /// <summary> /// 獲取驗證碼圖片 /// </summary> /// <param name="update"></param> /// <returns></returns> private async Task<byte[]> GetImageAsync() { string update = await GetupdateAsync(); byte[] bytes = await httpClient.GetByteArrayAsync(update); return bytes; } /// <summary> /// 登錄 /// </summary> /// <returns></returns> private async Task<bool> GetLoginAsync() { byte[] bytes = await GetImageAsync(); ImagToWords imagToWords = BaiDuAccessToken.RecogniseImage(bytes, baiDuToken);//利用百度 ai識別驗證碼 string code = string.Join("", imagToWords.Words_result.Select(s => s.Words)); string url = $"misc.php?mod=seccode&action=check&inajax=1&modid=member::logging&idhash={seccode}&secverify={code}";//請求地址 string html = await GetResponseStrAsync(url); if (html.Contains("succeed")) { url = $"member.php?mod=logging&action=login&loginsubmit=yes&loginhash{loginhash}&inajax=1";//請求地址 List<KeyValuePair<string, string>> paraList = new List<KeyValuePair<string, string>> { new KeyValuePair<string, string>("formhash", formhash), new KeyValuePair<string, string>("username", userName), new KeyValuePair<string, string>("password", passWord), new KeyValuePair<string, string>("seccodehash", seccode), new KeyValuePair<string, string>("seccodeverify", code), }; HttpResponseMessage response = await httpClient.PostAsync(url, new FormUrlEncodedContent(paraList)); html = await response.Content.ReadAsStringAsync(); return html.Contains("歡迎您回來"); } return false; }
HttpClient 應用案例揭破應用Discuss論壇登錄