• 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语言用了……试着抽象

  • 相关阅读:
    Python 函数装饰器简明教程
    *arg和**kwarg的区别
    克里金插值
    C语言Hello world
    ibatis错误
    typealias
    视图
    权限分级设置
    走出浮躁的泥沼:学会享受学习过程的乐趣
    R语言 eval(quote(x)) 和 eval(x)
  • 原文地址:https://www.cnblogs.com/scgw/p/2418161.html
Copyright © 2020-2023  润新知