C#实现知乎登录、点赞、关注、退出、评论(一)登录

来源:互联网 发布:android源码里编译apk 编辑:程序博客网 时间:2024/06/06 19:52
因为某些需求涉及到了这个方面,重新整理一遍与大家分享。

     首先打开知乎主页https://www.zhihu.com/

     会发现提示登录,开始模拟抓包。(建议用Chrome或者IE9以上版本按F12)

     故意输入错误的帐号密码登录结果如下:

Request URL:
https://www.zhihu.com/login/phone_num
  1. Request Form Data:_xsrf=a47378f80cdf8920b558caf0166d176d&password=xxxxx&remember_me=true&phone_num=xxxx&captcha=6370
  2. 格式化之后也就是
    1. _xsrf:
      a47378f80cdf8920b558caf0166d176d
    2. password:
      xxxx
    3. remember_me:
      true
    4. phone_num:
      xxxxxx
    5. Captcha:6370

    6. 经过多次验证发现对应关系为
    7. _xsrf为跨域验证字符串,password为用户密码,remember_me为是否记住密码,phone_num为手机号(咦?手机号,原来知乎帐号有两种,一种是手机账号一种邮箱帐号,现在先说手机帐号,稍后说另一个)Captcha:验证码
    ok,基本关系数据搞懂了,如何获取这些参数呢?
  3.      首先是_xsrf是一种知乎的跨域验证方案,举个栗子在A.html页面中存在一个input(hidden),server给这个hideen随机赋值并储存,然后当用户post提交到B.html时验证这个xsrf是否正确。一般用于防止爬虫、恶意提交之类的。那么如何获取_xhrf呢?可以使用HttpWebRequest来模拟,获取html源代码然后找出xhrf
  4. C#code
  5.  private string GetXsrf(string uri)        {            HttpWebRequest request = null;            string url = uri;   //登录页面            request = (HttpWebRequest)WebRequest.Create(url);            request.Method = "get";            request.Accept = "*/*;";            request.UserAgent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; InfoPath.3; BOIE9;ZHCN)";            request.ContentType = "application/x-www-form-urlencoded";            request.AllowAutoRedirect = true;            request.KeepAlive = true;            request.Referer = url;            HttpWebResponse response = (HttpWebResponse)request.GetResponse();            string strWebData = string.Empty;            using (StreamReader reader = new StreamReader(response.GetResponseStream()))            {                strWebData = reader.ReadToEnd();            }            return strWebData.Substring(strWebData.IndexOf("_xsrf") + 14, 32);//此处测试使用为了提升性能可以用正则表达式        }

    下一个获取captcha验证码,这个可以使用C#下载验证码存储为image 展示在picturebox或者直接用插件识别。
  6. 使用chrome右键‘审查’验证码发现地址为http://www.zhihu.com/captcha.gif
  7. 为了能够登陆时使用对应的验证码所以要保存cookie
  8.  CookieContainer cookies = null;        string strCookies = string.Empty;        private void GetValidateImage()        {            cookies = new CookieContainer();            string url = "http://www.zhihu.com/captcha.gif";  //验证码页面            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);            request.Accept = "*/*";            request.Method = "GET";            request.UserAgent = "Mozilla/5.0";            request.CookieContainer = new CookieContainer(); //暂存到新实例            HttpWebResponse response = (HttpWebResponse)request.GetResponse();            MemoryStream ms = null;            using (var stream = response.GetResponseStream())            {                Byte[] buffer = new Byte[response.ContentLength];                int offset = 0, actuallyRead = 0;                do                {                    actuallyRead = stream.Read(buffer, offset, buffer.Length - offset);                    offset += actuallyRead;                }                while (actuallyRead > 0);                ms = new MemoryStream(buffer);            }            response.Close();            cookies = request.CookieContainer; //保存cookies            strCookies = request.CookieContainer.GetCookieHeader(request.RequestUri); //把cookies转换成字符串            pictureBox_YZM.Image = Image.FromStream(ms);//将验证码显示在picturebox上

    然后呢,我们已经获取了_xhrf,captcha还剩下password、remember_me、phone_num这三个就是用户自己设置了。
  9. 尝试模拟登录。
     private string Login(string name, string password,string yzm)        {            HttpWebRequest request = null;            string url = "http://www.zhihu.com/login/phone_num";   //登录页面            request = (HttpWebRequest)WebRequest.Create(url);            request.Method = "POST";            request.Accept = "*/*;";            request.UserAgent = "Mozilla/5.0";            request.ContentType = "application/x-www-form-urlencoded";            request.AllowAutoRedirect = true;            request.CookieContainer = cookies; //此处使用获取验证码的那个cookie            request.KeepAlive = true;            string postData = string.Format("password={0}&captcha={2}&remember_me=false&phone_num={1}", password, name, yzm);              byte[] postdatabyte = Encoding.UTF8.GetBytes(postData);            request.ContentLength = postdatabyte.Length;            using (Stream stream = request.GetRequestStream())            {                stream.Write(postdatabyte, 0, postdatabyte.Length);            }            HttpWebResponse response = (HttpWebResponse)request.GetResponse();            string strWebData = string.Empty;            using (StreamReader reader = new StreamReader(response.GetResponseStream()))            {                strWebData = reader.ReadToEnd();            }            return strWebData;        }
    继续发现获取服务器返回了如下信息:
  10. {    "r": 1,    "errcode": 100030,    "data": {"account":"\u8bf7\u8f93\u5165\u6b63\u786e\u7684\u624b\u673a\u53f7"},    "msg": null}

    其中的data经过解码数据为 “请输入正确的手机号”,data为返回的信息。就这样登录完成了。
  11. 那么问题来了,前文有提到过,如果用邮箱帐号登录的呢?
  12. 继续抓包,使用邮箱帐号登录。发现了区别request url变成了https://www.zhihu.com/login/email
  13. 发送数据的变成了
    1. _xsrf:
      a47378f80cdf8920b558caf0166d176d
    2. password:
      xxxxx
    3. remember_me:
      true
    4. email:
      xxx@xxxxx.com
    5. Captcha:4568
    6. 可以看出来,邮箱登录和手机号登录区别只是改变了request和一个参数不一样.那么你可以修改Login方法简单判断用户名中是否有'@'而进行不同的登录处理。
    7. 好了,这些就是登录部分。


1 0
原创粉丝点击