用libcurl 登录网站

libcurl 可以发送和接收HTTP消息,因此可以发送用户名、密码和验证码来登录网站,网上有不少这方面的内容,但不甚完整,我摸索了两天,将其中要点记录下来。

基本步骤 

  1. 正常访问登录页面,访问时,设置CURL参数,指定COOKIE文件。
  2. 获取验证码的图片。
  3. 发送用户名,密码和验证码(附加上第一次访问时指定的COOKIE)。
 /*首次访问页面,指定COOKIE文件,因为我们后面发送登录的账户和密码时,需要这个COOKIE*/
1
void accessFirstTime(){ 2 void* curl = curl_easy_init(); 3 curl_easy_setopt(curl, CURLOPT_URL, POSTURL); 4 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); 5 curl_easy_setopt(curl, CURLOPT_WRITEDATA, 0); 6 curl_easy_setopt(curl, CURLOPT_VERBOSE,1); 7 curl_easy_setopt(curl, CURLOPT_COOKIEJAR, "D:/dearTony/t1.cookie"); 8 curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,false);//设定为不验证证书和HOST 9 curl_easy_setopt(curl,CURLOPT_SSL_VERIFYHOST,false); 10 CURLcode res = curl_easy_perform(curl); 11 curl_easy_cleanup(curl); 12 return; 13 }

上面代码中,line 3, POSTURL 是需要访问得登录页面地址。 特别要注意的是,line 7, 8, 9 第七行告诉libcurl 将服务器发送过来的COOKIE存在哪个文件, 8,9行告诉服务器不需要SSL验证。

 

 1 /*将图片存盘*/
 2 size_t downImage(void *buffer, size_t size, size_t nmemb, void *userp){
 3     FILE *fp = fopen("d:/dearTony/validateImg","wb");
 4     fwrite(buffer,size, nmemb, fp);
 5     fclose(fp);
 6     return true;
 7 }
 8 
 9 
10 /*获取验证码*/ 
11 void getYZM(){
12     const char* targetUrl= "https://***.***.com/cgi-bin/img/validateimg"; //图片的URL
13     void* curl = curl_easy_init();  
14 
15     curl_easy_setopt(curl, CURLOPT_URL, targetUrl); 
16     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, downImage);  
17     curl_easy_setopt(curl, CURLOPT_WRITEDATA, 0);  
18     curl_easy_setopt(curl, CURLOPT_VERBOSE,1);    
19     curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "D:/dearTony/t1.cookie");  
20     curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER,0);//设定为不验证证书和HOST
21     curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST,0);
22 
23     CURLcode res = curl_easy_perform(curl);  
24     curl_easy_cleanup(curl);  
25     return;
26 }

注意line 19,20,21  , 如果不附加COOKIE,  则获取的验证图片内容不对。

 

最后,发送账户名,密码和验证码。

 1 #define POSTURL "https://***.***.com/cgi-bin/user/Login" 
 2 #define POSTFIELDS "fundAccount=28000000****&isSaveAccount=1&mac=&normalpassword=&\
 3 password=23c0d43c50972a7c6b927e61c52f15bd3d71c03e05ae9fce\
 4 fd8b7ac29d19b293c25d72c651756050c4e843e31de0c05b9bca6e8b547\
 5 9a90f5f1bb59818e0b983991b4259bbdd35d9ae423ef5602c8956bae122270f68908c229ca63a40114d4586c4bfcb90764&\
 6 password_Controls=normal&\
 7 retUrl=&ticket=%1&type=Z"
 8 
 9 /*登录,ticket是上一步取得的验证码*/
10 bool login(QString& ticket){
11     QString postf = QString(POSTFIELDS).arg(ticket);
12     std::string tstr = postf.toStdString();
13     void* curl = curl_easy_init();  
14     const char *postArg = tstr.c_str();
15     struct curl_slist *chunk = NULL;
16     chunk = curl_slist_append(chunk, "Accept: image/gif, image/jpeg, image/pjpeg, application/x-ms-application, application/xaml+xml, application/x-ms-xbap, application/msword, application/vnd.ms-powerpoint, application/vnd.ms-excel, */*");
17     chunk = curl_slist_append(chunk, "Accept-Encoding: text/plain"); 
18     chunk = curl_slist_append(chunk, "Accept-Language: zh-Hans-CN, zh-Hans; q=0.8, en-US; q=0.5, en; q=0.3");
19     chunk = curl_slist_append(chunk, "Connection: Keep-Alive"); 
20     chunk = curl_slist_append(chunk, "Cache-Control: no-cache"); 
21     chunk = curl_slist_append(chunk, "Host: ***.***.com"); 
22     chunk = curl_slist_append(chunk, "Content-Type: application/x-www-form-urlencoded"); 
23     chunk = curl_slist_append(chunk, "Referer: https://***.***.com/cgi-bin/user/Login"); 
24     chunk = curl_slist_append(chunk, "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729)");
25 
26     curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);   
27     curl_easy_setopt(curl, CURLOPT_URL, POSTURL); 
28     curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postArg);    /*POST的参数,通过F12抓包得到*/
29     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);  
30     curl_easy_setopt(curl, CURLOPT_WRITEDATA, 0);  
31     curl_easy_setopt(curl, CURLOPT_POST, 1);    /*表明是POST方法*/
32     curl_easy_setopt(curl, CURLOPT_VERBOSE,1);    
33     curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "D:/dearTony/t1.cookie");  //一定要带上  
34     curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER,0);//设定为不验证证书和HOST
35     curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST,0);
36 
37     int response_code = 0;
38     CURLcode res = curl_easy_perform(curl);  
39     curl_easy_cleanup(curl);  
40     curl_slist_free_all(chunk);
41     return true;
42 }

line15~24是HTTP头,可以用浏览器的F12功能抓包得到。


总结: 一定要注意COOKIE选择和 SSL 选项。

posted @ 2016-12-20 09:41  小阳明  阅读(2925)  评论(0)    收藏  举报