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

简介: 环境:Win7 64位+VC2008 软件及源码下载:(http://pan.baidu.com/s/1jGE52pK) 涉及到的知识点: C++多线程编程 libcurl的使用(包括发送http请求、发送cookie给服务器、保存cookie) 关于libcurl的资料,推荐大家参考下官方文档:http://curl.

环境:Win7 64位+VC2008

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

涉及到的知识点:

C++多线程编程

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

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

软件运行结果

libcurl中的所有函数

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

 
以下几个函数需要重点掌握

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文件
curl_easy_setopt(curl, CURLOPT_COOKIEJAR, "cookie.txt");

读取本地的cookie.txt文件中的cookie信息

1
curl_easy_setopt(easy_handle, CURLOPT_COOKIEFILE,  "cookie.txt" );

模拟登录csdn

复制代码
ReturnInfo CCSDNDlg::LoginServer(CString strUser,CString strPass)
{
    ReturnInfo returnInfo;
    returnInfo.bReturn = FALSE;

    CURL *curl;
    CURLcode res;
    struct curl_slist *headers = NULL;
    curl_global_init(CURL_GLOBAL_ALL);
    curl = curl_easy_init();
    if(curl){
        //初始化cookie引擎
        curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "");
        curl_easy_setopt(curl,CURLOPT_FOLLOWLOCATION, 1L);

        //http请求头
        headers = curl_slist_append(headers,"User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64; rv:25.0) Gecko/20100101 Firefox/25.0");    //模拟浏览器
        headers = curl_slist_append(headers,"Host:passport.csdn.net");
        headers = curl_slist_append(headers,"Accept:*/*");
        headers = curl_slist_append(headers,"Accept-Language:zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3");
        headers = curl_slist_append(headers,"Accept-Encoding:gzip, deflate");
        headers = curl_slist_append(headers,"X-Requested-With:XMLHttpRequest");
        headers = curl_slist_append(headers,"Referer:https://passport.csdn.net/account/loginbox?callback=logined&hidethird=1&from=http%3a%2f%2fwww.csdn.net%2f");
        headers = curl_slist_append(headers,"Connection:keep-alive");
        
        curl_easy_setopt(curl, CURLOPT_COOKIEJAR, "cookie.txt");        //把服务器发过来的cookie保存到cookie.txt

        //发送http请求头
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
        char url[256];
        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);
        curl_easy_setopt(curl, CURLOPT_URL,url);

        string content;
        //设置回调函数
        res = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer);
        res = curl_easy_setopt(curl, CURLOPT_WRITEDATA, &content);

        //执行http请求
        res = curl_easy_perform(curl);

        string returnVal;
        Utf8ToMb((char*)content.c_str(),content.length(),returnVal);
        int pos = returnVal.find("\"status\":true");
        if ( pos >= 0){
            returnInfo.bReturn = TRUE;
            int nStartPos = content.find("data\":");
            int nEndPos      = content.rfind("\"}}");
            returnInfo.data = content.substr(nStartPos+6,nEndPos - nStartPos-4);
        }else{
            int nStartPos = returnVal.find("error\":");
            int nEndPos      = returnVal.find("data\":",nStartPos);
            returnInfo.strErrorInfo = returnVal.substr(nStartPos+8,nEndPos-nStartPos-11);
        }
        //释放资源
        curl_easy_cleanup(curl);
        curl_slist_free_all(headers);
        headers = NULL;
    }
    curl_global_cleanup();
    return returnInfo;
}
复制代码

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

复制代码
static string GetHtmlPage(string url)
{
    CURL *easy_handle;
    CURLcode res;
    string content;
    curl_global_init(CURL_GLOBAL_ALL);
    easy_handle = curl_easy_init();
    if( easy_handle )
    {
        //初始化cookie引擎
        curl_easy_setopt(easy_handle, CURLOPT_COOKIEFILE,"");
        curl_easy_setopt(easy_handle,CURLOPT_TIMEOUT,5);            //设置请求超时时间
        //curl_easy_setopt(easy_handle,CURLOPT_VERBOSE,1);            //输出请求头和响应头
        //curl_easy_setopt(easy_handle,CURLOPT_HEADER,1);
        curl_easy_setopt(easy_handle,CURLOPT_FOLLOWLOCATION, 1L);

        //http请求头
        struct curl_slist *headers = NULL;
        headers = curl_slist_append(headers,"Host: download.csdn.net");
        headers = curl_slist_append(headers,"User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:25.0) Gecko/20100101 Firefox/25.0");
        headers = curl_slist_append(headers,"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
        headers = curl_slist_append(headers,"Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3");        
        headers = curl_slist_append(headers,"Referer: http://www.csdn.net/");
        headers = curl_slist_append(headers,"Connection: keep-alive");
        curl_easy_setopt(easy_handle, CURLOPT_HTTPHEADER, headers);

        curl_easy_setopt(easy_handle, CURLOPT_COOKIEFILE, "cookie.txt");        //读取本地存储的cookie

        if(!InitCurl(easy_handle,res,url,content))
        {
            //释放资源
            curl_slist_free_all(headers);
            curl_easy_cleanup(easy_handle);
            return NULL;
        }
        //释放资源
        curl_slist_free_all(headers);
        curl_easy_cleanup(easy_handle);
    }
    curl_global_cleanup();
    string tt;
    Utf8ToMb((char *)content.c_str(),content.length(),tt);
    return tt;
}
复制代码

获取下载资源总页数

复制代码
static int GetTotalPageNum()
{
    string url = "http://download.csdn.net/my/downloads/1";

    string html = GetHtmlPage(url);
    int nPos = html.rfind("尾页");
    if (nPos == -1)
        return -1;
    nPos -= 2;
    int nStartPos = html.rfind("/",nPos);
    string strTotal = html.substr(nStartPos+1,nPos - nStartPos - 1);
    return atoi(strTotal.c_str());
}
复制代码

获取待评论的资源列表

复制代码
static vector<DownResourceInfo> GetToCommentList(int pageNum)
{
    vector<DownResourceInfo> vtDownload;
    char url[128] = {0};
    sprintf(url,"http://download.csdn.net/my/downloads/%d",pageNum);
    string html = GetHtmlPage(url);
    int nPos = 0;
    int n = 0;
    int flag = 1;
    while((nPos = html.find("#comment",n)) != -1)
    {
        n = nPos+1;
        int nStartPos = html.rfind("/",nPos);
        string strUrl = html.substr(nStartPos+1,nPos - nStartPos -1);
        DownResourceInfo info;
        info.strResourceCurl = strUrl;
        //获取资源的名字
        nStartPos = html.find(strUrl,nPos+1);
        if(nStartPos == -1)
            return vtDownload;
        nStartPos += 2;
        nStartPos += strUrl.length();
        int nEndPos = html.find("</a>",nStartPos);
        string ResourceName = html.substr(nStartPos,nEndPos - nStartPos);
        info.strResourceName = ResourceName;        
        vtDownload.push_back(info);
    }
    return vtDownload;
}
复制代码

发表评论

复制代码
static BOOL AddComment(string sourceId)
{
    CURL *easy_handle;
    CURLcode res;
    string content;
    curl_global_init(CURL_GLOBAL_ALL);
    easy_handle = curl_easy_init();
    if( easy_handle )
    {
        //初始化cookie引擎
        curl_easy_setopt(easy_handle, CURLOPT_COOKIEFILE,"");        
        curl_easy_setopt(easy_handle,CURLOPT_FOLLOWLOCATION, 1L);        
        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";
        string referer = "Referer: http://download.csdn.net/detail/wasdzxce/"+sourceId;
        //http请求头
        struct curl_slist *headers = NULL;        
        headers = curl_slist_append(headers,"Host: download.csdn.net");
        headers = curl_slist_append(headers,"User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:25.0) Gecko/20100101 Firefox/25.0");
        headers = curl_slist_append(headers,"Accept: text/javascript, application/javascript, */*");
        headers = curl_slist_append(headers,"Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3");
        headers = curl_slist_append(headers,"Accept-Encoding: gzip, deflate");
        headers = curl_slist_append(headers,"Content-Type: application/x-www-form-urlencoded");
        headers = curl_slist_append(headers,"X-Requested-With: XMLHttpRequest");
        headers = curl_slist_append(headers,referer.c_str());
        headers = curl_slist_append(headers,"Connection: keep-alive");
        curl_easy_setopt(easy_handle, CURLOPT_HTTPHEADER, headers);
        curl_easy_setopt(easy_handle, CURLOPT_COOKIEFILE, "cookie.txt");        //读取本地存储的cookie 

        if(!InitCurl(easy_handle,res,url,content))
        {
            //释放资源
            curl_slist_free_all(headers);
            curl_easy_cleanup(easy_handle);
            curl_global_cleanup();
            return FALSE;
        }
        //释放资源
        curl_slist_free_all(headers);
        curl_easy_cleanup(easy_handle);
    }
    curl_global_cleanup();
    int pos = content.find("\"succ\":1");
    if (pos>=0)
        return TRUE;
    else
        return FALSE;
}
复制代码
目录
相关文章
|
6月前
|
开发工具 Android开发
【uniapp】sigmob广告加载失败:-5005、500422没有imei的解决办法(原创可用)
【uniapp】sigmob广告加载失败:-5005、500422没有imei的解决办法(原创可用)
|
2月前
|
小程序 开发者
【经验分享】支付宝小程序如何获取外部链接携带的参数
【经验分享】支付宝小程序如何获取外部链接携带的参数
61 1
|
4月前
|
Java Windows Spring
IDEA中报错:因为在此系统上禁止运行脚本有关详细信息,请参阅...(图文解释 亲测已解决)
IDEA中报错:因为在此系统上禁止运行脚本有关详细信息,请参阅...(图文解释 亲测已解决)
56 0
|
8月前
|
数据采集 Python
python自动签到参考网站
python自动签到参考网站
|
C++
VS平台的基本设置以及相关报错问题解决方法
在刚开始学习编程后,期间总会遇到问题,以前都是记录下来没有整理。现在积少成多,也乘着有空就在这里给整理一下。
130 0
|
小程序 Android开发
(成功最详细版本,自定义传参失败,跳转出现空白页面,校验文件失败)微信小程序扫码跳转小程序指定页面保姆级教程
文档里面虽然说了,但是还是有几个坑的地方,坑等文章最后面再写扫普通链接二维码打开小程序 | 微信开放文档
246 0
(成功最详细版本,自定义传参失败,跳转出现空白页面,校验文件失败)微信小程序扫码跳转小程序指定页面保姆级教程
|
安全 CDN
github,codeforces访问过慢处理方法(涉及权限)
更新:最近发现下列配置已经失效,但是github的访问速度明显快乐很多,所以不需要哦配置,如果找到正确的网站或者其他网站访问慢可以按照相同的方法。另外。我之前的始用权限问题比较麻烦,可以直接右击属性安全中设置应用程序的权限可以修改内容(记得改回去,万一被黑了然后黑客把你的hosts文件链向黄网?)
794 0
github,codeforces访问过慢处理方法(涉及权限)
|
数据采集 JSON JavaScript
新浪短网址接口源码,并使用PHP模拟登陆来自动更新
新浪短网址接口源码,并使用PHP模拟登陆来自动更新
121 0
|
小程序 程序员 数据库
Web网站扫【小程序码】登录的技术实现!记得收藏,要用时别找不到!
我准备给彩虹屁老婆插件开发一个皮肤/模型下载网站,里面需要具备用户系统。但我又懒得去完整开发一套注册,用户激活机制。 不过当时我的第一反应是可以利用微信公众号的扫码登录,但公众号的扫码登录接口必须得是服务号才可以使用。服务号的注册又必须使用营业执照走企业认证,总之比较麻烦。恰好当时我的小程序猿创聚合助手已经发布了,所以我就在思考,能否直接利用小程序码的接口来自己设计一套扫码登录流程呢?
459 0
Web网站扫【小程序码】登录的技术实现!记得收藏,要用时别找不到!
python接口自动化3-自动发帖(session)
前言 上一篇模拟登录博客园,但这只是第一步,一般登录后,还会有其它的操作,如发帖,评论等,这时候如何保持会话呢?  (敲黑板!!!由于博客园最近登录机制变了,登录全部走cookie登录) 一、session简介 1.
1501 0