如何在C++中获取重定向网页的URL

How to obtain the URL of re-directed webpage in C++

本文关键字:重定向 网页 URL 获取 C++      更新时间:2023-10-16

我确实编写了一个 c++ 代码,它会自动解析网页并打开并解析它们的一些链接。关键是,在这些网页中,有一些地址被重定向到其他网页。例如,当我尝试打开时:

https://atlas.immobilienscout24.de/property-by-address?districtId=1276001006014

我最终打开了:

https://atlas.immobilienscout24.de/orte/deutschland/baden-württemberg/böblingen-kreis/leonberg

如何在C++中获取第二页的网址?

在这种特殊情况下,它由 301("永久移动"(响应中的Location标头给出(根据 Chrome 的开发者工具(。

如果将FOLLOWLOCATION设置为0,则可以阻止 libcurl 跟踪重定向,然后只检查原始响应的标头(或者,更好的是,查询REDIRECT_URL以获取信息(。

(然后,您可以根据需要对备用 URL 执行新请求。

默认设置是0,但是,您必须将其设置为当前自己1

您可以使用CURLOPT_HEADERFUNCTION来检查标头并解析出Location标头,例如

#include <iostream>
#include <cstring>
#include <curl/curl.h>
size_t header_callback(char *buffer,   size_t size,   size_t nitems,   void *userdata){
const std::string needle="Location: ";
if(nitems>needle.size()){
if(std::memcmp(&needle[0],buffer,needle.size()) == 0 ){
//todo: verify that im not off-by-one below.
((std::string*)userdata)->assign(&buffer[needle.size()],nitems-needle.size());
}
}
return nitems;
}
int main(int argc, char *argv[])
{
CURLcode ret;
CURL *hnd = curl_easy_init();
curl_easy_setopt(hnd, CURLOPT_URL, "https://atlas.immobilienscout24.de/property-by-address?districtId=1276001006014");
curl_easy_setopt(hnd, CURLOPT_NOPROGRESS, 1L);
curl_easy_setopt(hnd, CURLOPT_NOBODY, 1L);
std::string redirect_url;
curl_easy_setopt(hnd,CURLOPT_HEADERDATA,&redirect_url);
curl_easy_setopt(hnd,CURLOPT_HEADERFUNCTION,header_callback);
ret = curl_easy_perform(hnd);
curl_easy_cleanup(hnd);
hnd = NULL;
std::cout << redirect_url;
return (int)ret;
}

但是如果你想要最终的网址(在多次重定向的情况下(,而不仅仅是"第二个网址",你可能应该使用CURLOPT_FOLLOWLOCATION和CURLINFO_EFFECTIVE_URL代替,例如

#include <iostream>
#include <cstring>
#include <curl/curl.h>
int main(int argc, char *argv[])
{
CURLcode ret;
CURL *hnd = curl_easy_init();
curl_easy_setopt(hnd, CURLOPT_URL, "https://atlas.immobilienscout24.de/property-by-address?districtId=1276001006014");
curl_easy_setopt(hnd, CURLOPT_NOPROGRESS, 1L);
curl_easy_setopt(hnd, CURLOPT_NOBODY, 1L);
curl_easy_setopt(hnd,CURLOPT_FOLLOWLOCATION,1L);
ret = curl_easy_perform(hnd);
char *lolc;
curl_easy_getinfo(hnd, CURLINFO_EFFECTIVE_URL, &lolc);
std::string final_url(lolc);
curl_easy_cleanup(hnd);
hnd = NULL;
std::cout << final_url;
return (int)ret;
}

这种方法较慢(重定向时必须至少再执行 1 个请求(,但实现起来要简单得多,并且适用于重定向的 URL 和非重定向的 URL 以及多次重定向的 URL。