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

基本步骤

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

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

 /*将图片存盘*/
size_t downImage(void *buffer, size_t size, size_t nmemb, void *userp){
FILE *fp = fopen("d:/dearTony/validateImg","wb");
fwrite(buffer,size, nmemb, fp);
fclose(fp);
return true;
} /*获取验证码*/
void getYZM(){
const char* targetUrl= "https://***.***.com/cgi-bin/img/validateimg"; //图片的URL
void* curl = curl_easy_init(); curl_easy_setopt(curl, CURLOPT_URL, targetUrl);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, downImage);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, );
curl_easy_setopt(curl, CURLOPT_VERBOSE,);
curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "D:/dearTony/t1.cookie");
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER,);//设定为不验证证书和HOST
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST,); CURLcode res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
return;
}

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

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

 #define POSTURL "https://***.***.com/cgi-bin/user/Login"
#define POSTFIELDS "fundAccount=28000000****&isSaveAccount=1&mac=&normalpassword=&\
password=23c0d43c50972a7c6b927e61c52f15bd3d71c03e05ae9fce\
fd8b7ac29d19b293c25d72c651756050c4e843e31de0c05b9bca6e8b547\
9a90f5f1bb59818e0b983991b4259bbdd35d9ae423ef5602c8956bae122270f68908c229ca63a40114d4586c4bfcb90764&\
password_Controls=normal&\
retUrl=&ticket=%&type=Z" /*登录,ticket是上一步取得的验证码*/
bool login(QString& ticket){
QString postf = QString(POSTFIELDS).arg(ticket);
std::string tstr = postf.toStdString();
void* curl = curl_easy_init();
const char *postArg = tstr.c_str();
struct curl_slist *chunk = NULL;
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, */*");
chunk = curl_slist_append(chunk, "Accept-Encoding: text/plain");
chunk = curl_slist_append(chunk, "Accept-Language: zh-Hans-CN, zh-Hans; q=0.8, en-US; q=0.5, en; q=0.3");
chunk = curl_slist_append(chunk, "Connection: Keep-Alive");
chunk = curl_slist_append(chunk, "Cache-Control: no-cache");
chunk = curl_slist_append(chunk, "Host: ***.***.com");
chunk = curl_slist_append(chunk, "Content-Type: application/x-www-form-urlencoded");
chunk = curl_slist_append(chunk, "Referer: https://***.***.com/cgi-bin/user/Login");
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)"); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
curl_easy_setopt(curl, CURLOPT_URL, POSTURL);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postArg); /*POST的参数,通过F12抓包得到*/
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, );
curl_easy_setopt(curl, CURLOPT_POST, ); /*表明是POST方法*/
curl_easy_setopt(curl, CURLOPT_VERBOSE,);
curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "D:/dearTony/t1.cookie"); //一定要带上
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER,);//设定为不验证证书和HOST
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST,); int response_code = ;
CURLcode res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
curl_slist_free_all(chunk);
return true;
}

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

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

用libcurl 登录网站的更多相关文章

  1. 用c#开发微信 (20) 微信登录网站 - 扫描二维码登录

    像京东,一号店等网站都实现了用微信来登录的功能,就是用手机上的微信扫一扫网站上的二维码,微信上确认后,即可自动用微信的帐号登录网站. 1 创建网站应用 在微信开放平台创建一个网站应用 https:// ...

  2. c#使用WebClient登录网站抓取登录后的网页

    C#登录网站实际上就是模拟浏览器提交表单,然后记录浏览器响应返回的会话Cookie值,再次发送请求时带着这个会话cookie值去请求就可以实现模拟登录的效果了. 如下类CookieAwareWebCl ...

  3. .NET C#使用微信公众号登录网站

    适用于:本文适用于有一定微信开发基础的用户 引言:花了300大洋申请了微信公众平台后,发现不能使用微信公众号登录网站(非微信打开)获得微信帐号.仔细研究后才发现还要再花300大洋申请微信开放平台才能接 ...

  4. Winform模拟post请求和get请求登录网站

    引言 最近有朋友问如何用winform模拟post请求,然后登录网站,稍微想了一下,大致就是对http报文的相关信息的封装,然后请求网站登录地址的样子.发现自己的博客中对这部分只是也没总结,就借着这股 ...

  5. Bing必应(Yahoo雅虎)搜索引擎登录网站 - Blog透视镜

    Bing必应是微软的搜索引擎,原本是置放在MSN网站上的,微软重新开发并改为新的名子,只要连到官网,登录网站后,过了不久,搜索引擎就会用爬虫,来检索你的网站,等过了一阵子之后,自然就可以找到你的文章. ...

  6. Google谷歌搜索引擎登录网站 - Blog透视镜

    建置好了网站之后,为了能提升流量或是增加曝光度,Mix通常会到Google谷歌,用手动登录的方式,登录网站,不久之后,搜索引擎就会派遣蜘蛛机器人,来检索你的网站,等一段时间之后,就会出现在搜索引擎内, ...

  7. jQuery异步请求模拟IE登录网站

    具体请求的登录验证页面后台逻辑处理,这里我们忽略,不在我们的学习范围内:关键的是使用jQuery异步请求方法,如下例子: <%@ Page Language="C#" Aut ...

  8. python网络爬虫之使用scrapy自动登录网站

    前面曾经介绍过requests实现自动登录的方法.这里介绍下使用scrapy如何实现自动登录.还是以csdn网站为例. Scrapy使用FormRequest来登录并递交数据给服务器.只是带有额外的f ...

  9. Java 扫描微信公众号二维码,关注并自动登录网站

    https://blog.csdn.net/qq_42851002/article/details/81327770 场景:用户扫描微信公众号的二维码,关注后自动登录网站,若已关注则直接登录. 逻辑: ...

随机推荐

  1. Be a new gentlemen

    学好技术的同时,更要注重自身素养的提升! 一  .有则改之,无责加冕 1.女士优先 2. 不随地吐痰, 不乱扔垃圾, 不在人群中抽烟 3. 不大声喧哗 4. 不插队,碰到别人要说抱歉 5. 不在公共交 ...

  2. Java终止线程

    Thread提供了stop()方法终止线程,但是该方法是强行终止,容易产生一些错误,已经被废弃. 可以使用退出标志来终止线程,在run()函数里面设置while循环,把退出标志作为while的条件,当 ...

  3. MVC Request.IsAuthenticated一直false Request.Cookie获取不到cookie

    项目中,在做登录验证时,用到了cookie,同一账户登陆,可以.切换其他账号时,就在也登录不上了,用原来的也不行.检查Request.IsAuthenticated一直false,而且Request. ...

  4. 1.JAVA基础复习——计算机基础与环境变量配置

    软件开发的了解 软件开发: 软件:一系列按照特定组织的计算机数据和指令的集合. 开发:制作软件. 程序:一系列有序指令的集合. 人机交互 人机交互的方式有两种:图形化界面和命令行方式. 图形化界面:简 ...

  5. CSS3 @font-face的使用

    首先我们一起来看看@font-face的语法规则: @font-face { font-family: <YourWebFontName>; src: <source> [&l ...

  6. android环境下的即时通讯

    首先了解一下即时通信的概念.通过消息通道 传输消息对象,一个账号发往另外一账号,只要账号在线,可以即时获取到消息,这就是最简单的即使通讯.消息通道可由TCP/IP UDP实现.通俗讲就是把一个人要发送 ...

  7. Looper.prepare()和Looper.loop()

    什么时候需要 Looper Looper用于封装了android线程中的消息循环,默认情况下一个线程是不存在消息循环(message loop)的,需要调用Looper.prepare()来给线程创建 ...

  8. ListView之点击展开菜单

    一.概述 ListView点击item显示菜单是要实现这样的效果: 需要实现的逻辑如下: 1)点击一个普通item,展开当前菜单,同时关闭其他菜单 2)点击一个已展开的菜单,隐藏当前菜单 3)将展开菜 ...

  9. 【代码笔记】iOS-获得现在的日期

    一,代码. - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, ...

  10. SVN为什么比Git更好

    首先我表明一个根本的立场,我个人更喜欢用Git,但是,这仅仅是一个个人偏好.当我们需要将一种技术方案带给整个团队的时候,并不是由我们的个人偏好作为主要决定因素,而应该充分去权衡利弊,选择对团队,对公司 ...