用libcurl 登录网站
libcurl 可以发送和接收HTTP消息,因此可以发送用户名、密码和验证码来登录网站,网上有不少这方面的内容,但不甚完整,我摸索了两天,将其中要点记录下来。
基本步骤
- 正常访问登录页面,访问时,设置CURL参数,指定COOKIE文件。
- 获取验证码的图片。
- 发送用户名,密码和验证码(附加上第一次访问时指定的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 选项。
自由软件开发者。承接图像处理,视频智能算法,GIS,三维仿真等方面的工程项目。联系方式 QQ or wechat: 714601476。

浙公网安备 33010602011771号