http://www.sufeinet.com/plugin.php?id=keke_group

苏飞论坛

 找回密码
 马上注册

QQ登录

只需一步,快速开始

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

HttpHelper爬虫框架(V2.7-含.netcore) HttpHelper官方出品,爬虫框架讨论区 - 源码下载 - 在线测试和代码生成

HttpHelper爬虫类(V2.0) 开源的爬虫类,支持多种模式和属性 源码 - 代码生成器 - 讨论区 - 教程- 例子

查看: 5456|回复: 8

[HttpHelper] 登陆成功后只成功获取数据一次就被拒

[复制链接]
发表于 2015-6-29 20:35:14 | 显示全部楼层 |阅读模式
1金钱
新人报到,多多关照!我试图用HttpHelper模拟登陆网站I V O L A T I L I T Y . C O M. 此站需要用户名和密码登陆,登陆后由/login.j转发到/home.j才能开始查询。我用chrome的开发工具截获其Http通讯的相关信息如下:

登录页header:
login.jpg

登录后转home的header:
home.jpg

查询页header:
query.jpg

退出页header:
logoff.jpg

该站允许一个用户实例同时登录,但在测试中,需要反复登陆,所以,我登录前先模拟退出。用于不知道如何检验用户是否已登录,我只好发送一个GET的请求来退出:
[C#] 纯文本查看 复制代码
            HttpHelper http = new HttpHelper();
            HttpItem item = null;
            string cookie = "";
            item = new HttpItem()
            {
    URL = "https://www.i v o l a t i l i t y.com/logoff.j?logoff=1&cookies_disabled=true",        
    Method = "get",                                                  
    Cookie = null,
    ICredentials = null,
            };

    HttpResult html = http.GetHtml(item);


接着登录:
[C#] 纯文本查看 复制代码
            item = new HttpItem()
            {
    URL = "https://www.i v o l a t i l i t y.com/login.j",       
    Encoding = null,                                   
    Method = "Post",                                   
    ContentType = "application/x-www-form-urlencoded", 
    Postdata = "username=ABCDE&password=123456789" +
                    "&login__is__sent=1&step=1",
    KeepAlive = true,
    Referer = "https://www.i v o l a t i l i t y.com/login.j",
            };

            html = http.GetHtml(item);
            if (html.Header["set-cookie"] != null)
    cookie = html.Header["set-cookie"];


开始查询:
[C#] 纯文本查看 复制代码
			string [] stocks = {"IBM", "AAPL"};
            
            if (html.StatusCode == System.Net.HttpStatusCode.OK)
            {
    Console.WriteLine("Logined");        
    string mysql = "insert into Options  ";

                foreach (string s in stocks)
                {
    url = "http://www.i v o l a t i l i t y.com/options.j?ticker={0}";
    string gourl = string.Format(url, s);

    item = new HttpItem()
    {
        URL = gourl,
        Method = "get",                                   
        Cookie = cookie,
                        
    };

    HttpResult res = http.GetHtml(item);
    // 判断是否被拒
    if (!res.Html.Contains("We are sorry")) 
         Console.WriteLine("Found the SORRY page\n");

    HtmlDocument doc = new HtmlDocument();
    doc.LoadHtml(res.Html);                    
    string sql = mysql;
    HtmlNodeCollection cells = doc.DocumentNode.SelectNodes("//font[@class='s2']");

    for (int k = 0; k < cells.Count; k++)
   {
        HtmlNode node = cells[k];
        if (node.InnerText.Contains("Index mean"))
        {

             sql += "(symbol, Current, OneWkAgo, OneMthAgo, YearHi, YearLo) values (" + s;
             sql += ", " +   (cells[k + 1].InnerText) + ", " +
                                (cells[k + 2].InnerText) + ", " +
                                (cells[k + 3].InnerText) + ", " +
                                (cells[k + 4].InnerText) + ", " +
                                (cells[k + 5].InnerText) + ")";

                      break;
       }
       k++;

    }                    
    Execute(sql);
    Console.WriteLine(sql);  
    Thread.Sleep(2000);
                    
  }
            }


大概就是这样,运行后发现,登录成功后第一次查询是没问题的,能拿到数据,但第二次用同样的cookie(即使是同样的股票代码),却被拒了。请飞哥和各位帮忙看看哪里出错了!












1. 开通SVIP会员,免费下载本站所有源码,不限次数据,不限时间
2. 加官方QQ群,加官方微信群获取更多资源和帮助
3. 找站长苏飞做网站、商城、CRM、小程序、App、爬虫相关、项目外包等点这里
发表于 2015-6-30 08:15:35 | 显示全部楼层
但第二次用同样的cookie……
Cookie是动态的,第二次请求后有没有产生Cookie?如有,附加进去再进行后续请求。
回复

使用道具 举报

发表于 2015-6-30 08:39:07 | 显示全部楼层
抓包不完整,发送Http请求,Cookie会更新,发送请求时,Refer参数也会影响。只看Cookie是不行的。
回复

使用道具 举报

 楼主| 发表于 2015-6-30 08:50:59 | 显示全部楼层
谢谢回复。我试过加新的cookie, 但还是不行。见图: output.png

注意,上述的cookie都来自Response。但为何第一次合法,第二次就不行了?肯定是缺了什么信息。

通过对比Request和Response的Header, 发现有些不同,如UKL, __utmb, JSESSIONID等几项出现在Request的header里而不在Response里,是不是应该将这些信息拿到,附加到原来的cookie上? 我是新手,不太了解该调用什么函数来取得上述信息?此外,还不太明白CoookieCollection和CookieContainer的用法,Request的header跟这些有关吗? 请点播和指教!
回复

使用道具 举报

 楼主| 发表于 2015-6-30 09:16:00 | 显示全部楼层
楼上的大哥说的对。但怎样每次才能抓到完整的包呢?
回复

使用道具 举报

发表于 2015-6-30 10:40:06 | 显示全部楼层
smufimmu 发表于 2015-6-30 09:16
楼上的大哥说的对。但怎样每次才能抓到完整的包呢?

换抓包工具,如httpwatch等。
回复

使用道具 举报

 楼主| 发表于 2015-7-1 01:49:03 | 显示全部楼层
我追问一句,假设抓包成功,请问该如何自动获取有关信息,有些消息不在响应的头或cookie里,怎么办?
回复

使用道具 举报

发表于 2015-7-2 23:46:28 | 显示全部楼层
我也遇到类似问题,非常关注,望高手解答
回复

使用道具 举报

 楼主| 发表于 2015-7-11 20:47:34 | 显示全部楼层
这个问题已解决,关键是在请求中使用CookieCollection而不是Cookie:
如:
先用get请求,拿到其响应中的CookieCollection并赋值于下一个post请求中的CookieCollection就好了,要的cookies就会在成功登录后返回,后续的抓取就用这个CookieCollection就好了。
下面是post请求:

[C#] 纯文本查看 复制代码
            signin = logout();

            item = new HttpItem()
            {
                URL = "https://www.mysite.com/login",
                Encoding = null,
                Method = "Post",
                ContentType = "application/x-www-form-urlencoded",
                Postdata = "username=myuser&password=mypass",
                KeepAlive = true,
                Referer = "http://www.mysite.com/home",
                Allowautoredirect = false,
                ResultCookieType = ResultCookieType.CookieCollection,
                CookieCollection = signin.CookieCollection,  // 这是前面get请求获得的
            };
//此响应中含有以后要用到的信息,保留起来,每次请求都用就Ok了
            signin = http.GetHtml(item);




回复

使用道具 举报

您需要登录后才可以回帖 登录 | 马上注册

本版积分规则

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

GMT+8, 2024-4-28 02:43

© 2014-2021

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