C#保存CookieContainer到文件

爬数据的时候免不了需要登录。每次实验都要输入验证码是个麻烦的事情,于是就想像浏览器一样把cookies存到文件中,下次重新运行的时候可以直接使用。


Google 搜“C# CookieContainer 存文件”能找到最好的代码如下:
http://www.huxu.net.cn/2011_03/154.html

  1. public static List<Cookie> GetAllCookies(CookieContainer cc) {   
  2.     List<Cookie> lstCookies = new List<Cookie>();   
  3.     Hashtable table = (Hashtable)cc.GetType().InvokeMember("m_domainTable",   
  4.         System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.GetField |   
  5.         System.Reflection.BindingFlags.Instance, null, cc, new object[] { });   
  6.     foreach (object pathList in table.Values) {   
  7.         SortedList lstCookieCol = (SortedList)pathList.GetType().InvokeMember("m_list",   
  8.             System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.GetField   
  9.             | System.Reflection.BindingFlags.Instance, null, pathList, new object[] { });   
  10.         foreach (CookieCollection colCookies in lstCookieCol.Values)   
  11.             foreach (Cookie c in colCookies) lstCookies.Add(c);   
  12.     }   
  13.     return lstCookies;   
  14. }   
  15.   
  16. //存储   
  17. StringBuilder sbc = new StringBuilder();   
  18. List<Cookie> cooklist = Code.ProgTool.GetAllCookies(CookieContainer);   
  19. foreach (Cookie cookie in cooklist) {   
  20.     sbc.AppendFormat("{0};{1};{2};{3};{4};{5}\r\n",   
  21.         cookie.Domain, cookie.Name, cookie.Path, cookie.Port,   
  22.         cookie.Secure.ToString(), cookie.Value);   
  23. }   
  24. FileStream fs = File.Create("d:\\chinarencookies.txt");   
  25. fs.Close();   
  26. File.WriteAllText("d:\\chinarencookies.txt", sbc.ToString(), System.Text.Encoding.Default);   
  27.   
  28. //读取   
  29. string[] cookies = File.ReadAllText("d:\\chinarencookies.txt", System.Text.Encoding.Default)   
  30.     .Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);   
  31. foreach (string c in cookies) {   
  32.     string[] cc = c.Split(";".ToCharArray());   
  33.     Cookie ck = new Cookie(); ;   
  34.     ck.Discard = false;   
  35.     ck.Domain = cc[0];   
  36.     ck.Expired = true;   
  37.     ck.HttpOnly = true;   
  38.     ck.Name = cc[1];   
  39.     ck.Path = cc[2];   
  40.     ck.Port = cc[3];   
  41.     ck.Secure = bool.Parse(cc[4]);   
  42.     ck.Value = cc[5];   
  43.     CookieContainer.Add(ck);   
  44. }  

这种方法需要深入了解cookies的构成,作为模板用还可以接受。IE也用类似的方式存储cookies。
但这种写法非常容易出bug,其中的ck.Expired = true;就是一个隐患。

尝试着又搜了一下“C# save CookieContainer to file”,果然发现了一份更优雅的代码。
http://stackoverflow.com/questions/1777203/c-writing-a-cookiecontainer-to-disk-and-loading-back-in-for-use

  1. public static void WriteCookiesToDisk(string file, CookieContainer cookieJar)   
  2. {   
  3.     using(Stream stream = File.Create(file))   
  4.     {   
  5.         try {   
  6.             Console.Out.Write("Writing cookies to disk... ");   
  7.             BinaryFormatter formatter = new BinaryFormatter();   
  8.             formatter.Serialize(stream, cookieJar);   
  9.             Console.Out.WriteLine("Done.");   
  10.         } catch(Exception e) {   
  11.             Console.Out.WriteLine("Problem writing cookies to disk: " + e.GetType());   
  12.         }   
  13.     }   
  14. }      
  15.   
  16. public static CookieContainer ReadCookiesFromDisk(string file)   
  17. {   
  18.     try {   
  19.         using(Stream stream = File.Open(file, FileMode.Open))   
  20.         {   
  21.             Console.Out.Write("Reading cookies from disk... ");   
  22.             BinaryFormatter formatter = new BinaryFormatter();   
  23.             Console.Out.WriteLine("Done.");   
  24.             return (CookieContainer)formatter.Deserialize(stream);   
  25.         }   
  26.     } catch(Exception e) {   
  27.         Console.Out.WriteLine("Problem reading cookies from disk: " + e.GetType());   
  28.         return new CookieContainer();   
  29.     }   
  30. }  

这里用了C#自带的序列化功能,几行代码就完成了这一任务。把繁琐的事情全都交给库自动完成。

C#已经在最近(2012年2月)的编程语言排行榜中排名第三了。被强大的库函数吸引过来,现在也渐渐感觉到语言本身的优势了。不能再当C语言用了……试着抽象

原文地址:https://www.cnblogs.com/scgw/p/2418161.html