Curl使用问题

来源:互联网 发布:淘宝联盟看不到高佣金 编辑:程序博客网 时间:2024/05/19 03:26
在进行网页抓取和模拟登陆的开发,curl必须是首选的工具,由于它强大的功能,也提供了多个平台的支持。最近使用curl进行模拟登陆https网站,遇到了一些问题,问题的真相真是不好找,因为本身对网络方面的东西也不太熟悉,后来经过调试,还是找到原因了。

curl下载:http://curl.haxx.se/download.html

官网提供了多个平台的软件和动态库的下载,这里我使用Qt开发,所以使用了Windows平台下的mingw编译版本:http://curl.haxx.se/gknw.net/7.28.1/dist-w32/curl-7.28.1-devel-mingw32.zip


解压出来,可以看到include、lib、bin等目录,编译的时候,使用bin目录下的dll动态库,包含include头文件,即可完成编译和使用。该版本支持ssl,可以访问https的网站。
另外帮助文档的问题,可以下载curl源码,里面就有提供完整的文档,很详细,如果要使用curl开发,使用里面的文档已经非常清楚。

我遇到以下几个问题:
1.curl登陆https网站失败(最终确认是url编码与socket长连接的问题。)
2.获取的网页源码与浏览器访问的源码有点区别

1.
登陆https网站,在不使用证书的情况下,要设置:

curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYHOST, 0L);curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYPEER, 0L);

2.curl抓取的网页代码与浏览器打开的不一致,这主要是user-agent的设置问题,如果一定要使用浏览器的格式,那么可以直接将某个浏览器的user-agent的值拿来使用,这样就模仿浏览器访问网页了。我这里使用的是火狐浏览器的user-agent:
curl_easy_setopt(m_pCurl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 5.1; rv:17.0) Gecko/20100101 Firefox/17.0");


3.url编码
如果是post操作,那么提交的的表单域要转换成url编码,有些人不熟悉url编码,其实只是把某些特殊的字符转换成通用的格式。
比如:'='转换成"%3D"
如果函数库没有提供,可以自己根据url编码表写一个转换函数。

4.长连接

用户可以在curl默认的http头添加或修改自己想要的选项,我这里要添加长连接选项:Connection: keep-alive:

struct curl_slist *list;list = curl_slist_append(list, "Connection: keep-alive");curl_easy_setopt(m_pCurl, CURLOPT_HTTPHEADER, list);

设置到CURLOPT_HTTPHEADER中,即可添加进去。

5.在curl遇到奇怪的问题,最好要打开调试选项,而且可以结合火狐浏览器的httpfox插件

curl_easy_setopt(m_pCurl, CURLOPT_DEBUGFUNCTION, CurlDebug);//打印完整的调试信息curl_easy_setopt(m_pCurl, CURLOPT_VERBOSE, 1);//打印调试信息

6.在这里分享一个现成的curl的post操作:

bool CCurl::Post(const QString &actionUrl, const QString &fieldsInfo, QString &htmlStr){    CURLcode code;struct curl_slist *list;list = curl_slist_append(list, "Connection: keep-alive");    curl_easy_setopt(m_pCurl, CURLOPT_URL, actionUrl.toLatin1().data());    curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYHOST, 0L);    curl_easy_setopt(m_pCurl, CURLOPT_SSL_VERIFYPEER, 0L);    curl_easy_setopt(m_pCurl, CURLOPT_COOKIEJAR, m_CookiesFileName.toAscii().data());    curl_easy_setopt(m_pCurl, CURLOPT_COOKIEFILE, m_CookiesFileName.toAscii().data());    curl_easy_setopt(m_pCurl, CURLOPT_WRITEFUNCTION, WriteToMem);    curl_easy_setopt(m_pCurl, CURLOPT_WRITEDATA, &htmlStr);    curl_easy_setopt(m_pCurl, CURLOPT_POSTFIELDS, fieldsInfo.toLatin1().data());    curl_easy_setopt(m_pCurl, CURLOPT_POST, 1L);    curl_easy_setopt(m_pCurl, CURLOPT_FOLLOWLOCATION, 1L);    curl_easy_setopt(m_pCurl, CURLOPT_HTTPHEADER, list);    curl_easy_setopt(m_pCurl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 5.1; rv:17.0) Gecko/20100101 Firefox/17.0");//curl_easy_setopt(m_pCurl, CURLOPT_DEBUGFUNCTION, CurlDebug);//打印完整的调试信息//curl_easy_setopt(m_pCurl, CURLOPT_VERBOSE, 1);//打印调试信息    code = curl_easy_perform(m_pCurl);    if (CURLE_OK != code)    {        qDebug() << "curl_easy_perform: " << curl_easy_strerror(code);        curl_slist_free_all(list);        return false;    }    curl_slist_free_all(list);    return true;}

7.调试函数可以这么写,这是在网上找到的:

int CCurl::CurlDebug(CURL *pcurl, curl_infotype itype, char * pData, size_t size, void *){    if(itype == CURLINFO_TEXT)    {        qDebug() << "[TEXT]:" << pData;    }    else if(itype == CURLINFO_HEADER_IN)    {        qDebug() << "[HEADER_IN]:" << pData;    }    else if(itype == CURLINFO_HEADER_OUT)    {        qDebug() << "[HEADER_OUT]:" << pData;    }    else if(itype == CURLINFO_DATA_IN)    {        qDebug() << "[DATA_IN]:" << pData;    }    else if(itype == CURLINFO_DATA_OUT)    {        qDebug() << "[DATA_OUT]:" << pData;    }    return 0;}


原创粉丝点击