libcurl 重定向url:
301 永久重定向
:请求的网页已被永久移动到新位置。服务器返回此响应时,会自动将请求者转到新位置。搜索引擎会将已收录的链接变为重定向之后的链接,权重也会转移到新的链接。302 临时重定向
:服务器目前正从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。搜索引擎将继续保持展示已收录的链接。
获取重定向url有如下两种方法:
方法一: 通过Header
的Location:
获取
size_t HeaderCallback4Download(char *ptr,size_t size,size_t nmemb,void *userdata)
{
//通过Location:获取重定向url
CurlDownloadContext* dld_ctx = (CurlDownloadContext*)userdata;
const char key_loc[] = "Location:";
if (_strnicmp(ptr, key_loc, strlen(key_loc)) == 0)
{
dld_ctx->redirect_url.assign(ptr + strlen(key_loc));
//去掉\r\n
if (dld_ctx->redirect_url.size() > 2)
{
dld_ctx->redirect_url.resize(dld_ctx->redirect_url.size() - 2);
}
}
return size * nmemb;
}
//设置头部回调
::curl_easy_setopt(pcurl, CURLOPT_HEADERFUNCTION, HeaderCallback4Download);
::curl_easy_setopt(pcurl, CURLOPT_HEADERDATA, &dld_ctx);
方法二:通过CURLINFO_REDIRECT_URL获取
CURLcode ret = ::curl_easy_perform(pcurl);
//执行完成之后获取状态码和重定向url
if(ret == CURLE_OK)
{
long httpcode;
curl_easy_getinfo(pcurl, CURLINFO_RESPONSE_CODE, &httpcode);
if (httpcode == 301 || httpcode == 302)
{
char *redirect_url = NULL;
//1表示重定向次数,最多允许一次重定向
curl_easy_setopt(pcurl, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_getinfo(pcurl, CURLINFO_REDIRECT_URL, &redirect_url);
//if (redirect_url != nullptr)
curl_free(redirect_url);
}
}
完整测试demo:
struct CurlDownloadContext
{
std::string redirect_url;
CurlDownloadContext()
{
}
~CurlDownloadContext()
{
}
};
size_t HeaderCallback4Download(char *ptr,size_t size,size_t nmemb,void *userdata)
{
//通过Location:获取重定向url
CurlDownloadContext* dld_ctx = (CurlDownloadContext*)userdata;
const char key_loc[] = "Location:";
if (_strnicmp(ptr, key_loc, strlen(key_loc)) == 0)
{
dld_ctx->redirect_url.assign(ptr + strlen(key_loc));
//去掉\r\n
if (dld_ctx->redirect_url.size() > 2)
{
dld_ctx->redirect_url.resize(dld_ctx->redirect_url.size() - 2);
}
}
return size * nmemb;
}
int _tmain(int argc, _TCHAR* argv[])
{
curl_global_init(CURL_GLOBAL_ALL);
CURL *pcurl = curl_easy_init();
CurlDownloadContext dld_ctx;
::curl_easy_setopt(pcurl, CURLOPT_URL, "http://weibo.com/");
::curl_easy_setopt(pcurl, CURLOPT_HTTPGET, 1L);
::curl_easy_setopt(pcurl, CURLOPT_CONNECTTIMEOUT, 30000L);
::curl_easy_setopt(pcurl, CURLOPT_LOW_SPEED_TIME, 1800L);
::curl_easy_setopt(pcurl, CURLOPT_LOW_SPEED_LIMIT, 10L);
::curl_easy_setopt(pcurl, CURLOPT_SSL_VERIFYPEER, 0L);
::curl_easy_setopt(pcurl, CURLOPT_SSL_VERIFYHOST, 0L);
::curl_easy_setopt(pcurl, CURLOPT_NOSIGNAL, 1L);
::curl_easy_setopt(pcurl, CURLOPT_HEADERFUNCTION, HeaderCallback4Download);
::curl_easy_setopt(pcurl, CURLOPT_HEADERDATA, &dld_ctx);
//::curl_easy_setopt(pcurl, CURLOPT_WRITEFUNCTION, WriteCallback4Download);
//::curl_easy_setopt(pcurl, CURLOPT_WRITEDATA, &dld_ctx);
CURLcode ret = ::curl_easy_perform(pcurl);
long httpcode;
curl_easy_getinfo(pcurl, CURLINFO_RESPONSE_CODE, &httpcode);
if (httpcode == 301 || httpcode == 302)
{
char *redirect_url = NULL;
//1表示重定向次数,最多允许一次重定向
curl_easy_setopt(pcurl, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_getinfo(pcurl, CURLINFO_REDIRECT_URL, &redirect_url);
//if (redirect_url != nullptr)
curl_free(redirect_url);
}
curl_global_cleanup();
return 0;
}