阳光岛主 2020-06-14
在之前的文章《curl使用小记(一)》中论述了命令行工具curl的基本使用。除此之外,curl还提供了能够直接供程序调用的模块库接口libcurl。这里就通过一个远程下载网络上的一个图片的实例,讲述libcurl的使用。
libcurl库还是推荐直接找已经编译好的,因为是C程序接口,所以还是比较稳定的。
libcurl虽然用起来比较繁复,但大概可以就初分为4类函数:
其中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的配置项并没有做好完善的配置,服务器不会接受一些不合规的配置请求访问,毕竟请求都是消耗资源的,现在的正规网站都会做一些反爬虫的设置。