1. 概述
在之前的文章《curl使用小記(一)》中論述了命令行工具curl的基本使用。除此之外,curl還提供了能夠直接供程序調用的模塊庫接口libcurl。這里就通過一個遠程下載網絡上的一個圖片的實例,講述libcurl的使用。
2. 實例
libcurl庫還是推薦直接找已經編譯好的,因為是C程序接口,所以還是比較穩定的。
libcurl雖然用起來比較繁復,但大概可以就初分為4類函數:
- 初始化:curl_easy_init()。
- 配置數據傳輸選項,設置回調函數:curl_easy_setopt()。
- 啟動傳輸任務:curl_easy_perform()。
- 釋放資源:curl_easy_cleanup()。
其中curl_easy_setopt最為繁復,curl有超多的配置選項可以選擇,但是基本上可以跟curl命令行工具的參數選項對應起來。具體實例如下,可參看注釋說明:
#include <iostream>
#include <curl/curl.h>
using namespace std;
size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream)
{
size_t written = fwrite(ptr, size, nmemb, (FILE *)stream);
return written;
}
//顯示文件傳輸進度,dltotal代表文件大小,dlnow代表傳輸已經完成部分
//clientp是CURLOPT_PROGRESSDATA傳入的值
int progress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow){
if (dltotal != 0)
{
printf("%lf / %lf (%lf %%)\n", dlnow, dltotal, dlnow*100.0 / dltotal);
}
return 0;
}
int main()
{
const char *netlink = "http://cn.bing.com/th?id=OHR.GrandsCausses_EN-CN3335882379_800x480.jpg";
const char *output = "dst.jpg";
curl_global_init(CURL_GLOBAL_ALL); //初始化全局資源
CURL *curl = curl_easy_init(); //初始化句柄
//需要的話,可以設置代理
curl_easy_setopt(curl, CURLOPT_PROXY, "127.0.0.1:1080");
//訪問網址
curl_easy_setopt(curl, CURLOPT_URL, netlink);
//設置用戶代理
curl_easy_setopt(curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36");
//注意以二進制打開
FILE *fp = nullptr;
if (fopen_s(&fp, output, "wb") != 0)
{
curl_easy_cleanup(curl);
return 0;
}
//寫出數據
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
//實現下載進度
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, false);
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress_callback);
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, nullptr);
//運行
curl_easy_perform(curl);
curl_easy_cleanup(curl); //釋放句柄
fclose(fp);
curl_global_cleanup(); //釋放全局資源
return 1;
}
這個實例訪問了網上的一個圖片資源,設置了一個代理,並且偽裝成瀏覽器訪問,並將其圖片下載到本地。最后還實現了下載進度的顯示:
需要注意的是我試過很多圖片資源,並不是所有的圖片資源都能夠正常訪問到並且下載的。這里面的原因是一方面網站服務器就做了相關的設置,比如博客網站上的圖片資源就不允許外鏈,我這里下載博客網站上的圖片就失敗了;另一方面是curl的配置項並沒有做好完善的配置,服務器不會接受一些不合規的配置請求訪問,畢竟請求都是消耗資源的,現在的正規網站都會做一些反爬蟲的設置。