用新浪微博api收集数据有诸多限制,每小时只能调用官方api函数150次,认证也很麻烦。因此想通过爬网页的方式来收集数据。访问新浪微博用户网页首先需要登录,登录获取cookie后可直接获取网页数据,无需再次登录。获取登录cookie的方式具体如下:

1)采用get的方式访问http://login.sina.com.cn/sso/prelogin.php?entry=miniblog&callback=sinaSSOController.preloginCallBack&user=账户&client=ssologin.js(v1.3.16),获取servertime和 nonce,用于之后的密码加密。注:账户值为登录新浪微博用户名的base64编码值。

2)处理新浪微博用户密码psw。若hex_sha1(pwd)表示对pwd进行sha1处理,则新浪微博用户密码的处理方式表示为hex_sha1(hex_sha1(hex_sha1(psw)) + servertime + nonce)。

3)采用post方式访问http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.3.16),并post如下数据:

string str = "entry=weibo&gateway=1&from=&savestate=7&useticket=1&ssosimplelogin=1&su=" +
                登录账户base64值 + "&service=miniblog&servertime=" + servertime + "&nonce=" + nonce + "&pwencode=wsse&sp=" + 密码处理值 + "&encoding=utf-8&url=" +
                HttpUtility.UrlEncode("http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack") +
                "&returntype=META";

4)如果登录成功,返回页面中retcode值为0;get方式访问网页中location.replace处的地址。

保存这三次访问页面的cookie后下次再访问新浪微博用不再需要重新登录了。具体代码如下:

static CookieContainer cc = new CookieContainer();

public static int SinaLogin(string uid, string psw, CookieContainer cc)
        {

string uidbase64 = Base64Code(uid); //处理登录账户 如***@**.com 
            string url = "http://login.sina.com.cn/sso/prelogin.php?entry=miniblog&callback=sinaSSOController.preloginCallBack&user="
                + uidbase64 + "&client=ssologin.js(v1.3.16)";
            HttpWebRequest webRequest1 = (HttpWebRequest)WebRequest.Create(new Uri(url)); //获取servertime和 nonce
            webRequest1.CookieContainer = cc;
            HttpWebResponse response1 = (HttpWebResponse)webRequest1.GetResponse();
            StreamReader sr1 = new StreamReader(response1.GetResponseStream(), Encoding.UTF8);
            string res = sr1.ReadToEnd();
            int start = res.IndexOf("servertime");
            if (start < 0 || start >= res.Count()) return -1;
            int end = res.IndexOf(',', start);
            if (end < 0 || end >= res.Count()) return -1;
            string servertime = res.Substring(start + 12, end - start - 12);

start = res.IndexOf("nonce");
            if (start < 0 || start >= res.Count()) return -1;
            end = res.IndexOf(',', start);
            if (end < 0 || end >= res.Count()) return -1;
            string nonce = res.Substring(start + 8, end - start - 9);

string password = hex_sha1("" + hex_sha1(hex_sha1(psw)) + servertime + nonce); //处理新浪微博用户密码psw

string str = "entry=weibo&gateway=1&from=&savestate=7&useticket=1&ssosimplelogin=1&su=" +
                uidbase64 + "&service=miniblog&servertime=" + servertime + "&nonce=" + nonce + "&pwencode=wsse&sp=" + password + "&encoding=utf-8&url=" +
                HttpUtility.UrlEncode("http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack") +
                "&returntype=META";
            byte[] bytes;
            ASCIIEncoding encoding = new ASCIIEncoding();
            bytes = encoding.GetBytes(str);
            // bytes = System.Text.Encoding.UTF8.GetBytes(HttpUtility.UrlEncode(str));
            HttpWebRequest webRequest2 = (HttpWebRequest)WebRequest.Create("http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.3.16)");
            webRequest2.Method = "POST";
            webRequest2.ContentType = "application/x-www-form-urlencoded";

webRequest2.ContentLength = bytes.Length;
            webRequest2.CookieContainer = cc;
            Stream stream;
            stream = webRequest2.GetRequestStream();
            stream.Write(bytes, 0, bytes.Length);
            stream.Close();

HttpWebResponse response2 = (HttpWebResponse)webRequest2.GetResponse();
            StreamReader sr2 = new StreamReader(response2.GetResponseStream(), Encoding.Default);
            string res2 = sr2.ReadToEnd();
            int pos = res2.IndexOf("retcode");
            if (pos < 0 || pos > res2.Count()) return -1;
            int retcode = -1;
            for (pos += 8; pos < 100 + res2.Count(); pos++)
            {
                if (res2[pos] < '0' || res2[pos] > '9')
                {
                    retcode = 0;
                    break;
                }
                else if (res2[pos] > '0' && res2[pos] <= '9')
                    break;
            }
            if (retcode == -1) return -1;

start = res2.IndexOf("location.replace");
            end = res2.IndexOf("")", start);
            url = res2.Substring(start + 18, end - start - 18);
            HttpWebRequest webRequest3 = (HttpWebRequest)WebRequest.Create(new Uri(url));
            webRequest3.CookieContainer = cc;
            HttpWebResponse response3 = (HttpWebResponse)webRequest3.GetResponse();
            StreamReader sr3 = new StreamReader(response3.GetResponseStream(), Encoding.UTF8);
            res = sr3.ReadToEnd();

foreach (Cookie cookie in response3.Cookies)
            {
                cc.Add(cookie);
            }
            return 0;
        }

//base64加密
        public static string Base64Code(string Message)
        {
            char[] Base64Code = new char[]{'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T', 
         'U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n', 
         'o','p','q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5','6','7', 
         '8','9','+','/','='};
            byte empty = (byte)0;
            System.Collections.ArrayList byteMessage = new System.Collections.ArrayList(System.Text.Encoding.Default.GetBytes(Message));
            System.Text.StringBuilder outmessage;
            int messageLen = byteMessage.Count;
            int page = messageLen / 3;
            int use = 0;
            if ((use = messageLen % 3) > 0)
            {
                for (int i = 0; i < 3 - use; i++)
                    byteMessage.Add(empty);
                page++;
            }
            outmessage = new System.Text.StringBuilder(page * 4);
            for (int i = 0; i < page; i++)
            {
                byte[] instr = new byte[3];
                instr[0] = (byte)byteMessage[i * 3];
                instr[1] = (byte)byteMessage[i * 3 + 1];
                instr[2] = (byte)byteMessage[i * 3 + 2];
                int[] outstr = new int[4];
                outstr[0] = instr[0] >> 2;
                outstr[1] = ((instr[0] & 0x03) << 4) ^ (instr[1] >> 4);
                if (!instr[1].Equals(empty))
                    outstr[2] = ((instr[1] & 0x0f) << 2) ^ (instr[2] >> 6);
                else
                    outstr[2] = 64;
                if (!instr[2].Equals(empty))
                    outstr[3] = (instr[2] & 0x3f);
                else
                    outstr[3] = 64;
                outmessage.Append(Base64Code[outstr[0]]);
                outmessage.Append(Base64Code[outstr[1]]);
                outmessage.Append(Base64Code[outstr[2]]);
                outmessage.Append(Base64Code[outstr[3]]);
            }
            return outmessage.ToString();
        }

// sha-1加密

public static string hex_sha1(string Source_String)
        {
            byte[] StrRes = Encoding.Default.GetBytes(Source_String);
            HashAlgorithm iSHA = new SHA1CryptoServiceProvider();
            StrRes = iSHA.ComputeHash(StrRes);
            StringBuilder EnText = new StringBuilder();
            foreach (byte iByte in StrRes)
            {
                EnText.AppendFormat("{0:x2}", iByte);
            }
            return EnText.ToString();
        }

提示下,我这个登录用的是v1.3.17版本的,最新的新浪微博登录的是v1.4.2版本的,密码采用的是RSA加密,目前还没研究。

微博很火啊,开发了一个微博爬虫应用

有的人 会说 新浪微博 不是API吗,为什么还要取单独开发爬虫系统呢

如果你用过新浪微博API,你就知道,有着诸多限制,功能少,信息少,信息不全,调用次数限制,重新授权等等 一系列的问题,最主要是返回的信息量少喝调用次数限制,

还有针对IP的.

我们设计这个爬虫的初衷是新浪微博的所有信息,目前是70%,为什么不是100%呢,说到底 还是资源问题了.

新浪微博号称有3亿多人,实际上我们发现存在的加上新注册的大概在2亿左右,其他的都是僵尸用户。

这些后续 再说吧。

这个系统最重要的第一步就是模拟登录了,如果登录都不行,后续的都是扯淡.

这个模拟登录早在2011年3月份就搞定了,到现在,登录也改过好几次,主要新浪那边有变动.

新浪模拟登录不算很复杂,最麻烦的就是验证码了.

要搞清楚这个登录,必须有些工具 httpfox,httpwatch,Fidder等web抓包工具中的一个。

我这里用的是httpFox,获取浏览器

weibo.com打开后,你需要找到对你登录可能产生影响的请求,上面蓝色的返回的参数都是我们需要的,貌似 现在我以前又有点不一样了,

sinaSSOController.preloginCallBack({"retcode":0,"servertime":1346291808,"pcid":"ec06b269ce680ef43ce669d56f9abbfd9d43","nonce":"28FKAG","pubkey":"EB2A38568661887FA180BDDB5CABD5F21C7BFD59C090CB2D245A87AC253062882729293E5506350508E7F9AA3BB77F4333231490F915F6D63C55FE2F08A49B353F444AD3993CACC02DB784ABBB8E42A9B1BBFFFB38BE18D78E87A0E41B9B8F73A928EE0CCEE1F6739884B9777E4FE9E88A1BBE495927AC4A799B3181D6442443","rsakv":"1330428213"})

servertime nonce 都是登录时候需要提交的,以及密码加密,pubkey 是RSAJS 加密的公共密钥 pcid rsakv post时候需要带上去

这些返回值你都需要保存下来。

现在开始登录

分析提交的参数:

entry=weibo&gateway=1&from=&savestate=7&useticket=1&vsnf=1&ssosimplelogin=1&su=dGVzdCU0MHNpbmEuY29t&service=miniblog&servertime=1346292130&nonce=28FKAG&pwencode=rsa2&rsakv=1330428213&sp=29f86ffc66bbd9ed7d750777a918fdf776211ef8ce4c3d4266111df5e3ad3cd06e2c11c9811a945d245b19eaf51174e70c798735ba5c96bb97220531c4131a6dc5f7207abeb2072401901e3259912b8e2cda3b6e540049b232d72d0693d7bb8db4d8e5d03f2f2b16c0bf11e3c0137150c80d355197b84da510d8c4ca117bbc58&encoding=UTF-8&prelt=264&url=http%3A%2F%2Fweibo.com%2Fajaxlogin.php%3Fframelogin%3D1%26callback%3Dparent.sinaSSOController.feedBackUrlCallBack&returntype=META

固定的我就不说了,

su账号base64加密 应改都会把

sp是密码的加密是下面这个方法,至于说 怎么知道这些加密的,其实也不是很复杂,你需要把这个页面的JS 下载下来单独分析,看哪个地方是最终post数据的,再逆向找加密的地方就知道了 SHAEncrypt 就是sha加密了

  1. protected static string SinaSHA(string pwd, string servertime, string nonce)
  2. {
  3. StringBuilder sbl = new StringBuilder();
  4. string tmppwd = SHAEncrypt(SHAEncrypt(pwd));
  5. sbl.Append(tmppwd);
  6. sbl.Append(servertime);
  7. sbl.Append(nonce);
  8. return SHAEncrypt(sbl.ToString());
  9. }

servertime,nonce,rsakv,pdid(主要是在需要验证码的时候获取)获取过的

参数都解决了,再看返回值

<html>
  <head>
  <title>ÐÂÀËͨÐÐÖ¤</title>
  <meta http-equiv="refresh" content="0; url='http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack&retcode=101&reason=%B5%C7%C2%BC%C3%FB%BB%F2%C3%DC%C2%EB%B4%ED%CE%F3'"/>
  <meta http-equiv="Content-Type" content="text/html; charset=GBK" />
  </head>
  <body bgcolor="#ffffff" text="#000000" link="#0000cc" vlink="#551a8b" alink="#ff0000">
  <script type="text/javascript" language="javascript">
  location.replace("http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack&retcode=101&reason=%B5%C7%C2%BC%C3%FB%BB%F2%C3%DC%C2%EB%B4%ED%CE%F3");
  </script>
  </body>
  </html>

只有当retcode=0的时候 才是登录成功,其他的都是登录失败,

101密码错误

5 也是密码错误

4057 你的账号异常了,需要人工认证下,

4049,2070 是需要验证码哦。

这里是登录失败了。如果是登录成功

<html>
<head>
<title>Sina Member</title>
<meta http-equiv="Content-Type" content="text/html; charset=GBK" />

<script charset="utf-8" src="http://i.sso.sina.com.cn/js/ssologin.js"></script>
</head>
<body>
Signing in ...
<script>
try{sinaSSOController.setCrossDomainUrlList({"retcode":0,"arrURL":["http:\/\/kandian.com\/logon\/do_crossdomain.php?action=login&savestate=1346897732","http:\/\/login.t.cn\/sinaurl\/sso.json?action=login&uid=你账号的UID"]});}catch(e){}try{sinaSSOController.crossDomainAction('login',function(){location.replace('http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack&ssosavestate=1346897732&ticket=ST-MTk3NDEyNjk1NQ==-1346292932-xd-B6F5BF7A5E4438EA368D6116E6FD1622&retcode=0');});}catch(e){}
</script>
</body>
</html>

这个retcode=0的就是登录成功了.

接下来 就需要提取这里面的3个URL了,分别请求一遍就OK了

值得注意的是,这一些列都要用同一个CookieContainer

到此,登录就成功了,接下来看需要验证码的.

当你的IP,或者账号 对新浪来说有怀疑的时候,主要是访问次数过多的问题的,或者你账号异常的情况,需要你输入验证码

找了半天,账号都忘记了,一时找不到 登录需要验证码的账号

如果是需要验证码:

post时候加个参数就可以了

door=验证码

当然你请求验证码的时候需要pcid就是上面的那个,同时需要同一个cooki了,

至于验证码怎么解决,我在验证码识别中有记录.

这样登录就都搞定了。

c#获取新浪微博登录cookie的更多相关文章

  1. C# 获取 新浪微博登录之后的 完整的Cookie

    程序说明: 1.此项目 包含两个项目, 一个 Winform WinGetMocroblogCookie 用于手动 登录 新浪微博 其中涉及到的技术有: 使用webbrowser 获取HttpOnly ...

  2. 第三方登录 QQ登录 人人网登录 新浪微博登录

    http://www.pp6.cn/Index.aspx http://www.pp6.cn/Login.aspx 网站有自己的账号系统,这里使用的第三方登录仅仅是获取第三方账号的唯一id,昵称,性别 ...

  3. 设置Cookie,登录记住用户登录信息,获取用户登录过得信息

    function setCookie(name,value) { var Days = 30; var exp = new Date(); exp.setTime(exp.getTime() + Da ...

  4. 爬虫程序获取登录Cookie信息时遇到302,怎么处理

    最近要做个爬虫程序爬爬东西,先搞定登录授权这块,没得源代码,所以只能自行搞定了,按平时的直接发起HttpWebRequest(req)请求,带上用户名密码,好了,然后 HttpWebResponse ...

  5. 定向爬虫 - Python模拟新浪微博登录

    当我们试图从新浪微博抓取数据时,我们会发现网页上提示未登录,无法查看其他用户的信息. 模拟登录是定向爬虫制作中一个必须克服的问题,只有这样才能爬取到更多的内容. 实现微博登录的方法有很多,一般我们在模 ...

  6. qq登录,新浪微博登录 ,接口开发

    给linux命令在线中文手册加了,qq登录和新浪微博登录,认证用的是auth2.0,并且用了js api和php api相结合的方式来做的.个人觉得这种方式,兼顾安全和人性化.以前写过一篇关于申请的博 ...

  7. php新浪微博登录接口用法实例

    本文实例讲述了php新浪微博登录接口用法.分享给大家供大家参考.具体分析如下: 在做微博登陆之前是需要申请到APP KEY 和App Secret,这个的申请方式请去 open.weibo.com 申 ...

  8. 新浪微博登录接口(PHP版)

    CI框架下 新浪微博登录接口完整版说明:本贴只适合CI框架.功能实现:登录接口跳转链接成功,获取用户信息(包括最重要的u_id)成功,将用户与本地平台连接起来,用户登录成功后信息的存储,本地数据库第三 ...

  9. 后台获取用户登录token 和获取前端参数方法

    //获取request请求中所有参数 Enumeration<String> names = request.getParameterNames(); HashMap<String, ...

随机推荐

  1. how to use tar?

    In UNIX, tar is the most useful tool to compress files (just like zip in Windows.) To compress, inpu ...

  2. android 瀑布流效果(仿蘑菇街)

    我们还是来看一款示例:(蘑菇街)           看起来很像我们的gridview吧,不过又不像,因为item大小不固定的,看起来是不是别有一番风味,确实如此.就如我们的方角图形,斯通见惯后也就出 ...

  3. ios做的两个矩形相交叉

    #import "ViewController.h" @interface ViewController (){    UIView *_gee;  //定义的实例变量    UI ...

  4. iOS长按选择

    确实,其实就是一个长按手势 + 图片二维码识别,原生SDK从8.0开始支持 /** *  从照片中直接识别二维码 *  @param qrCodeImage 带二维码的图片 *  @param myQ ...

  5. Tomcat 7优化

    1.在bin/catalina.bat文件中加入下面参数,对JVM进行优化,至于这一大驼参数的作用及说明,大家到网上找找,应该有很多的,如:http://www.mzone.cc/article/32 ...

  6. php常用命令大全

    1.php -v 查看版本号   [root@rs-2 lib]# php -v   PHP 5.5.11 (cli) (built: Apr 29 2014 12:35:52)   Copyrigh ...

  7. codeforces DIV2 D 最短路

    http://codeforces.com/contest/716/problem/D 题目大意:给你一些边,有权值,权值为0的表示目前该边不存在,但是可以把0修改成另外一个权值.现在,我们重新建路, ...

  8. iperf linux版本移植到android (使用工具链方式不是使用Android.mk)

    由于很多程序是用makefile编译linux应用程序的,如果移植到android就要重新写Android.mk,对于不熟悉这个的人来说,特别麻烦,所以这里介绍只修改makefile就能移植到andr ...

  9. iOS开发 GET、POST请求方法:NSURLSession篇

    NSURLConnection,在iOS 9被宣布弃用,本文不使用NSURLConnection进行网络编程,有兴趣的童鞋可以参考: iOS开发 GET.POST请求方法(NSURLConnectio ...

  10. Hibernate 系列教程12-继承-Join策略

    Employee public class Employee { private Long id; private String name; HourlyEmployee public class H ...