VC使用libcurl模拟登录CSDN并自动评论资源以获取积分

来源:互联网 发布:从化数据 编辑:程序博客网 时间:2024/04/29 20:26

环境:Win7 64位+VC2008

软件及源码下载:(http://pan.baidu.com/s/1jGE52pK)

涉及到的知识点:

C++多线程编程

libcurl的使用(包括发送http请求、发送cookie给服务器、保存cookie)

关于libcurl的资料,推荐大家参考下官方文档:http://curl.haxx.se/libcurl/c/example.html

软件运行结果

原帖提供的源码已经不可用,改了下提供的源码自己的又可以登录自动评价了(2015年2月10日00:53:10)如图:


添加两张HttpWatch的使用图
1:这个就不用多说了,大家都是明白人,这个就是登录第一步访问的url地址
2:刚才忘了说,这个列表包括了请求和返回的全部数据包
3:post请求,以及访问该网站的路径地址,
4:这个微信网站用来防止外链登录的,一开始试登录的时候忘了加这个,然后总是奇怪登录不上,然后把head字段一个个试才知道是需要这个字段;
5:这个也必须得写上,因为有点网站禁止了一些随意的抓包,所以必须得模拟你所在的运行环境。不让服务器发送你是抓包;
6:这个是post的数据列表;
7:这个就是服务器那边需要在本地设置的cookie值,这个得缓存起来,然后在后面的操作发送给服务器,因为服务器有时会用到某些值,如果没有的话就不好办了, 你懂的;
8:这个就是登录操作返回过来的结果,具体的数据就要看自己分析了,这里的数据是一个json字符串,

libcurl中的所有函数

curl_easy_cleanup 

curl_easy_duphandle 
curl_easy_escape 
curl_easy_getinfo 
curl_easy_init 
curl_easy_pause 
curl_easy_perform 
curl_easy_recv 
curl_easy_reset 
curl_easy_send 
curl_easy_setopt 
curl_easy_strerror 
curl_easy_unescape 
curl_escape (deprecated, do not use
curl_formadd 
curl_formfree 
curl_formget 
curl_free 
curl_getdate 
curl_getenv (deprecated, do not use
curl_global_cleanup 
curl_global_init 
curl_global_init_mem 
curl_mprintf (deprecated, do not use
curl_multi_add_handle 
curl_multi_assign 
curl_multi_cleanup 
curl_multi_fdset 
curl_multi_info_read 
curl_multi_init 
curl_multi_perform 
curl_multi_remove_handle 
curl_multi_setopt 
curl_multi_socket 
curl_multi_socket_action 
curl_multi_strerror 
curl_multi_timeout 
curl_share_cleanup 
curl_share_init 
curl_share_setopt 
curl_share_strerror 
curl_slist_append 
curl_slist_free_all 
curl_strequal (deprecated, do not use
curl_strnequal (deprecated, do not use
curl_unescape (deprecated, do not use
curl_version 
curl_version_info


以下几个函数需要重点掌握
curl_easy_init 
curl_easy_cleanup 
curl_easy_getinfo 
curl_easy_perform 
curl_easy_setopt 
curl_global_cleanup 
curl_version 


CURLcode curl_global_init(long flags)
描述:这个函数只能用一次。(其实在调用curl_global_cleanup 函数后仍然可再用)
如果这个函数在curl_easy_init函数调用时还没调用,它将由libcurl库自动完成。

参数:flags
CURL_GLOBAL_ALL           //初始化所有的可能的调用。
CURL_GLOBAL_SSL           //初始化支持 安全套接字层。
CURL_GLOBAL_WIN32         //初始化win32套接字库。
CURL_GLOBAL_NOTHING     //没有额外的初始化。

void curl_global_cleanup(void);
描述:在结束libcurl使用的时候,用来对curl_global_init做的工作清理。类似于close的函数。

char *curl_version( );

描述: 打印当前libcurl库的版本

CURL *curl_easy_init( );
描述:curl_easy_init用来初始化一个CURL的指针(有些像返回FILE类型的指针一样). 相应的在调用结束时要用curl_easy_cleanup函数清理.
一般curl_easy_init意味着一个会话的开始. 它的返回值一般都用在easy系列的函数中

void curl_easy_cleanup(CURL *handle);
描述:这个调用用来结束一个会话.与curl_easy_init配合着用.
参数:CURL类型的指针.

CURLcode curl_easy_setopt(CURL *handle, CURLoption option, parameter);
描述: 这个函数最重要了.几乎所有的curl 程序都要频繁的使用它.
它告诉curl库.程序将有如何的行为. 比如要查看一个网页的html代码等.
(这个函数有些像ioctl函数)
参数:
1 CURL类型的指针
2 各种CURLoption类型的选项.(都在curl.h库里有定义,man 也可以查看到)
3 parameter 这个参数 既可以是个函数的指针,也可以是某个对象的指针,也可以是个long型的变量.它用什么这取决于第二个参数.
CURLoption 这个参数的取值很多.具体的可以查看man手册.

CURLcode curl_easy_perform(CURL *handle);
描述:这个函数在初始化CURL类型的指针 以及curl_easy_setopt完成后调用. 就像字面的意思所说perform就像是个舞台.让我们设置的
option 运作起来.
参数:
CURL类型的指针

如何操作cookie

通过curl_easy_setopt函数的第二个参数,就可以很容易的操作cookie
保存cookie信息到本地的cookie.txt文件
[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. curl_easy_setopt(curl, CURLOPT_COOKIEJAR, "cookie.txt");  
读取本地的cookie.txt文件中的cookie信息
[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. curl_easy_setopt(easy_handle, CURLOPT_COOKIEFILE, "cookie.txt");  

模拟登录csdn

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. ReturnInfo CCSDNDlg::LoginServer(CString strUser,CString strPass)  
  2. {  
  3.     ReturnInfo returnInfo;  
  4.     returnInfo.bReturn = FALSE;  
  5.   
  6.     CURL *curl;  
  7.     CURLcode res;  
  8.     struct curl_slist *headers = NULL;  
  9.     curl_global_init(CURL_GLOBAL_ALL);  
  10.     curl = curl_easy_init();  
  11.     if(curl){  
  12.         //初始化cookie引擎  
  13.         curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "");  
  14.         curl_easy_setopt(curl,CURLOPT_FOLLOWLOCATION, 1L);  
  15.   
  16.         //http请求头  
  17.         headers = curl_slist_append(headers,"User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64; rv:25.0) Gecko/20100101 Firefox/25.0"); //模拟浏览器  
  18.         headers = curl_slist_append(headers,"Host:passport.csdn.net");  
  19.         headers = curl_slist_append(headers,"Accept:*/*");  
  20.         headers = curl_slist_append(headers,"Accept-Language:zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3");  
  21.         headers = curl_slist_append(headers,"Accept-Encoding:gzip, deflate");  
  22.         headers = curl_slist_append(headers,"X-Requested-With:XMLHttpRequest");  
  23.         headers = curl_slist_append(headers,"Referer:https://passport.csdn.net/account/loginbox?callback=logined&hidethird=1&from=http%3a%2f%2fwww.csdn.net%2f");  
  24.         headers = curl_slist_append(headers,"Connection:keep-alive");  
  25.           
  26.         curl_easy_setopt(curl, CURLOPT_COOKIEJAR, "cookie.txt");        //把服务器发过来的cookie保存到cookie.txt  
  27.   
  28.         //发送http请求头  
  29.         curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);  
  30.         char url[256];  
  31.         sprintf(url,"http://passport.csdn.net/ajax/accounthandler.ashx?t=log&u=%s&p=%s&remember=0&f=http%3A%2F%2Fwww.csdn.net%2F&rand=0.47590136872096434",strUser,strPass);  
  32.         curl_easy_setopt(curl, CURLOPT_URL,url);  
  33.   
  34.         string content;  
  35.         //设置回调函数  
  36.         res = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer);  
  37.         res = curl_easy_setopt(curl, CURLOPT_WRITEDATA, &content);  
  38.   
  39.         //执行http请求  
  40.         res = curl_easy_perform(curl);  
  41.   
  42.         string returnVal;  
  43.         Utf8ToMb((char*)content.c_str(),content.length(),returnVal);  
  44.         int pos = returnVal.find("\"status\":true");  
  45.         if ( pos >= 0){  
  46.             returnInfo.bReturn = TRUE;  
  47.             int nStartPos = content.find("data\":");  
  48.             int nEndPos   = content.rfind("\"}}");  
  49.             returnInfo.data = content.substr(nStartPos+6,nEndPos - nStartPos-4);  
  50.         }else{  
  51.             int nStartPos = returnVal.find("error\":");  
  52.             int nEndPos   = returnVal.find("data\":",nStartPos);  
  53.             returnInfo.strErrorInfo = returnVal.substr(nStartPos+8,nEndPos-nStartPos-11);  
  54.         }  
  55.         //释放资源  
  56.         curl_easy_cleanup(curl);  
  57.         curl_slist_free_all(headers);  
  58.         headers = NULL;  
  59.     }  
  60.     curl_global_cleanup();  
  61.     return returnInfo;  
  62. }  

根据给定的网址获取网页源码

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. static string GetHtmlPage(string url)  
  2. {  
  3.     CURL *easy_handle;  
  4.     CURLcode res;  
  5.     string content;  
  6.     curl_global_init(CURL_GLOBAL_ALL);  
  7.     easy_handle = curl_easy_init();  
  8.     if( easy_handle )  
  9.     {  
  10.         //初始化cookie引擎  
  11.         curl_easy_setopt(easy_handle, CURLOPT_COOKIEFILE,"");  
  12.         curl_easy_setopt(easy_handle,CURLOPT_TIMEOUT,5);            //设置请求超时时间  
  13.         //curl_easy_setopt(easy_handle,CURLOPT_VERBOSE,1);          //输出请求头和响应头  
  14.         //curl_easy_setopt(easy_handle,CURLOPT_HEADER,1);  
  15.         curl_easy_setopt(easy_handle,CURLOPT_FOLLOWLOCATION, 1L);  
  16.   
  17.         //http请求头  
  18.         struct curl_slist *headers = NULL;  
  19.         headers = curl_slist_append(headers,"Host: download.csdn.net");  
  20.         headers = curl_slist_append(headers,"User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:25.0) Gecko/20100101 Firefox/25.0");  
  21.         headers = curl_slist_append(headers,"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");  
  22.         headers = curl_slist_append(headers,"Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3");          
  23.         headers = curl_slist_append(headers,"Referer: http://www.csdn.net/");  
  24.         headers = curl_slist_append(headers,"Connection: keep-alive");  
  25.         curl_easy_setopt(easy_handle, CURLOPT_HTTPHEADER, headers);  
  26.   
  27.         curl_easy_setopt(easy_handle, CURLOPT_COOKIEFILE, "cookie.txt");        //读取本地存储的cookie  
  28.   
  29.         if(!InitCurl(easy_handle,res,url,content))  
  30.         {  
  31.             //释放资源  
  32.             curl_slist_free_all(headers);  
  33.             curl_easy_cleanup(easy_handle);  
  34.             return NULL;  
  35.         }  
  36.         //释放资源  
  37.         curl_slist_free_all(headers);  
  38.         curl_easy_cleanup(easy_handle);  
  39.     }  
  40.     curl_global_cleanup();  
  41.     string tt;  
  42.     Utf8ToMb((char *)content.c_str(),content.length(),tt);  
  43.     return tt;  
  44. }  

获取下载资源总页数

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. static int GetTotalPageNum()  
  2. {  
  3.     string url = "http://download.csdn.net/my/downloads/1";  
  4.   
  5.     string html = GetHtmlPage(url);  
  6.     int nPos = html.rfind("尾页");  
  7.     if (nPos == -1)  
  8.         return -1;  
  9.     nPos -= 2;  
  10.     int nStartPos = html.rfind("/",nPos);  
  11.     string strTotal = html.substr(nStartPos+1,nPos - nStartPos - 1);  
  12.     return atoi(strTotal.c_str());  
  13. }  

获取待评论的资源列表

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. static vector<DownResourceInfo> GetToCommentList(int pageNum)  
  2. {  
  3.     vector<DownResourceInfo> vtDownload;  
  4.     char url[128] = {0};  
  5.     sprintf(url,"http://download.csdn.net/my/downloads/%d",pageNum);  
  6.     string html = GetHtmlPage(url);  
  7.     int nPos = 0;  
  8.     int n = 0;  
  9.     int flag = 1;  
  10.     while((nPos = html.find("#comment",n)) != -1)  
  11.     {  
  12.         n = nPos+1;  
  13.         int nStartPos = html.rfind("/",nPos);  
  14.         string strUrl = html.substr(nStartPos+1,nPos - nStartPos -1);  
  15.         DownResourceInfo info;  
  16.         info.strResourceCurl = strUrl;  
  17.         //获取资源的名字  
  18.         nStartPos = html.find(strUrl,nPos+1);  
  19.         if(nStartPos == -1)  
  20.             return vtDownload;  
  21.         nStartPos += 2;  
  22.         nStartPos += strUrl.length();  
  23.         int nEndPos = html.find("</a>",nStartPos);  
  24.         string ResourceName = html.substr(nStartPos,nEndPos - nStartPos);  
  25.         info.strResourceName = ResourceName;          
  26.         vtDownload.push_back(info);  
  27.     }  
  28.     return vtDownload;  
  29. }  

发表评论

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. static BOOL AddComment(string sourceId)  
  2. {  
  3.     CURL *easy_handle;  
  4.     CURLcode res;  
  5.     string content;  
  6.     curl_global_init(CURL_GLOBAL_ALL);  
  7.     easy_handle = curl_easy_init();  
  8.     if( easy_handle )  
  9.     {  
  10.         //初始化cookie引擎  
  11.         curl_easy_setopt(easy_handle, CURLOPT_COOKIEFILE,"");         
  12.         curl_easy_setopt(easy_handle,CURLOPT_FOLLOWLOCATION, 1L);         
  13.         string url = "http://download.csdn.net/index.php/comment/post_comment?jsonpcallback=jsonp1385304626524&sourceid="+sourceId+"&content=%E9%9D%9E%E5%B8%B8%E6%84%9F%E8%B0%A2%EF%BC%8C%E8%BF%99%E8%B5%84%E6%BA%90%E6%88%91%E6%89%BE%E4%BA%86%E5%A5%BD%E4%B9%85%E4%BA%86%EF%BC%81&rating=5&t=1385304679900";  
  14.         string referer = "Referer: http://download.csdn.net/detail/wasdzxce/"+sourceId;  
  15.         //http请求头  
  16.         struct curl_slist *headers = NULL;        
  17.         headers = curl_slist_append(headers,"Host: download.csdn.net");  
  18.         headers = curl_slist_append(headers,"User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:25.0) Gecko/20100101 Firefox/25.0");  
  19.         headers = curl_slist_append(headers,"Accept: text/javascript, application/javascript, */*");  
  20.         headers = curl_slist_append(headers,"Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3");  
  21.         headers = curl_slist_append(headers,"Accept-Encoding: gzip, deflate");  
  22.         headers = curl_slist_append(headers,"Content-Type: application/x-www-form-urlencoded");  
  23.         headers = curl_slist_append(headers,"X-Requested-With: XMLHttpRequest");  
  24.         headers = curl_slist_append(headers,referer.c_str());  
  25.         headers = curl_slist_append(headers,"Connection: keep-alive");  
  26.         curl_easy_setopt(easy_handle, CURLOPT_HTTPHEADER, headers);  
  27.         curl_easy_setopt(easy_handle, CURLOPT_COOKIEFILE, "cookie.txt");        //读取本地存储的cookie  
  28.         if(!InitCurl(easy_handle,res,url,content))  
  29.         {  
  30.             //释放资源  
  31.             curl_slist_free_all(headers);  
  32.             curl_easy_cleanup(easy_handle);  
  33.             curl_global_cleanup();  
  34.             return FALSE;  
  35.         }  
  36.         //释放资源  
  37.         curl_slist_free_all(headers);  
  38.         curl_easy_cleanup(easy_handle);  
  39.     }  
  40.     curl_global_cleanup();  
  41.     int pos = content.find("\"succ\":1");  
  42.     if (pos>=0)  
  43.         return TRUE;  
  44.     else  
  45.         return FALSE;  
  46. }  


原文地址:曾是土木人



0 0
原创粉丝点击