苏飞论坛

 找回密码
 马上注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

分布式系统框架(V2.0) 轻松承载百亿数据,千万流量!讨论专区 - 源码下载 - 官方教程

HttpHelper万能框架(V2.3-含.netcore) HttpHelper官方出品,无敌框架讨论区 - 源码下载 - 在线测试和代码生成

HttpHelper爬虫类(V2.0) 最牛的爬虫类,没有爬不到只有想不到 源码 - 代码生成器 - 讨论区 - 教程- 例子

查看: 559|回复: 2

[反馈建议] 返回的HttpResult的Cookie字符串不为空,CookieCollection却为空的解决办法

[复制链接]
发表于 2019-8-7 16:28:59 | 显示全部楼层 |阅读模式
今天遇到个问题,一个网站登录请求返回的HttpResult的Cookie字符串不为空,CookieCollection的Count却为0。返回的Cookie字符串是这样:

[SQL] 纯文本查看 复制代码
JSESSIONID=EB3A9A7D49A4AB4C44D7838821CC8D48; Secure; HttpOnly; Expires=07-08-2019 13:16:01,
_tf_sso_main_session_id=EB3A9A7D49A4AB4C44D7838821CC8D48; Domain=aaa.cn; Path=/; HttpOnly

返回了2个cookie,第一个cookie却没有Domain设置,经过测试后发现,HttpWebResponse response在解析cookie的时候,如果这个cookie没有设置Domian,就会引发异常,导致这个以后的所有cookie都不会被解析进response.cookies中,这是导致这个问题的原因。
知道了原因,处理办法就很简单了,如果发现Cookie字符串不为空,CookieCollection的Count为0的情况,就手动解析Cookie字符串,把没有Domian的cookie手动加上当前访问的Host,然后把Cookie加入手动创建CookieCollection中,代码如下:

HTTP访问处理:
[C#] 纯文本查看 复制代码
HttpResult ret = m_hb.GetHtml(itm);

            if (ret.Cookie.Split(',').Length > ret.CookieCollection.Count)
            {
                string host = ret.Header["Host"];
                if (null == host || host.Length == 0)
                {
                    Uri uri = new Uri(itm.URL);
                    host = uri.Host;
                }
                CookieCollection cookielist = BaseTool.StrCookieToCookieCollection(host, ret.Cookie);
                cookie.Add(cookielist);
            }
            else
            {
                cookie.Add(ret.CookieCollection);
            }


StrCookieToCookieCollection实现:
[C#] 纯文本查看 复制代码
public CookieCollection StrCookieToCookieCollection(string baseDomain, string cookiestr)
        {
            CookieCollection cc = new CookieCollection();


            string[] cookies = cookiestr.Split(',');


            foreach(string c in cookies)
            {
                Cookie cookie = new Cookie();
                string[] list = c.ToString().Split(new string[] { ",", ";" }, StringSplitOptions.RemoveEmptyEntries);
                foreach (string item in list)
                {
                    string itemcookie = item.ToLower().Trim().Replace("\r\n", string.Empty).Replace("\n", string.Empty);
                    //排除空字符串
                    if (string.IsNullOrWhiteSpace(itemcookie)) continue;
                    else if (!itemcookie.Contains("="))
                    {
                        if(itemcookie == "httponly")
                            cookie.HttpOnly = true;
                        else if(itemcookie == "secure")
                            cookie.Secure = true;
                    }
                    else if (itemcookie.Contains("path="))
                    {
                        cookie.Path = itemcookie.Replace("path=", string.Empty);
                    }
                    else if (itemcookie.Contains("expires="))
                    {
                        cookie.Expires = Convert.ToDateTime(itemcookie.Replace("expires=", string.Empty));
                    }
                    else if (itemcookie.Contains("domain="))
                    {
                        cookie.Domain = itemcookie.Replace("domain=", string.Empty);
                    }
                    else
                    {
                        string[] kv = item.ToString().Replace("\r\n", string.Empty).Replace("\n", string.Empty).Split(new string[] { "=" }, StringSplitOptions.RemoveEmptyEntries);
                        if (kv.Length == 2)
                        {
                            cookie.Name = kv[0].Trim();
                            cookie.Value = kv[1].Trim();
                        }
                    }
                }


                if (cookie.Domain.Length == 0)
                {
                    cookie.Domain = baseDomain;
                }


                cc.Add(cookie);
            }


            return cc;
        }

这么处理,就解决了没有Domian的Cookie不能被记录的问题。



 楼主| 发表于 2019-8-7 16:42:38 | 显示全部楼层
编辑不了了,上面的HTTP访问处理代码可以优化一下:
[C#] 纯文本查看 复制代码
HttpResult ret = m_hb.GetHtml(itm);

            if (ret.Cookie.Split(',').Length > ret.CookieCollection.Count)
            {
                string host = ret.Header["Host"];
                if (null == host || host.Length == 0)
                {
                    Uri uri = new Uri(itm.URL);
                    host = uri.Host;
                }
                CookieCollection cookielist = BaseTool.StrCookieToCookieCollection(host, ret.Cookie);
                cookie.Add(cookielist);
            }
            else
            {
                cookie.Add(ret.CookieCollection);
            }
发表于 2019-8-8 09:49:55 | 显示全部楼层
您需要登录后才可以回帖 登录 | 马上注册

本版积分规则

QQ|手机版|小黑屋|手机版|联系我们|关于我们|广告合作|苏飞论坛 ( 豫ICP备17001017号-1)

GMT+8, 2019-12-6 17:02

© 2017-2018

快速回复 返回顶部 返回列表