如何在 C 中使用 libcurl 获取 HTML 页面源代码

Jam*_*den 2 c curl libcurl

我尝试查看 libcurl 网站上的简单示例,该示例位于以下网址:http : //curl.haxx.se/libcurl/c/simple.html,但是我还没有弄清楚如何做我需要的,这是将页面的源存储在一个字符串变量中。

任何帮助将不胜感激。

Tha*_*tos 5

您很可能想curl_easy_setopt使用 CURLOPT_WRITEFUNCTION 选项调用。这允许您提供具有此原型的函数:

size_t function( void *ptr, size_t size, size_t nmemb, void *userdata);
Run Code Online (Sandbox Code Playgroud)

有数据时哪个 curl 会调用。然后,您可以使用userdata参数传递指向 a std::string(如果在 C++ 中)或char **在 C中的 a 的指针,这允许您将数据保存到内存中。或者,您可以直接处理传入的数据,而无需完全存储它。

编辑:这是我从前为 C++ 编写的这样一个函数(它使用std::string)这是我的代码,但如果您需要许可信息,它是公共领域 - 用它做任何你想做的事。:-)

size_t curl_to_string(void *ptr, size_t size, size_t nmemb, void *data)
{
    std::string *str = (std::string *) data;
    char *sptr = (char *) ptr;
    int x;

    for(x = 0; x < size * nmemb; ++x)
    {
        (*str) += ptr[x];
    }

    return size * nmemb;
}
Run Code Online (Sandbox Code Playgroud)

可能应该使用 C++ 风格的强制转换,但那时我还是一个年轻的程序员。:-) 你会像上面一样使用:

curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, curl_to_string);
curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, &pagedata);
Run Code Online (Sandbox Code Playgroud)

哪里pagedatastd::string. 调用 后curl_easy_perform,如果没有错误,就会显示pagedata您的页面。

编辑 2: 这个的 AC 版本稍微复杂一些,主要是因为我们必须管理内存以适应传入的数据。(有什么事情喜欢std::stringstd::vector我们用C ++做...)

typedef struct
{
    size_t size;
    size_t allocated;
    char *data;
} c_vector;

size_t curl_to_string(void *ptr, size_t size, size_t nmemb, void *data)
{
    if(size * nmemb == 0)
        return 0;

    c_vector *vec = (c_vector *) data;

    // Resize the data array if needed
    if(vec->size + size * nmemb > allocated)
    {
        char *new_data = realloc(vec->data, sizeof(char) * (vec->size + size * nmemb));
        if(!new_data)
            return 0;
        vec->data = new_data;
        vec->allocated = vec->size + size * nmemb;
    }

    memcpy(vec->data + vec->size, ptr, size * nmemb);
    vec->size += size * nmemb;

    return size * nmemb;
}
Run Code Online (Sandbox Code Playgroud)

它基本上是 C++ 的std::vector,归结为 C。(这就是为什么我默认是 C++ 程序员而不是 C...)

你会这样称呼,

c_vector vec = {0};

curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, curl_to_string);
curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, &pagedata);
Run Code Online (Sandbox Code Playgroud)

谨防上述代码中的错误;我只是证明它是正确的,没有尝试过。