curl使用小记——远程下载一张图片(代码片段)

charlee44 charlee44     2022-12-01     474

关键词:

1. 概述

在之前的文章《curl使用小记(一)》中论述了命令行工具curl的基本使用。除此之外,curl还提供了能够直接供程序调用的模块库接口libcurl。这里就通过一个远程下载网络上的一个图片的实例,讲述libcurl的使用。

2. 实例

libcurl库还是推荐直接找已经编译好的,因为是C程序接口,所以还是比较稳定的。

libcurl虽然用起来比较繁复,但大概可以就初分为4类函数:

  1. 初始化:curl_easy_init()。
  2. 配置数据传输选项,设置回调函数:curl_easy_setopt()。
  3. 启动传输任务:curl_easy_perform()。
  4. 释放资源: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 %%)
", 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的配置项并没有做好完善的配置,服务器不会接受一些不合规的配置请求访问,毕竟请求都是消耗资源的,现在的正规网站都会做一些反爬虫的设置。

3. 参考

  1. libcurl 接口调用方式
  2. C++ 用libcurl库进行http通讯网络编程

使用vue将两张图片叠加再保存为一张图片下载(代码片段)

...f0c;勿对号入座!!!)步骤先将两张图片使用css进行叠加,然后按照自己需求将图片移动到合理位置要使用到一个插件将两张图片转为canvas,插件链接:html2canvas最后将canvas保存下载。代码<tem 查看详情

php下载网络图片常用的三个方法总结(代码片段)

...;curl非常强大,也是phper必须掌握的技能,所以建议大家使用该方法。该方法的思路是,使用curl工具获取远程图片的信息,然后将该信息保存到本地的文件中。这里我没有对curl_exec的结果做校验了,偷个懒。关于curl的用法,如... 查看详情

前端动画小记---bilibili(゜-゜)つロ客户下载小动画

...处理方式,将页面涉及到的图片零星图片集中到一张图上使用,主要利用cssbackground-position定位要显示的图片位置。 雪碧图文件:  查看详情

多线程批量下载远程图片(代码片段)

python多线程使用场景:多线程采集,以及性能测试等。数据库驱动类-简单封装下mysqlDriver.py#!/usr/bin/python3#-*-coding:utf-8-*-#author:zhouchao#mysql驱动模型类importpymysql;importtraceback;classmysqlDriver:host="localhost";user="root";passwo 查看详情

使用vue将两张图片叠加再保存为一张图片下载(代码片段)

...f0c;勿对号入座!!!)步骤先将两张图片使用css进行叠加,然后按照自己需求将图片移动到合理位置要使用到一个插件将两张图片转为canvas,插件链接:html2canvas最后将canvas保存下载。代码<template>... 查看详情

laya资源加载小记(代码片段)

Laya.Loader负责资源的加载逻辑,被LoaderManager管理。Laya支持多种类型资源加载,也支持自定义类型加载。不同类型的加载方式可能不同。Laya.Loader缓存已经被加载过得资源,减少资源重复加载。提供清理资源接口,由LoaderManager封... 查看详情

mac编译jdk源码小记(代码片段)

...ootstrapjdk版本最少14,15第一步:下载jdk源码  没有使用hg去下载,使用了git仓库代码 https://github.com/openjdk/jdk.git  克隆仓库代码gitclonehttps://github.com/unoffic 查看详情

phpphp下载远程图片保存到本地(代码片段)

查看详情

sh使用curl下载文件(代码片段)

查看详情

sh使用curl下载文件(代码片段)

查看详情

deepin配置小记(代码片段)

...home(家目录)4.自动安装(Deepin安装后如果某些驱动无法正常使用,就去官网下载相应的驱动程序,官网不提供那就比较麻烦了)安装Git$sudoapt-getinstallgit$ssh- 查看详情

sh使用wget和curl下载(代码片段)

查看详情

php使用curl从页面下载并保存图像(代码片段)

查看详情

php使用进度条下载php/curl文件(代码片段)

查看详情

springdatamongo使用小记(代码片段)

一、更新并返回更新后的值ObjectnewVal=mongoTemplate.findAndModify(query,update,FindAndModifyOptions.options().returnNew(true),Object.class,collectionName);二、批量操作BulkOperationsbulkOps=mongoTemplate.bulkOps( 查看详情

cgcontextref使用小记(代码片段)

1.用CGContextRef画文字在UIView的-(void)drawRect:(CGRect)rect方法中进行CGContextRefcontext=UIGraphicsGetCurrentContext();CGContextSetShouldAntialias(context,YES);//抗锯齿CGContextSetLineWidth(context,1.0f);//设置线宽/ 查看详情

php使用curl从安全网站(https)下载文件(代码片段)

查看详情

curl日志分析(代码片段)

....log命令解析-k :允许连接到没有证书(H)的SSL站点-O :使用远程文件的文件名作为本地文件名2>&1 :将标准错误重定向到标准输出tee :从标准输入读取并写入标准输出和文件2.分析日志文件tai 查看详情