分享

自动登录人人网程序的编写

 北书房2014 2017-02-11

人人网需要天天登陆,才能获得持续的登录奖励,但是每次都登录啥的,感觉非常没意思,于是派生出用软件来自动登陆,这样既省时省事,又能获得奖励。

登录过程非常简单,就是模拟浏览器发送请求,如果你需要更新状态,需要从返回的请求包中提取出get_check,然后在发送的时候使用这个值就ok了。

当然服务器返回的数据中,使用的是gzip编码,需要进行响应的解码才能得到数据。

别的不多说了,贴C++代码。

环境 Win7 +VS2010MFC+ zlib。

以下是登录代码:

C++代码
  1. // 模拟FireFox4.0 登陆网页  

  2. bool CLoginDlg::OnPcWebLogin(const CString &email,  // username : email  

  3. const CString &password)        // password:  

  4. {  

  5. bool ret = false;  

  6. CInternetSession  session;  

  7. CHttpConnection* pServer;  

  8. CHttpFile* pf;  

  9. m_check = "";  

  10. try  

  11. {  

  12. CString ServerName  =  "www.renren.com";  

  13. INTERNET_PORT nPort  =  80;  //port  

  14. CString suffix = "autoLogin=false&origURL=http%3A%2F%2Fwww.renren.com%2Fhome&domain=renren.com";  

  15. CString data = "email=" + email + "&password=" + password + "&" + suffix;  

  16. pServer  = session.GetHttpConnection(ServerName, nPort);   

  17. //拼接头部  

  18. pf =  pServer->OpenRequest(CHttpConnection::HTTP_VERB_POST,"/PLogin.do");  

  19. pf->AddRequestHeaders("Host: www.renren.com");    

  20. pf->AddRequestHeaders("User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:2.0) Gecko/20100101 Firefox/4.0");  

  21. pf->AddRequestHeaders("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");   

  22. pf->AddRequestHeaders("Accept-Language: zh-cn,zh;q=0.5");  

  23. pf->AddRequestHeaders("Accept-Encoding: gzip, deflate");  

  24. pf->AddRequestHeaders("Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7"); //  

  25. pf->AddRequestHeaders("Keep-Alive: 115");   //  

  26. pf->AddRequestHeaders("DNT: 1");   //   

  27. pf->AddRequestHeaders("Connection:Keep-Alive");  

  28. pf->AddRequestHeaders("Referer: http://www.renren.com/SysHome.do");  

  29. pf->AddRequestHeaders("Content-Type: application/x-www-form-urlencoded");  

  30. pf->SendRequest(NULL, 0, data.GetBuffer(0), data.GetLength());  

  31. DWORD statusCode = 0;  

  32. if(!pf->QueryInfoStatusCode(statusCode) || statusCode != HTTP_STATUS_OK)  

  33. {  

  34. CString e;  

  35. e.Format("PC WEB Login failed, Pls Check. status code = %d/n", statusCode);  

  36. throw exception(e.GetBuffer());  

  37. }  

  38. DWORD ptrLen = 100 * 1024;  

  39. // 以下为读取数据  

  40. LPSTR ptr = new CHAR[ptrLen];  

  41. ZeroMemory(ptr, ptrLen);  

  42. DWORD len = 0, len2 = 0;  

  43. do  

  44. {  

  45. len = pf->Read(ptr + len2, ptrLen);  

  46. len2 += len;  

  47. }while(len != 0);  

  48. LPSTR ptr2 = new CHAR[ptrLen];  

  49. ZeroMemory(ptr2, ptrLen);  

  50. // 由gzip解压  

  51. httpgzdecompress((Byte *)ptr, len2, (Byte *)ptr2, &ptrLen);  

  52. delete ptr;  

  53. ptr = NULL;  

  54. // 寻找校验码  

  55. LPSTR checkBeginPos = strstr(ptr2, "get_check:/'");  

  56. if(checkBeginPos != NULL)  

  57. {  

  58. checkBeginPos += strlen("get_check:/'");  

  59. LPSTR checkEndPos = strstr(checkBeginPos, "/'");  

  60. if(checkEndPos != NULL)  

  61. {  

  62. *checkEndPos = '/0';  

  63. m_check = checkBeginPos;  

  64. ret = true;  

  65. }  

  66. }  

  67. delete ptr2;  

  68. ptr2 = NULL;  

  69. }  

  70. catch(exception e)  

  71. {  

  72. TRACE("[ERROR]:%s/n", e.what());  

  73. }  

  74. if(pf != NULL)  

  75. {  

  76. pf->Close();  

  77. delete pf;  

  78. pf = NULL;  

  79. }  

  80. if(pServer != NULL)  

  81. {  

  82. pServer->Close();  

  83. delete pServer;  

  84. pServer = NULL;  

  85. }  

  86. session.Close();  

  87. return ret;  

  88. }  

以下是发送状态的代码。

这里面的状态要求是utf8编码,务必请自己转换。

C++代码
  1. bool CLoginDlg::OnPcWebStatus(const CString &status)        // status for update  

  2. {  

  3. bool ret = false;  

  4. if(m_check == "")  

  5. {  

  6. TRACE("Pls Login First!/n");  

  7. return ret;  

  8. }  

  9. CInternetSession session;  

  10. CHttpConnection* pServer;  

  11. CHttpFile* pf;  

  12. CString  ServerName  =  "status.renren.com";  

  13. INTERNET_PORT  nPort  =  80;  //port  

  14. CString data = "c=" + status + "&raw=" + status + "&isAtHome=1&publisher_form_ticket=" + m_check + "&requestToken=" + m_check;  

  15. pServer  = session.GetHttpConnection(ServerName,nPort);   


  16. //拼接头部  

  17. pf =  pServer->OpenRequest(CHttpConnection::HTTP_VERB_POST,"/doing/update.do?");  

  18. pf->AddRequestHeaders("Host:  status.renren.com");    

  19. pf->AddRequestHeaders("User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:2.0) Gecko/20100101 Firefox/4.0");  

  20. pf->AddRequestHeaders("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");   

  21. pf->AddRequestHeaders("Accept-Language: zh-cn,zh;q=0.5");  

  22. pf->AddRequestHeaders("Accept-Encoding: gzip, deflate");  

  23. pf->AddRequestHeaders("Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7"); //  

  24. pf->AddRequestHeaders("Keep-Alive: 115");   //  

  25. pf->AddRequestHeaders("DNT: 1");   //   

  26. pf->AddRequestHeaders("Connection:Keep-Alive");  

  27. pf->AddRequestHeaders("Content-Type: application/x-www-form-urlencoded; charset=UTF-8");  

  28. pf->AddRequestHeaders("Referer:  http://status.renren.com/ajaxproxy.htm");  


  29. pf->SendRequest(NULL,0,data.GetBuffer(0), data.GetLength());    

  30. ret = true;  

  31. DWORD statusCode = 0;  

  32. if(!pf->QueryInfoStatusCode(statusCode) || statusCode != HTTP_STATUS_OK)  

  33. {  

  34. TRACE("Fuck for error %d/n", statusCode);  

  35. ret = false;  

  36. }  

  37. if(pf != NULL)  

  38. {  

  39. pf->Close();  

  40. delete pf;  

  41. pf = NULL;  

  42. }  

  43. if(pServer != NULL)  

  44. {  

  45. pServer->Close();  

  46. delete pServer;  

  47. pServer = NULL;  

  48. }  

  49. session.Close();  

  50. return ret;  

  51. }  

转换代码如下:

C++代码
  1. DWORD ucs2Len = MultiByteToWideChar(CP_ACP, 0,  

  2. status.GetBuffer(0), status.GetLength(), NULL, 0);  

  3. PWCHAR ucs2 = new WCHAR[ucs2Len + 1];  

  4. ZeroMemory(ucs2, (ucs2Len + 1) * sizeof(WCHAR));  

  5. MultiByteToWideChar(CP_ACP, 0,  

  6. status.GetBuffer(0), status.GetLength(), ucs2, ucs2Len + 1);  

  7. DWORD utf8Len = WideCharToMultiByte(CP_UTF8, 0, ucs2, ucs2Len, NULL, 0, 0, 0);  

  8. PCHAR utf8 = new CHAR[utf8Len + 1];  

  9. ZeroMemory(utf8, (utf8Len + 1) * sizeof(CHAR));  

  10. WideCharToMultiByte(CP_UTF8, 0, ucs2, ucs2Len, utf8, utf8Len, 0, 0);  

  11. CString newStatus = utf8;  

  12. delete [] utf8;  

  13. utf8 = NULL;  

  14. delete [] ucs2;  

  15. ucs2 = NULL;  

最后还有最重要的是,gzip解码代码,这部分代码时参考某位大神提供的gzip的测试代码,具体是哪位大神,没有记录下来,非常的不好意思。

C++代码
  1. /* HTTP gzip decompress */  

  2. int httpgzdecompress(Byte *zdata, uLong nzdata,                   

  3. Byte *data, uLong *ndata)  

  4. {  

  5. int err = 0;  

  6. z_stream d_stream = {0}; /* decompression stream */  

  7. static char dummy_head[2] =   

  8. {  

  9. 0x8 + 0x7 * 0x10,  

  10. (((0x8 + 0x7 * 0x10) * 0x100 + 30) / 31 * 31) & 0xFF,  

  11. };  

  12. d_stream.zalloc = (alloc_func)0;  

  13. d_stream.zfree = (free_func)0;  

  14. d_stream.opaque = (voidpf)0;  

  15. d_stream.next_in  = zdata;  

  16. d_stream.avail_in = 0;  

  17. d_stream.next_out = data;  

  18. if(inflateInit2(&d_stream, 47) != Z_OK) return -1;  

  19. while (d_stream.total_out < *ndata && d_stream.total_in < nzdata) {  

  20. d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */  

  21. if((err = inflate(&d_stream, Z_NO_FLUSH)) == Z_STREAM_END) break;  

  22. if(err != Z_OK )  

  23. {  

  24. if(err == Z_DATA_ERROR)  

  25. {  

  26. d_stream.next_in = (Bytef*) dummy_head;  

  27. d_stream.avail_in = sizeof(dummy_head);  

  28. if((err = inflate(&d_stream, Z_NO_FLUSH)) != Z_OK)   

  29. {  

  30. return -1;  

  31. }  

  32. }  

  33. else return -1;  

  34. }  

  35. }  

  36. if(inflateEnd(&d_stream) != Z_OK) return -1;  

  37. *ndata = d_stream.total_out;  

  38. return 0;  

  39. }  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约