这是一个CookieContainer错误吗?

时间:2016-01-11 23:25:32

标签: c# cookiecontainer

我在做什么:
我正在开发一个“webscraper”(多线程),就是这样,哈哈。我需要在从页面中提取数据之前提交表单,所以布局是这样的:

  1. 获取对example.com/path/doc.jsp(我的数据)的请求。
  2. 检查doc源中是否存在确认表单。如果是,继续执行步骤3(我的数据不存在,需要先提交表单),否则返回(因为没有表单可以提交,我的数据在这里)。
  3. 请求example.com/path/sub/other.jsp(必要的键值)。
  4. 对example.com/path/submit.jsp的POST请求(发送值)。
  5. 检查POST请求的响应,如果可以,请转到6,否则返回1.
  6. 再次请求example.com/path/doc.jsp(我的数据。自从我提交表单后,现在我的数据将会出现)。
  7. 除非POST请求(步骤4)的响应告诉我返回步骤1,否则一切正常。

    问题:
    我需要从cookie中提取它的形式中的一个值,所以我使用GetCookies()函数,但是,就像我说的,如果响应告诉我回到步骤1,所有请求(都是GET)之后缺少cookie(并添加了奇怪的cookie)。见下图:

    Cookie Error
    图片说明:

    • 第一个调用是对doc.jsp的GET请求,我的数据是。
    • 第二个调用是other.jsp请求,因为确认表单存在于doc.jsp源代码中。
    • 第三个电话是我提交所有值。
    • 第四次调用再次是对doc.jsp的GET请求,因为提交表单的响应(第三次调用)告诉我重复该过程。基本上,4º~6º的呼叫与1º~3º的呼叫相同,但是使用了cookie。


    我的代码:

    public class CWeb : IDisposable
    {
        private WebClientEx _wc;
        private string _originalUrl;
    
        public CWeb()
        {
            _wc = new WebClientEx(new CookieContainer());
        }
    
        public string downloadPage(string url)
        {
            _originalUrl = url;
            string pgSrc = "error";
            int tries = 0;
    
            while (tries < 3 && pgSrc == "error)
            {
                try
                {
                    pgSrc = _wc.DownloadString(url);
                }
                catch (Exception err)
                {
                    tries += 1;
                    pgSrc = "error";
                    ...
                }
            }
    
            if (needSubmit(pgSrc)) // needSubmit just peform IndexOf on pgSrc
                do
                {
                    pgSrc = sendForm(pgSrc);
                } while (needSubmit(pgSrc));
    
            return WebUtility.HtmlDecode(pgSrc);
        }
    
        public string sendForm(pageSource)
        {
            // 1- Get Cookie Value
            string cookie = _wc.CookieContainer.GetCookies(new Uri(_originalUrl))["JSESSIONID"].Value;
    
            // 2- Get hidden values in pageSource parameter
            // skip this, since there's no web request here, only some html parsing
            // with Html Agility Pack
            ...
    
            // 3- Get key value
            string tmpStr = _wc.DownloadString("http://example.com/path/sub/other.jsp");
            ... more html parsing ...
    
            // 4- Build form
            NameValueCollection nvc = new NameValueCollection();
            nvc["param1"] = cookie;
            nvc["param2"] = key;
            ...
    
            // 5- Send
            _wc.UploadValues("example.com/path/submit.jsp", nvc);
    
            // 6- Return
            return _wc.DownloadString(_originalUrl);
        }
    
        public void Dispose()
        {
            _wc.Dispose();
        }
    }
    


    主程序:

    static void Main(string[] args)
    {
        // Load tons of 'doc' url list from database...
        List<string> urls = new List<string>();
        ...
    
        Parallel.ForEach(urls, (url) =>
            {
                using (CWeb crawler = new CWeb())
                {
                    string pageData = crawler.downloadPage(url);
                    ... parse html data here ...
                }
            });
    }
    


    我的环境:

    • 使用Visual Studio Professional 2013。
    • 目标框架是.NET Framework 4.5。
    • 平台x86(调试)。
    • WebClientEx是WebClient的扩展版本,用于处理cookie。在此处PasteBin。我尝试实施BugFix_CookieDomain()(来自this question),但即使使用该修复程序,仍会出现此问题。
    • 我的所有网址都包含http://前缀。

    • 使用Fiddler查看请求信息。

    • 英语不是我的母语......' - '

1 个答案:

答案 0 :(得分:0)

我使用System.Net.WebRequest来做类似于你正在做的事情。它通过名为CookieContainer的属性使用Http(WebRequest的HttpWebRequest子类)时处理cookie。我注意到cookie被添加并且显然也从cookie容器中删除了。我的信念是,这完全由服务器端(您正在请求的Web应用程序)控制。它能够添加额外的cookie。

此外,如果Cookie具有过期日期,丢弃标志和域名,那么如果过期日期过去,服务器会设置丢弃标志,或者域名更改适用的Cookie列表可能会更改。

不确定这是否有用,但我尝试了。