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 庫
-
下載完成後通過共享文件夾或者 FileZill 或者直接拖拽將壓縮包移動到虛擬機。我這裏將壓縮包拖拽至虛擬機的共享文件夾,然後使用指令:
cp /mnt/hgfs/sharefile/curl-7.71.1.tar.bz2 .
將壓縮包拷貝到我新建的 httpHandler 這個文件夾裏面,然後使用指令:tar vxf curl-7.71.1.tar.bz2
解壓這個文件夾,解壓後進入文件夾,如下圖所示(之後用到的開源的庫基本都是這樣的,內容形式差不多): -
那麼如何使用這種開源的壓縮包呢?這個文件夾下面有一個 README 文件夾,裏面有對庫的一些說明,如下圖所示,由下圖可知,我們使用 libcurl 庫時可以查看 curl.1 手冊或者 MANUAL document 這個手冊
-
這裏我用有道翻譯將這些英文進行了簡單地翻譯:
自述:Curl 是一個命令行工具,用於傳輸由 URL(網址)指定的數據語法。通過閱讀 curl 瞭解如何使用 curl。手冊頁或手冊文檔。通過閱讀 install 瞭解如何安裝 Curl 文檔。Libcurl 是 curl 用來完成其工作的庫。它很容易可被您的軟件使用。閱讀 libcurl。3 手冊頁學習如何! 你可以在 FAQ 文檔中找到最常見問題的答案。研究 copy 文件中的分發條款和類似條款。如果你分配 Curl 二進制文件或其他涉及 libcurl 的二進制文件,您可能會喜歡 LICENSE-MIXING 文檔。所有這些文檔以及更多文檔都可以在 docs / 目錄中找到。聯繫:如果您有問題、疑問、想法或建議,請與我們聯繫通過郵寄到一個合適的郵寄名單。參見 http//curl.haxx.se/mail / 該項目的所有貢獻者都列在 THANKS 文檔中。網站:訪問 curl 網站獲取最新消息和下載: https://curl.haxx.se/,GIT:要從 GIT 服務器上下載最新的源代碼,請這樣做: git 克隆 https://github.com/curl/curl.git,(您將創建一個名爲 curl 的目錄,並填充源代碼)。安全問題:通過我們的 HackerOne 頁面報告可疑的安全問題,而不是在公共場合! https://hackerone.com/curl 請注意:Curl 包含的源代碼是版權所有 ©1998, 1999。終於 Tekniska Hogskolan。在此附上此通知是爲了遵守分佈條件。
-
通過閱讀
README
我們並沒有找到如何使用這個庫,然後進入到docs
這個文件夾,這個文件夾是對RADME
的一個補充,在這個文件夾下面我們會看到README
裏面提到的curl1.1
這個 API 相關的手冊,還有INSTALL
(== 這個一定要看,有時候他會和README
都放在解壓後的文件夾裏面,有時候會放在docs
裏面 ==)。 -
打開
INSTALL
後看到 提示說如何編譯(compile)這個庫請看INSTALL.md
這個文件,打開這個文件後,裏面有介紹如何安裝編譯後的libcurl庫
,然後下面可以看到在 UNIX 環境下面如何進行安裝 如下圖所示,./config
就是配置的一個東西,就是將庫安裝到哪裏,若後面不跟任何的參數,就是默認安裝(可能安裝在/usr/lib
或者/usr/include
下面)。 ==make
就是編譯的意思,make install
就是將編譯後的東西拷貝到根目錄的相關文件夾下面。如果默認安裝的話可能需要root權限
== 因爲:默認可能安裝在 / usr/lib 或者 / usr/include 下面,而訪問這兩個文件夾需要 root 權限。
在這裏插入圖片描述
-
當然一般不安裝在默認的路徑下面,可以通過下圖方式指定安裝路徑
-
通過指令:
./configure --help
可以查看configure
都支持哪些功能參數,其中下面的HOST
這個指令可以指定交叉編譯的編譯器 (若不指定交叉編譯工具默認使用gcc
編譯工具)。 -
通過以下指令:
./configure --prefix=$PWD/_install
進行指定位置的安裝,安裝的時候會生成一個_install
文件夾,庫將會被安裝到這個文件夾下面,安裝過程中沒有出現任何 error 表示安裝成功,然後使用指令:make
進行編譯,然後使用使用指令:make install
進行拷貝,然後會發現當前文件夾下面生成了一個_install
文件夾,然後進入到該文件夾,如下圖所示:
調用 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
,用 get 跟 post 兩種方法來請求的一個網頁。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;
訪問成功,這個是相關的步驟
- 使用指令:
gcc demo1.c -I ./curl-7.71.1/_install/include/ -L./curl-7.71.1/_install/lib/ -lcurl
進行編譯,-I 是指定頭文件的查找路徑,-L 是指定庫文件的查找路徑,同時還要 - l curl,編譯後的執行文件在執行的時候出現以下圖中錯誤:因爲**在程序執行的時候,默認去 / usr/lib 去找庫 **,然而沒有找到,所以我們要設置動態庫的環境遍變量:使用指令: export LD_LIBRARY_PATH=庫的路徑
,這種方法臨時有效,永久生效的環境變量設置,編輯/etc/profile
即可。也可以修改工作目錄下的.bashrc
文件。linux 動態庫,靜態庫
通過以上設置然後再執行程序:可以看到/tmp/get.html
這個文件夾裏面有從百度網頁獲取的 html 代碼:
libcurl 庫函數介紹:
curl_global_init(long flags) 函數:
- libcurl 的使用(其實和 socket 編程時一樣,都需要一定的步驟):
調用 curl_global_init() 初始化 libcurl,(就像初始化套接字)
調用 curl_easy_init() 函數得到 easy interface 型指針(這個指針用來各種配置)
調用 curl_easy_setopt() 設置傳輸選項(通過調 curl_easy_setopt 這個函數來對指針進行各種配置,比如:請求的方式)
根據 curl_easy_setopt() 設置的傳輸選項,實現回調函數以完成用戶特定任務
調用 curl_easy_perform() 函數進行訪問請求
調用 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 //沒有額外的初始化。
-
void curl_global_cleanup(void)
函數:結束 libcurl 使用的時候,用來對 curl_global_init 做的工作清理。類似於 close 的函數。注意:雖然 libcurl 是線程安全的,但 curl_global_cleanup 是不能保證線程安全的,所以不要在每個線程中都調用 curl_global_init,應該將該函數的調用放在主線程中。 -
char * curl_version( )
函數: 打印當前 libcurl 庫的版本。 -
CURL * curl_easy_init( )
函數:curl_easy_init 用來初始化一個 CURL 的指針 (有些像返回 FILE 類型的指針一樣). 相應的在調用結束時要用 url_easy_cleanup 函數清理. 一般 curl_easy_init 意味着一個會話的開始. 它會返回一個 easy_handle(CURL * 對象), 一般都用在 easy 系列的函數中. -
void curl_easy_cleanup(CURL * handle)
函數:這個調用用來結束一個會話. 與 curl_easy_init 配合着用. 參數: CURL 類型的指針.
CURLcode curl_easy_setopt(CURL * handle, CURLoption option,parameter)
函數:這個函數最重要了. 幾乎所有的 curl 程序都要頻繁的使用它. 它告訴 curl 庫. 程序將有如何的行爲. 比如要查看一個網頁的 html 代碼等.(這個函數有些像 ioctl 函數)
參數:
CURL 類型的指針
各種 CURLoption 類型的選項.(都在 curl.h 庫裏有定義, man 也可以查看到)
parameter 這個參數 既可以是個函數的指針, 也可以是某個對象的指針, 也可以是個 long 型的變量. 它用什麼這取決於第二個參數. CURLoption 這個參數的取值很多. 具體的可以查看 man 手冊.
-
CURLcode curl_easy_perform(CURL *handle)
函數;在初始化 CURL 類型的指針 以及 curl_easy_setopt 完成後調用. 就像字面的意思所說 perform 就像是個舞臺. 讓我們設置的 option 運作起來. 參數: CURL 類型的指針.
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/I1Iut-twZo_Wg2QowuFaIA