【问题标题】:How do I fetch a HTML page source with libcurl in C如何在 C 中使用 libcurl 获取 HTML 页面源
【发布时间】:2011-04-02 20:19:19
【问题描述】:

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

任何帮助将不胜感激。

【问题讨论】:

    标签: c curl libcurl


    【解决方案1】:

    您很可能希望使用 CURLOPT_WRITEFUNCTION 选项调用 curl_easy_setopt。这允许您使用此原型提供函数:

    size_t function( void *ptr, size_t size, size_t nmemb, void *userdata);
    

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

    编辑:这是我曾经为 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;
    }
    

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

    curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, curl_to_string);
    curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, &pagedata);
    

    其中pagedatastd::string。调用curl_easy_perform后,如果没有错误,pagedata就有你的页面了。

    编辑 2: C 版本稍微复杂一些,主要是因为我们必须管理内存以适应传入的数据。 (像 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;
    }
    

    它基本上是 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);
    

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

    【讨论】:

    • 您有机会提供一些 C 语言示例代码吗?
    • 也许吧。 ;-) 它在上面。就个人而言,对于类似的事情,我发现 C++ 更适合,因为我不必处理内存管理。
    • 感谢您的 C++ 示例,我已经解决了所有问题,但是我无法修复以下错误:“错误:无效使用成员(您忘记了 '&' 吗?)”这是针对“curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, curl_to_string);”这一行的,你对它可能是什么有什么建议吗?
    【解决方案2】:

    巧合的是,curl 网站提供了一个正好针对这个问题的示例:

    http://curl.haxx.se/libcurl/c/getinmemory.html

    【讨论】:

      【解决方案3】:

      如果我没记错的话,您需要使用 curl_easy_setopt 设置 CURLOPT_WRITEFUNCTION 和 CURLOPT_WRITEDATA 以便处理接收到的数据

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-06
        • 2011-08-26
        • 2017-12-31
        • 1970-01-01
        • 1970-01-01
        • 2010-11-24
        相关资源
        最近更新 更多