WPF带cookie get/post请求网页,下载文件,图片,可保持会话状态

Posted romanticcrystal

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WPF带cookie get/post请求网页,下载文件,图片,可保持会话状态相关的知识,希望对你有一定的参考价值。

直接写成啦一个MyNet.cs类方便使用

get/post方法请求

//get请求
MyNet.SendRequest("http://www.baidu.com");
//post请求 
var param = new Dictionary<string, string>
    {
        {"a","this is a param" },
        {"b","this second param"}
    };
 MyNet.SendRequest("http://www.baidu.com",param);
//后面有参数自动转为post,没有参数默认为get

设置请求头

var headers = new Dictionary<string, string>() {
    {"UserAgent","Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/60.0.3112.90 Safari/537.36" }
};
MyNet.SendRequest("http://www.baidu.com",param,headers);

带cookie请求

如果需要带cookies请求的话就在发送请求之前添加cookie(可以直接从浏览器中复制出来放进去)

 MyNet.m_cookie = MyNet.FormatCookies("thw=us; miid=417871058341351592; ali_ab=123.160.175.149.1488949082923.4; x=e%3D1%26p%3D*%26s%3D0%26c%3D0%26f%3D0%26g%3D0%26t%3D0; v=0;", ".taobao.com");
 String str = MyNet.SendRequest("https://myseller.taobao.com/seller_admin.htm");

保持会话状态(保持cookie不丢失)

在请求之前设置如下

MyNet.m_sessionStatus=true;//默认为false不保持会话

下载文件

最后一个参数为下载的进度条显示,如果不需要可以不填写

<ProgressBar Name="jindu" Width="200"></ProgressBar>
MyNet.DownloadFile("http://sw.bos.baidu.com/sw-search-sp/software/1c5131aea1842/ChromeStandalone_56.0.2924.87_Setup.exe", "d:/a.exe",jindu);

下面是类文件直接复制保存为MyNet.cs即可

using System;
using System.Net;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Controls;
using System.Security.Permissions;
using System.Windows.Threading;
using System.Collections.Generic;
using System.Web;
namespace Ank.Class
{
    class MyNet
    {
        //是否保持会话状态
        public static bool m_sessionStatus = false;
        //请求时要带上的cookie
        public static CookieCollection m_cookie = null;
        //代理服务器信息格式为:  [主机:端口,用户名,密码];
        public static string[] m_proxy = null;
        private static Log m_log = Log.getInstance();
        public delegate void ProgressBarSetter(double value);
        /**
         * 添加cookie字符串
         * s cookie字符串
         * defaultDomain cookie域
         * */
        public static CookieCollection FormatCookies(string s, string defaultDomain)
        {
            s = s.Replace(",", "%2C");
            CookieCollection cc = new CookieCollection();
            if (string.IsNullOrEmpty(s) || s.Length < 5 || s.IndexOf("=") < 0) return cc;
            if (string.IsNullOrEmpty(defaultDomain) || defaultDomain.Length < 5) return cc;
            s.TrimEnd(new char[] { ; }).Trim();
            //Uri urI = new Uri(defaultDomain);
            //defaultDomain = urI.Host.ToString();
            //用软件截取的cookie会带有expires,要把它替换掉
            if (s.IndexOf("expires=") >= 0)
            {
                s = Replace(s, @"expires=[ws,-:]*GMT[;]?", "");
            }
            //只有一个cookie直接添加
            if (s.IndexOf(";") < 0)
            {
                System.Net.Cookie c = new System.Net.Cookie(s.Substring(0, s.IndexOf("=")), s.Substring(s.IndexOf("=") + 1));
                c.Domain = defaultDomain;
                cc.Add(c);
                return cc;
            }
            //不同站点与不同路径一般是以英文道号分别
            if (s.IndexOf(",") > 0)
            {
                s.TrimEnd(new char[] { , }).Trim();
                foreach (string s2 in s.Split(,))
                {
                    cc = FormatCookies(s2, defaultDomain, cc);
                }
                return cc;
            }
            else //同站点与同路径,不同.Name与.Value
            {
                return FormatCookies(s, defaultDomain, cc);
            }
        }
        //添加到CookieCollection集合部分
        private static CookieCollection FormatCookies(string s, string defaultDomain, CookieCollection cc)
        {
            try
            {
                s.TrimEnd(new char[] { ; }).Trim();
                System.Collections.Hashtable hs = new System.Collections.Hashtable();
                foreach (string s2 in s.Split(;))
                {
                    string s3 = s2.Trim();
                    if (s3.IndexOf("=") > 0)
                    {
                        string[] s4 = s3.Split(=);
                        hs.Add(s4[0].Trim(), s4[1].Trim());
                    }
                }
                string defaultPath = "/";
                foreach (object Key in hs.Keys)
                {
                    if (Key.ToString().ToLower() == "path")
                    {
                        defaultPath = hs[Key].ToString();
                    }
                    else if (Key.ToString().ToLower() == "domain")
                    {
                        defaultDomain = hs[Key].ToString();
                    }
                }
                foreach (object Key in hs.Keys)
                {
                    if (!string.IsNullOrEmpty(Key.ToString()) && !string.IsNullOrEmpty(hs[Key].ToString()))
                    {
                        if (Key.ToString().ToLower() != "path" && Key.ToString().ToLower() != "domain")
                        {
                            Cookie c = new Cookie();
                            c.Name = Key.ToString();
                            c.Value = hs[Key].ToString();
                            c.Path = defaultPath;
                            c.Domain = defaultDomain;
                            cc.Add(c);
                        }
                    }
                }
            }
            catch(Exception ex) {
                errorMsg(ex);
            }
            return cc;
        }
        private static string Replace(string strSource, string strRegex, string strReplace)
        {
            try
            {
                Regex r;
                r = new Regex(strRegex, RegexOptions.IgnoreCase | RegexOptions.Singleline);
                string s = r.Replace(strSource, strReplace);
                return s;
            }
            catch
            {
                return strSource;
            }
        }
        /**
         * 创建一个请求
         * */
        private static HttpWebRequest CreateRequest(string url = "", Dictionary<string, string> headers = null)
        {
            HttpWebRequest httpRequest;
            CookieContainer cookieCon = new CookieContainer();
            if (m_cookie != null && m_cookie.Count > 0)
            {
                cookieCon.Add(new Uri(url), m_cookie);
            }
            httpRequest = (HttpWebRequest)WebRequest.Create(url);
            httpRequest.Timeout = 60000;
            //添加代理访问
            if (m_proxy != null && m_proxy.Length > 1)
            {
                WebProxy proxy = new WebProxy();
                proxy.Address = new Uri(m_proxy[0]);
                if (m_proxy.Length == 3)
                {
                    proxy.Credentials = new NetworkCredential(m_proxy[1], m_proxy[2]);
                    httpRequest.UseDefaultCredentials = true;
                }
                httpRequest.Proxy = proxy;
            }
            //如果有请求头的话加上请求头
            if (headers != null)
            {
                WebHeaderCollection hds = new WebHeaderCollection();
                foreach (var item in headers.Keys)
                {
                    hds.Add(item, headers[item]);
                }
                httpRequest.Headers = hds;
            }
            //如果有cookie就加上cookie
            httpRequest.CookieContainer = cookieCon;
            return httpRequest;
        }
        /**
         * 从图片地址下载图片到本地磁盘
         * filePath 保存的路径
         * url图片地址
         **/
        public static bool DownImage( string url,string filePath, Dictionary<string, string> headers = null)
        {
            bool Value = false;
            WebResponse response = null;
            HttpWebRequest request = null;
            Stream stream = null;
            try
            {
                request = CreateRequest(url, headers);
                response = request.GetResponse();
                stream = response.GetResponseStream();
                if (!response.ContentType.ToLower().StartsWith("text/"))
                {
                    Value = SaveBinaryFile(response, filePath);
                }
            }
            catch (Exception ex)
            {
                errorMsg(ex);
            }
            return Value;
        }
        /**
         * 将二进制文件保存到磁盘
         * response 响应数据
         * filePath 保存的文件路径
         **/
        private static bool SaveBinaryFile(WebResponse response, string filePath)
        {
            bool Value = true;
            byte[] buffer = new byte[1024];
            try
            {
                if (File.Exists(filePath))
                    File.Delete(filePath);
                Stream outStream = System.IO.File.Create(filePath);
                Stream inStream = response.GetResponseStream();
                int l;
                do
                {
                    l = inStream.Read(buffer, 0, buffer.Length);
                    if (l > 0)
                        outStream.Write(buffer, 0, l);
                }
                while (l > 0);
                outStream.Close();
                inStream.Close();
            }
            catch (Exception ex)
            {
                errorMsg(ex);
                Value = false;
            }
            return Value;
        }
        /**
         * 下载文件到本地
         * url 文件url地址,这里的路径要用双斜杠
         * filePath 本地保存文件路径
         * bar进度条
         **/
        public static void DownloadFile(string url, string filePath, ProgressBar bar = null, Dictionary<string, string> headers = null)
        {
            try
            {
                //去操作ui线程元素
                bar.Dispatcher.BeginInvoke(new Action(() =>
                {
                    if (bar != null)
                    {
                        bar.Value = bar.Minimum;
                    }
                }));
                HttpWebRequest req = CreateRequest(url, headers);
                HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
                long totalBytes = resp.ContentLength;
                bar.Dispatcher.BeginInvoke(new Action(() =>
                {
                    if (bar != null)
                    {
                        bar.Maximum = (int)totalBytes;
                    }
                }));
                using (Stream sResp = resp.GetResponseStream())
                {
                    filePath = filePath.Replace("\", "/");
                    if (!Directory.Exists(filePath.Substring(0, filePath.LastIndexOf(/))))
                    {
                        Directory.CreateDirectory(filePath.Substring(0, filePath.LastIndexOf(/)));
                    }
                    using (Stream sFile = new FileStream(filePath, FileMode.Create))
                    {
                        long totalDownloadBytes = 0;
                        byte[] bs = new byte[1024];
                        int size = sResp.Read(bs, 0, bs.Length);
                        while (size > 0)
                        {
                            totalDownloadBytes += size;
                            DispatcherHelper.DoEvents();
                            sFile.Write(bs, 0, size);
                            bar.Dispatcher.BeginInvoke(new Action(() =>
                            {
                                if (bar != null)
                                {
                                    bar.Value = (int)totalDownloadBytes;
                                }
                            }));
                            Console.WriteLine((int)totalDownloadBytes);
                            size = sResp.Read(bs, 0, bs.Length);
                        }
                    }
                }
                bar.Dispatcher.BeginInvoke(new Action(() =>
                {
                    if (bar != null)
                    {
                        bar.Value = bar.Maximum;
                    }
                }));
            }
            catch (Exception ex)
            {
                errorMsg(ex);
            }
        }
        public static string http_build_query(Dictionary<string, string> dict = null)
        {
            if (dict == null)
            {
                return "";
            }
            var builder = new UriBuilder();
            var query = HttpUtility.ParseQueryString(builder.Query);
            foreach (var item in dict.Keys)
            {
                query[item] = dict[item];
            }
            return query.ToString().Trim(?).Replace("+", "%20");
        }
        #region //post数据
        /**
         * 发送请求,如果有postdata自动转换为post请求
         * */
        public static string SendRequest(string url, Dictionary<string, string> postData = null, Dictionary<string, string> headers = null, string encode = "utf-8")
        {
            string rehtml = "";
            HttpWebRequest httpRequest = null;
            WebResponse response = null;
            try
            {
                Encoding encoding = Encoding.GetEncoding(encode);
                httpRequest = CreateRequest(url, headers);
                //如果有请求数据就改成post请求
                if (postData != null && postData.Count != 0)
                {
                    var parstr = http_build_query(postData);
                    byte[] bytesToPost = encoding.GetBytes(parstr);
                    httpRequest.ContentType = "application/x-www-form-urlencoded";
                    httpRequest.Method = "POST";
                    httpRequest.ContentLength = bytesToPost.Length;
                    Stream requestStream = httpRequest.GetRequestStream();
                    requestStream.Write(bytesToPost, 0, bytesToPost.Length);
                    requestStream.Close();
                }
                else
                {
                    httpRequest.Method = "GET";
                }
                response = httpRequest.GetResponse();
                //从响应头自动判断网页编码
                //Content - Type:text / html; charset = utf - 8
                string contentType = response.Headers["Content-Type"];
                //Encoding encoding = null;
                Regex regex = new Regex("charset\s*=\s*(\S+)", RegexOptions.IgnoreCase);
                Match match = null;
                if (contentType != null)
                {
                    match = regex.Match(contentType);
                    //在响应头中找到编码声明
                    if (match.Success)
                    {
                        //找到页面里的编码声明,就按编码转换
                        try
                        {
                            encoding = Encoding.GetEncoding(match.Groups[1].Value.Trim());
                            using (TextReader reader = new StreamReader(response.GetResponseStream(), encoding))
                            {
                                rehtml = reader.ReadToEnd();
                            }
                        }
                        catch (Exception ex)
                        {
                            errorMsg(ex);
                            rehtml = "";
                        }
                    }
                }
                //响应头类型为空或没有找到编码声明的情况,直接从响应内容中找编码声明
                using (TextReader reader = new StreamReader(response.GetResponseStream(), Encoding.Default))
                {
                    rehtml = reader.ReadToEnd();
                    regex = new Regex("<\s*meta.+charset\s*=\s*(\S+)\s*"", RegexOptions.IgnoreCase);
                    match = regex.Match(rehtml);
                    //找到编码声明就转码,找不到拉倒,不管啦
                    if (match.Success)
                    {
                        try
                        {
                            encoding = Encoding.GetEncoding(match.Groups[1].Value.Trim());
                            rehtml = encoding.GetString(Encoding.Default.GetBytes(rehtml));
                            // Console.WriteLine(str);
                        }
                        catch (Exception ex)
                        {
                            errorMsg(ex);
                            //转码出错,原样返回,不管它是啥东西,不处理啦
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                errorMsg(ex);
                rehtml = "";
            }
            if (m_sessionStatus)
            {
                m_cookie = httpRequest.CookieContainer.GetCookies(new Uri(url));
            }
            else
            {
                m_cookie = null;
            }
            httpRequest = null;
            if (response != null)
            {
                response.Dispose();
                response = null;
            }
            return rehtml;
            #endregion
        }
        private static void errorMsg(Exception ex = null)
        {
            if (ex != null)
            {
                Console.WriteLine(ex.Message);
                m_log.write(ex.Message, "litedb");
                m_log.write(ex.ToString(), "litedb");
            }
        }
        public static class DispatcherHelper
        {
            [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
            public static void DoEvents()
            {
                DispatcherFrame frame = new DispatcherFrame();
                Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, new DispatcherOperationCallback(ExitFrames), frame);
                try { Dispatcher.PushFrame(frame); }
                catch (InvalidOperationException) { }
            }
            private static object ExitFrames(object frame)
            {
                ((DispatcherFrame)frame).Continue = false;
                return null;
            }
        }
    }
}

 

以上是关于WPF带cookie get/post请求网页,下载文件,图片,可保持会话状态的主要内容,如果未能解决你的问题,请参考以下文章

Linux curl 命令模拟 POST/GET 请求

request请求的get/post的模块的封装

对GET/POST请求返回cookie中的键值对进行重新组合

爬虫学习——带cookie的网页进行爬取

Linux curl 命令模拟 POST/GET 请求

vue get/post请求如何携带cookie的问题