libcurl 庫訪問百度

libcurl 簡介:

libcurl 是一個跨平臺的網絡協議庫,支持 http, https, ftp, gopher, telnet, dict, file, 和 ldap 協議。libcurl 同樣支持 HTTPS 證書授權,HTTP POST, HTTP PUT, FTP 上傳, HTTP 基本表單上傳,代理,cookies, 和用戶認證。libcurl 的官網 、庫下載。這種庫使用的時候就像使用 wiringPi 庫一樣,編寫完代碼需要鏈接這個庫,所以要先下載這個庫。

libcurl 等第三方庫的通用編譯方法:

在這裏插入圖片描述

調用 libcurl 庫訪問百度

**調用 libcurl 庫訪問百度主頁並將數據保存到文件中:**程序代碼:

#include <stdio.h>
#include <curl/curl.h>

#define true 1
#define false 0
typedef unsigned int bool;

bool getUrl(char *filename)
{
    CURL *curl;
    CURLcode res;
    FILE *fp;
    if ((fp = fopen(filename, "w")) == NULL)  // 返回結果用文件存儲
        return false;
    struct curl_slist *headers = NULL;
    headers = curl_slist_append(headers, "Accept: Agent-007");
    curl = curl_easy_init();    // 初始化
    if (curl)
    {
        //curl_easy_setopt(curl, CURLOPT_PROXY, "10.99.60.201:8080");// 代理
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);// 改協議頭
        curl_easy_setopt(curl, CURLOPT_URL,"http://www.baidu.com");
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); //將返回的http頭輸出到fp指向的文件
        curl_easy_setopt(curl, CURLOPT_HEADERDATA, fp); //將返回的html主體數據輸出到fp指向的文件
        res = curl_easy_perform(curl);   // 執行
        if (res != 0) {

            curl_slist_free_all(headers);
            curl_easy_cleanup(curl);
        }
        fclose(fp);
        return true;
    }
}
bool postUrl(char *filename)
{
    CURL *curl;
    CURLcode res;
    FILE *fp;
    if ((fp = fopen(filename, "w")) == NULL)
        return false;
    curl = curl_easy_init();
    if (curl)
    {
        curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "/tmp/cookie.txt"); // 指定cookie文件
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "&logintype=uid&u=xieyan&psw=xxx86");    // 指定post內容
        //curl_easy_setopt(curl, CURLOPT_PROXY, "10.99.60.201:8080");
        curl_easy_setopt(curl, CURLOPT_URL, " http://mail.sina.com.cn/cgi-bin/login.cgi ");   // 指定url
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
        res = curl_easy_perform(curl);
        curl_easy_cleanup(curl);
    }
    fclose(fp);
    return true;
}
int main(void)
{
    getUrl("/tmp/get.html");
    postUrl("/tmp/post.html");
}

大概解讀代碼:要用一個是getUrl,一個是postUrl,用 getpost 兩種方法來請求的一個網頁。getUrl,我們來看一下,是自己封裝的這個函數,fopen這個函數去打開了一個文件,放在 fp 這個流裏面。然後curl_easy_init去做初始化,去初始化我們的 curl 引擎,初始化成功以後curl_easy_setopt去設置 curl 相關的項, 包括我們要訪問的 IP 地址等等,還有一個CURLOPT_WRITEDATA。訪問成功數據返回以後呢會把數據流導入到這個filename這個文件裏面,那filename文件是哪裏呢?在/tmp/get.html。這文件如果沒有的話,他這邊fp = fopen(filename, "w")應該會創建啊,去回顧一下文件相關的操作。然後將返回的 html主體數據輸出到fp指向的文件百度的訪問的所有結果往文件裏面去寫,然後curl_easy_perform執行就是在訪問百度,如果res != 0,這個 res 不等於零是啥意思呢?我們去回顧一下之前提到的這個進行 http 請求以後的一個返回值,如果請求成功以後啊,我們去釋放這相關的curl的這個句柄。並且關閉這個文件,return true;訪問成功,這個是相關的步驟

通過以上設置然後再執行程序:可以看到/tmp/get.html這個文件夾裏面有從百度網頁獲取的 html 代碼:

libcurl 庫函數介紹:

curl_global_init(long flags) 函數:

  • libcurl 的使用(其實和 socket 編程時一樣,都需要一定的步驟):
  1. 調用 curl_global_init() 初始化 libcurl,(就像初始化套接字)

  2. 調用 curl_easy_init() 函數得到 easy interface 型指針(這個指針用來各種配置)

  3. 調用 curl_easy_setopt() 設置傳輸選項(通過調 curl_easy_setopt 這個函數來對指針進行各種配置,比如:請求的方式)

  4. 根據 curl_easy_setopt() 設置的傳輸選項,實現回調函數以完成用戶特定任務

  5. 調用 curl_easy_perform() 函數進行訪問請求

  6. 調用 curl_easy_cleanup() 釋放內存

函數簡介

CURLcode curl_global_init(long flags)功能:初始化 libcurl 這個函數只能用一次。(其實在調用 curl_global_cleanup 函數後仍然可再用) 如果這個函數在 curl_easy_init 函數調用時還沒調用它將由 libcurl 庫自動調用所以多線程下最好主動調用該函數以防止在線程中 curl_easy_init 時多次調用。

注意:雖然 libcurl 是線程安全的,但 curl_global_init 是不能保證線程安全的, 所以不要在每個線程中都調用 curl_global_init,應該將該函數的調用放在主線程中。

參數:flags
CURL_GLOBAL_ALL                      //初始化所有的可能的調用。
CURL_GLOBAL_SSL                      //初始化支持 安全套接字層。
CURL_GLOBAL_WIN32            //初始化win32套接字庫。
CURL_GLOBAL_NOTHING         //沒有額外的初始化。
  • CURLcode curl_easy_setopt(CURL * handle, CURLoption option,parameter)函數:

  • 這個函數最重要了. 幾乎所有的 curl 程序都要頻繁的使用它. 它告訴 curl 庫. 程序將有如何的行爲. 比如要查看一個網頁的 html 代碼等.(這個函數有些像 ioctl 函數)


參數:

  1. CURL 類型的指針

  2. 各種 CURLoption 類型的選項.(都在 curl.h 庫裏有定義, man 也可以查看到)

  3. parameter 這個參數 既可以是個函數的指針, 也可以是某個對象的指針, 也可以是個 long 型的變量. 它用什麼這取決於第二個參數. CURLoption 這個參數的取值很多. 具體的可以查看 man 手冊.

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/I1Iut-twZo_Wg2QowuFaIA