curl下载工具使用参考
2013-01-08 10:57:59 阿炯

curl不仅是一款命令行的下载工具,它也可用作'http'协议的调试器,其功能和应用领域已经超过'wget'工具,并且还可以使用它的开发库libcurl'嵌入到第三方的应用程序中。Perl对curl的支持也是不错的,使用它所开发的'http'相关功能模块在同类对比的成绩也是不错的。

用户要想使用好这个工具,除了详细学习参数之外,还需要深刻理解http的各种协议与URL的各个语法。这里推荐几个RFC:
RFC 2616 HTTP协议语法的定义。
RFC 2396 URL语法的定义。
RFC 2109 Cookie是怎样工作的。
RFC 1867 HTTP如何POST,以及POST的格式。

指令选项参考1
-a/--append 上传文件时,附加到目标文件
-A/--user-agent <string> 设置用户代理发送给服务器
- anyauth 可以使用“任何”身份验证方法
-b/--cookie <name=string/file> cookie字符串或文件读取位置
- basic 使用HTTP基本验证
-B/--use-ascii 使用ASCII /文本传输
-c/--cookie-jar <file> 操作结束后把cookie写入到这个文件中
-C/--continue-at <offset> 断点续转
-d/--data <data> HTTP POST方式传送数据
--data-ascii <data> 以ascii的方式post数据
--data-binary <data> 以二进制的方式post数据
--negotiate 使用HTTP身份验证
--digest 使用数字身份验证
--disable-eprt 禁止使用EPRT或LPRT
--disable-epsv 禁止使用EPSV
-D/--dump-header <file> 把header信息写入到该文件中
--egd-file <file> 为随机数据(SSL)设置EGD socket路径
--tcp-nodelay 使用TCP_NODELAY选项
-e/--referer 来源网址
-E/--cert <cert[:passwd]> 客户端证书文件和密码 (SSL)
--cert-type <type> 证书文件类型 (DER/PEM/ENG) (SSL)
--key <key> 私钥文件名 (SSL)
--key-type <type> 私钥文件类型 (DER/PEM/ENG) (SSL)
--pass <pass> 私钥密码 (SSL)
--engine <eng> 加密引擎使用 (SSL). "--engine list" for list
--cacert <file> CA证书 (SSL)
--capath <directory> CA目录 (made using c_rehash) to verify peer against (SSL)
--ciphers <list> SSL密码
--compressed 要求返回是压缩的形势 (using deflate or gzip)
--connect-timeout <seconds> 设置最大请求时间
--create-dirs 建立本地目录的目录层次结构
--crlf 上传是把LF转变成CRLF
-f/--fail 连接失败时不显示http错误
--ftp-create-dirs 如果远程目录不存在,创建远程目录
--ftp-method [multicwd/nocwd/singlecwd] 控制CWD的使用
--ftp-pasv 使用 PASV/EPSV 代替端口
--ftp-skip-pasv-ip 使用PASV的时候,忽略该IP地址
--ftp-ssl 尝试用 SSL/TLS 来进行ftp数据传输
--ftp-ssl-reqd 要求用 SSL/TLS 来进行ftp数据传输
-F/--form <name=content> 模拟http表单提交数据
-form-string <name=string> 模拟http表单提交数据
-g/--globoff 禁用网址序列和范围使用{}和[]
-G/--get 以get的方式来发送数据
-h/--help 帮助
-H/--header <line>自定义头信息传递给服务器
--ignore-content-length 忽略的HTTP头信息的长度
-i/--include 输出时包括protocol头信息
-I/--head 只显示文档信息
从文件中读取-j/--junk-session-cookies忽略会话Cookie
- 界面<interface>指定网络接口/地址使用
- krb4 <级别>启用与指定的安全级别krb4
-j/--junk-session-cookies 读取文件进忽略session cookie
--interface <interface> 使用指定网络接口/地址
--krb4 <level> 使用指定安全级别的krb4
-k/--insecure 允许不使用证书到SSL站点
-K/--config 指定的配置文件读取
-l/--list-only 列出ftp目录下的文件名称
--limit-rate <rate> 设置传输速度
--local-port<NUM> 强制使用本地端口号
-m/--max-time <seconds> 设置最大传输时间
--max-redirs <num> 设置最大读取的目录数
--max-filesize <bytes> 设置最大下载的文件总量
-M/--manual 显示全手动
-n/--netrc 从netrc文件中读取用户名和密码
--netrc-optional 使用 .netrc 或者 URL来覆盖-n
--ntlm 使用 HTTP NTLM 身份验证
-N/--no-buffer 禁用缓冲输出
-o/--output 把输出写到该文件中
-O/--remote-name 把输出写到该文件中,保留远程文件的文件名
-p/--proxytunnel 使用HTTP代理
--proxy-anyauth 选择任一代理身份验证方法
--proxy-basic 在代理上使用基本身份验证
--proxy-digest 在代理上使用数字身份验证
--proxy-ntlm 在代理上使用ntlm身份验证
-P/--ftp-port <address> 使用端口地址,而不是使用PASV
-Q/--quote <cmd>文件传输前,发送命令到服务器
-r/--range <range>检索来自HTTP/1.1或FTP服务器字节范围
--range-file 读取(SSL)的随机文件
-R/--remote-time 在本地生成文件时,保留远程文件时间
--retry <num> 传输出现问题时,重试的次数
--retry-delay <seconds> 传输出现问题时,设置重试间隔时间
--retry-max-time <seconds> 传输出现问题时,设置最大重试时间
-s/--silent静音模式。不输出任何东西
-S/--show-error 显示错误
--socks4 <host[:port]> 用socks4代理给定主机和端口
--socks5 <host[:port]> 用socks5代理给定主机和端口
--stderr <file>
-t/--telnet-option <OPT=val> Telnet选项设置
--trace <file> 对指定文件进行debug
--trace-ascii <file> Like --跟踪但没有hex输出
--trace-time 跟踪/详细输出时,添加时间戳
-T/--upload-file <file> 上传文件
--url <URL> Spet URL to work with
-u/--user <user[:password]>设置服务器的用户和密码
-U/--proxy-user <user[:password]>设置代理用户名和密码
-v/--verbose 更多的额外的信息输出
-V/--version 显示版本信息
-w/--write-out [format]什么输出完成后
-x/--proxy <host[:port]>在给定的端口上使用HTTP代理
-X/--request <command>指定什么命令
-y/--speed-time 放弃限速所要的时间。默认为30
-Y/--speed-limit 停止传输速度的限制,速度时间'秒
-z/--time-cond 传送时间设置
-0/--http1.0 使用HTTP 1.0
-1/--tlsv1 使用TLSv1(SSL)
-2/--sslv2 使用SSLv2的(SSL)
-3/--sslv3 使用的SSLv3(SSL)
--3p-quote like -Q for the source URL for 3rd party transfer
--3p-url 使用url,进行第三方传送
--3p-user 使用用户名和密码,进行第三方传送
-4/--ipv4 使用IP4
-6/--ipv6 使用IP6
-#/--progress-bar 用进度条显示当前的传送状态

指令选项参考2

参数组参数描述
urlurl需要抓取的一到多个URLs;
多个下面通配符的方式:
  1、http://{www,ftp,mail}.freeoa.net;
  2、http://freeoa.net/images/[001-999].jpg;
  3、http://freeoa.net/images/[1-999].html;
  4、ftp://freeoa.net/file[a-z].txt


-H "name: value"
--header "name: value"
(HTTP)添加一个http header(http请求头);
-H "name:"
--header "name:"
(HTTP)移除一个http header(http请求头);
-A "string"
--user-agent "string"
(HTTP)设置Http请求头“User-Agent”,服务器通过“User-Agent”可以判断客户端使用的浏览器名称和操作系统类型,伪造此参数能导致服务器做出错误判断。
也可以使用“-H”, “--header option”设置此选项;
-e <URL>
--referer <URL>
(HTTP)设置访问时的来源页面,告诉http服务从哪个页面进入到此页面;
-e "freeoa.net"相当于“-H "Referer: www.qq.com"”;


-I
--head
(HTTP)只输出HTTP-header,不获取内容(HTTP/FTP/FILE)。
用于HTTP服务时,获取页面的http头;
  (如:curl -I http://freeoa.net)
用于FTP/FILE时,将会获取文件大小、最后修改时间;
  (如:curl -I file://test.txt)
-i
--include
(HTTP)输出HTTP头和返回内容;
-D <file>
--dump-header <file>
(HTTP)转储http响应头到指定文件;
cookie-b name=data
--cookie name=data
(HTTP)发送cookie数据到HTTP服务器,数据格式为:"NAME1=VALUE1; NAME2=VALUE2";

如果行中没有“=”,将把参数值当作cookie文件名;

这个cookie数据可以是由服务器的http响应头“Set-Cookie:”行发送过来的;
-c filename
--cookie-jar file name
(HTTP)完成操作后将服务器返回的cookies保存到指定的文件;
指定参数值为“-”将定向到标准输出“如控制台”;
-j
--junk-session-cookies
(HTTP)告诉curl放弃所有的"session cookies";
相当于重启浏览器;
代理-x host:port
-x [protocol://[user:pwd@]host[:port]
--proxy [protocol://[user:pwd@]host[:port]
使用HTTP代理访问;如果未指定端口,默认使用8080端口;
protocol默认为http_proxy,其他可能的值包括:
http_proxy、HTTPS_PROXY、socks4、socks4a、socks5;
如:
--proxy 8.8.8.8:8080;
-x "http_proxy://aiezu:123@freeoa.net:80"
-p
--proxytunnel
将“-x”参数的代理,作为通道的方式去代理非HTTP协议,如ftp;
--socks4 <host[:port]>
--socks4a <host[:port]>
--socks5 <host[:port]>
使用SOCKS4代理;
使用SOCKS4A代理;
使用SOCKS5代理;
此参数会覆盖“-x”参数;
--proxy-anyauth
--proxy-basic
--proxy-diges
--proxy-negotiate
--proxy-ntlm
http代理认证方式,参考:
--anyauth
--basic
--diges
--negotiate
--ntlm
-U <user:password>
--proxy-user <user:password>
设置代理的用户名和密码;
数据
传输
-G
--get
如果使用了此参数,“-d/”、“--data”、“--data-binary”参数设置的数据,讲附加在url上,以GET的方式请求; 
-d @file
-d "string"
--data "string"
--data-ascii "string"
--data-binary "string"
--data-urlencode "string"
(HTTP)使用HTTP POST方式发送“key/value对”数据,相当于浏览器表单属性(method="POST",enctype="application/x-www-form-urlencoded")
  -d,--data:HTTP方式POST数据;
  --data-ascii:HTTP方式POST ascii数据;
  --data-binary:HTTP方式POST二进制数据;
  --data-urlencode:HTTP方式POST数据(进行urlencode);
如果数据以“@”开头,后紧跟一个文件,将post文件内的内容;
-F name=@file
-F name=<file
-F name=content
--form name=content
(HTTP)使用HTTP POST方式发送类似“表单字段”的多类型数据,相当于同时设置浏览器表单属性(method="POST",enctype="multipart/form-data"),可以使用此参数上传二进制文件。

如果字段内容以“@”开头,剩下的部分应该是文件名,curl将会上传此文件,如:
curl -F "pic=@pic.jpg" http://freeoa.net;
curl -F "page=@a.html;type=text/html" http://freeoa.net
curl -F "page=@/tmp/a;filename=a.txt" http://freeoa.net

如果字段内容以“<”开头,剩下的部分应该是文件名,curl将从文件中获取作为此字段的值,如:curl -F "text=<text.txt" http://freeoa.net;
--form-string <key=value>(HTTP)类似于“--form”,但是“@”、“<”无特殊含义;
-T file
--upload-file file
通过“put”的方式将文件传输到远程网址;

选项参数只使用字符"-",将通过stdin读入文件内容;
如:
cat test.txt|curl "http://freeoa.net/a.php" -T - 
curl "http://freeoa.net/a.php" -T - <test.txt

此参数也可以使用通配符:
curl -T "{file1,file2}" http://freeoa.net
curl -T "img[1-1000].png" http://freeoa.net
断点
续传
-C <offset>
--continue-at <offset>
断点续转,从文件头的指定位置开始继续下载/上传;
offset续传开始的位置,如果offset值为“-”,curl会自动从文件中识别起始位置开始传输;
-r <range>
--range <range>
(HTTP/FTP/SFTP/FILE) 只传输内容的指定部分:
0-499:最前面500字节;
-500:最后面500字节;
9500-:最前面9500字节;
0-0,-1:最前面和最后面的1字节;
100-199,500-599:两个100字节;



认证
--basic(HTTP)告诉curl使用HTTP Basic authentication(HTTP协议时),这是默认认证方式;
--ntlm(HTTP)使用NTLM身份验证方式,用于HTTP协议;
一般用于IIS使用NTLM的网站;
--digest(HTTP)使用HTTP Digest authentication加密,用于HTTP协议;
配合“-u/--user”选项,防止密码使用明文方式发送;
--negotiate(HTTP)使用GSS-Negotiate authentication方式,用于HTTP协议;
它主要目的是为它的主要目的是为kerberos5认证提供支持支持;
--anyauth(HTTP)告诉curl自动选择合适的身份认证方法,并选用最安全的方式;
-u user:password
--user user:password
使用用户名、密码认证,此参数会覆盖“-n”、“--netrc”和“--netrc-optional”选项;

如果你只提供用户名,curl将要求你输入密码;

如果你使用“SSPI”开启的curl库做“NTLM”认证,可以使用不含用户名密码的“-u:”选项,强制curl使用当前登录的用户名密码进行认证;

此参数相当于设置http头“Authorization:”;
证书-E <证书[:密码]>
--cert <证书[:密码]>
(SSL)指定“PEM”格式的证书文件和证书密码;
--cert-type <type>(SSL)告诉curl所提供证书的类型:PEM、DER、ENG等;
默认为“PEM”;
--cacert <CA证书>(SSL)告诉curl所以指定的CA证书文件,必须是“PEM”格式;
--capath <CA证书路径>(SSL)告诉curl所以指定目录下的CA证书用来验证;
这些证书必须是“PEM”格式;
--crlfile <file>(HTTPS/FTPS)提供一个PEM格式的文件,用于指定被吊销的证书列表;
-k
--insecure
(SSL)设置此选项将允许使用无证书的不安全SSL进行连接和传输。
SSL
其他
--ciphers <list of ciphers>(SSL)指定SSL要使用的加密方式;如:“aes_256_sha_256”;
--engine <name>设置一个OpenSSL加密引擎用于加密操作;
使用“curl --engine list”查看支持的加密引擎列表;
--random-file(SSL)指定包含随机数据的文件路径名;数据是用来为SSL连接产生随机种子为;
--egd-file <file>(SSL)为随机种子生成器EGD(Entropy Gathering Daemon socket)指定的路径名;
-1/--tlsv1
--tlsv1.0
--tlsv1.1
--tlsv1.2
-2/--sslv2
-3/--sslv3
(SSL)使用TLS版本2与远程服务器通讯;
(SSL)使用TLS 1.0版本与远程服务器通讯;
(SSL)使用TLS 1.1版本与远程服务器通讯;
(SSL)使用TLS 1.2版本与远程服务器通讯;
(SSL)使用SSL版本2与远程服务器通讯;
(SSL)使用SSL版本3与远程服务器通讯;
私钥
公钥
--key <key>(SSL/SSH)指定一个私钥文件名;为指定时自动尝试使用下面文件:“~/.ssh/id_rsa”、“~/.ssh/id_dsa”、“./id_rsa'”、 “./id_dsa”;
--key-type <type>(SSL)指定私钥文件类型,支持:DER、PEM、ENG,默认是PEM;
--pass <phrase>(SSL/SSH)指定私钥文件的密码;
--pubkey <key>(SSH)使用指定文件提供的您公钥;
FTP-P
--ftp-port <接口>
(FTP)FTP主动模式时,设置一个地址等待服务器的连接,如:
网卡:eth1
IP:8.8.8.8
主机名:freeoa.net
可以加端口号:eth1:20000-21000;
--crlf(FTP)上传时将换行符(LF)转换为回车换行(CRLF);
--ftp-account [data](FTP)ftp帐号信息;
--ftp-method [method](FTP)可选值:multicwd/nocwd/singlecwd;
--ftp-pasv(FTP)使用使用PASV(被动)/EPSV模式;
--ftp-skip-pasv-ip(FTP)使用PASV的时,跳过指定IP;
--ftp-create-dirs(FTP)上传时自动创建远程目录;
-l
--list-only
(FTP)列出ftp文件列表;
-B
--use-ascii
(FTP/LDAP)使用Ascii传输模式,用于FTP、LDAP;在ftp中相当与使用了“type=A;”模式。
--disable-epsv(FTP)告诉curl在PASV(被动模式)时不要使用EPSV;
--disable-eprt(FTP)告诉curl在主动模式时禁用EPRT和LPRT;
限速--limit-rate <speed>限制curl使用的最大带宽;如果未指定单位,默认单位为“bytes/秒”,你也可以指定单位为“K”、“M”、“G”等单位,如:“--limit-rate 1m”为限制最大使用带宽为“1m字节/秒”;
-y
--speed-time <time>
If a download is slower than speed-limit bytes per second during a speed-time period, the download gets aborted. If speed-time is used, the default speed-limit will be 1 unless set with -Y.
This option controls transfers and thus will not affect slow connects etc. If this is a concern for you, try the --connect-timeout option.
-Y
--speed-limit <speed>
If a download is slower than this given speed (in bytes per second) for speed-time seconds it gets aborted. speed-time is set with -y and is 30 if not set.
其他
选项
-0/--http1.0(HTTP) 强制curl使用HTTP 1.0而不是使用默认的HTTP 1.1;
--interface <name>使用指定的网卡接口访问;
curl --interface eth0 http://freeoa.net
curl --interface 10.0.0.101 http://freeoa.net
-X <command>
--request <command>
(HTTP)指定与服务器通信使用的请求方法,如:GET、PUT、POST、DELETE等,默认GET;
--keepalive-time <seconds>设置keepalive时间
--no-keepalive关闭keepalive功能;
--no-buffer禁用对输出流缓冲;
--buffer启用输出流缓冲;
-L
--location
(HTTP/HTTPS)追随http响应头“Location:”定向到跳转后的页面;
(在http响应码为3XX时使用,如301跳转、302跳转)
--location-trusted(HTTP/HTTPS)同“--location”,但跳转后会发送跳转前的用户名和密码;
--compressed(HTTP)请求对返回内容使用压缩算法进行压缩;curl支持对gzip压缩进行解压;
--connect-timeout <seconds>指定最大连接超时,单位“秒”;
-m seconds
--max-time seconds
限制整个curl操作的最长时间,单位为秒;
-s
--silent
安静模式。不要显示进度表或错误消息;
-#
--progress-bar
显示进度条;
错误
选项
-f
--fail
(HTTP)连接失败时(400以上错误)不返回默认错误页面,而是返回一个curl错误码“22”;
--retry <num>
--retry-delay <seconds>
--retry-max-time <seconds>
失败重试次数;
重试间隔时间;
最大重试时间;
-S
--show-error
安静模式下显示错误信息;
--stderr <file>错误信息保存文件;
输出-o file
--output file
将返回内容输出到文件。
如果是用过通配符获取多个url,可以使用“#”后跟“数字序号”,curl会自动将它替换对应的关键词,如:
  curl "http://freeoa.net/{a,b}.txt" -o "#1.txt";
  将保存为:“a.txt”,“b.txt”;

  curl "http://freeoa.net/{a,b}_[1-3].txt" -o "#1#2.txt";
  将保存为:a1.txt、a2.txt、a3.txt、b1.txt、b2.txt、b3.txt

  如果要根据规则创建保存目录,参考:“--create-dirs”

指定“-”将定向到标准输出“如控制台”; 
-O
--remote-name
将返回内容输出到当前目录下,和url中文件名相同的文件中(不含目录);
--create-dirs与“-o”参数配合使用,创建必要的本地目录层次结构
-w
--write-out format
操作完成后在返回信息尾部追加指定的内容;要追加的内容可以是一个字符串“string”、从文件中获取“@filename”、从标准输入中获取“@-”

格式参数中可以用%{variable_name} 方式使用响应信息的相关变量,如:%{content_type}、%{http_code}、%{local_ip}...,更多变量参考“man curl”获取;

格式参数可以使用“\n”、“\r”、“\t”等转义字符;
调试--trace <file>转储所有传入和传出的数据到文件,包括描述信息;
使用“-”作为文件名将输出发送到标准输出。
--trace-ascii file转储所有传入和传出的数据到文件,包括描述信息,只转储ASCII部分,更容易阅读;
使用“-”作为文件名将输出发送到标准输出。
这个选项会覆盖之前使用的-v、 --verbose、 --trace-ascii选项;
--trace-time转储文件中添加时间信息;
-K
--config <config file>
从配置文件中读取参数,参考:http://curl.haxx.se/docs/
-v
--verbose
显示更详细的信息,调试时使用;
帮助-M
--manual
显示完整的帮助手册;
-h
--help
linux curl用法帮助;



最常用的curl参数


-I 可以看到http response的头信息。
-v 可以显示一次http通信的整个过程,包括端口连接和http request头信息。
-L 用户有301,302跳转的网址(比如http跳转到https),可以显示跳转后的网址的访问情况。
-o 表示将文件保存为命令行中指定的文件名的文件中,可以测试文件的下载的情况,比如-oa表示文件保存的命名为a,一般可以设置-o /dev/null 它是一个空设备,是一个特殊的设备文件,它丢弃一切写入其中的数据,因此没有文件保存到本地。
-X 可以指定什么方式请求,默认是GET请求,也可以指定POST,DELETE等。
-d可以模拟发送的携带的表单的数据,比如:curl -d "user=freeoa&password=12345" http://www.aaa.com/login.php
-H 可以指定请求头,比如可以验证防盗链的referer情况。curl -I http://www.freeoa.net/noe.txt -H "Referer:http://www.baidu.com/"
-F可以模拟表单上传,可以指定上传的ip地址或者是网址。
比如下面这个表单:
<form method="post" action="http://upload.freeoa.net/" enctype="multipart/form-data">
  <input name="key" type="hidden" value="<resource_key>">
  <input name="token" type="hidden" value="<upload_token>">
  <input name="file" type="file" />
</form>

可以通过下面的命令来模拟上传:
curl -v -F 'key=211' -F 'token=7mtwnwk' -F 'file=@/data/usersync/freeoa.jpg' http://ipaddr:port

-x 选项可以为curl添加代理功能

-x, --proxy <[protocol://][user:password@]proxyhost[:port]>

Use the specified HTTP proxy.If the port number is not specified, it is assumed at port 1080.

curl -x http://proxy_server:proxy_port --proxy-user username:password -L http://url

Beware that if you are using a SOCKS proxy, instead of a HTTP/HTTPS proxy, you will need to use the --socks5 switch instead:
curl --socks5 125.119.175.48:8909 http://example.com/

You can also use --socks5-hostname instead of --socks5 to resolve DNS on the proxy side.

For curl you can configure proxy in your ~/.curlrc (_curlrc on Windows) file by adding proxy value, the syntax is:
proxy = http://username:password@proxy-host:port

Just summarizing all great mentioned answers:
curl -x http://<user>:<pass>@<proxyhost>:<port>/ -o <filename> -L <link>

With a proxy with authentication I use:
curl -x <protocol>://<user>:<password>@<host>:<port> --proxy-anyauth <url>

export the http[s]_proxy shell variable if you're just setting the proxy for a one off command. e.g.

http_proxy=http://your.proxy.server:port curl http://www.example.com

curl -x http://10.1.1.50:8080/ -fsSL https://download.docker.com/linux/ubuntu/gpg

curl -v http://172.19.195.57:9998/hp/hpm.psp --socks5 172.19.131.210:9527


应用举例

1. 资源另存为
利用curl 可以把url资源以指定的文件名另存为到本地
curl -o lesson0.mp4 http://v.freeoa.net/video.mp4

使用-O (大写) 选项可以自动从url解析出文件名另存为到当前目录
curl -O http://v.freeoa.net/video.mp4

文件就会以'filename.mp4'为文件名进行保存。
但是如果执行:curl -O http://www.sina.com.cn

那么就会产生错误:"Remote file name has no length!" 无法去解析文件名。

2. 查看Http响应头
通过 -I 参数可以只查看Http响应头
curl -I http://www.sina.com.cn

3. 强大的通配符支持
curl -o 'video#1.mp4' 'http://xxx.com/video[1-4].mp4'

这样就可以下载所有的视频,并且所有的视频都会依次以video1.mp4 video2.mp4...这样来在本地进行保存。

另外范围的通配符还支持前面置0的做法:
curl -O http://v.freeoa.net/test[00-99].mp3

就会自动下载test00.mp3 到 test99.mp3
另外还可以指定步长:
curl -O http://v.freeoa.net/test[00-99:2].mp3

除了表示范围的通配符,还可以提供词汇列表的通配:
curl -O http://www.urltest.com/{minzufeng,tante}.mp3

4. 自动跟踪重定向
如果curl请求的地址产生重定向,那么使用-L参数会自动重定向,比如:
curl -L http://www.sina.com

会自动重定向到www.sina.com.cn

5. 指定HTTP请求方式
可以使用-X参数来指定http的请求方式,默认的情况下curl发起的是GET请求。

curl -X POST 发起post请求

curl -X UPDATE 发起update请求

6. 自定义HTTP请求头:
cookie: --cookie "name1=XXX;name2=XXX" http://v.freeoa.net
referer: --referer "<script>alert('I am admin, bitch!');</script>"
ua: --user-agent "<script>alert('I am admin, bitch!');</script>"

7. 提交Form表单
可以使用-F参数来提交form表单, -F参数允许有多个
curl -X post -F "name=chihz" -F "age=22" -F "headImg=@/home/freeoa/images/mypic.jpg" http://curltest.com

其中 -F "headImg=@/home/freeoa/images/mypic.jpg"  为文件上传。

8. 多进程下载
curl支持按照范围来进行文件下载,通过-r参数就可以实现:
curl -O -r'0-500' http://v.freeoa.net/video.mp4

这样就会下载文件的前500个byte, 如果一个大文件,我们可以通过先使用curl -I拿到Content-Length, 然后分配固定个进程,为每个进程制定一个下载的范围,这样就可以实现多进程下载,下载完毕之后再将每个进程下载的文件进行合并就可以。

不过这个最后还有个问题就是不能有个主进程去监控每个工作进程的完成情况,到时侯去自己合并数据,需要自己手工去合并。

对HTTP高级功能的支持
认证
curl可以处理各种情况的认证页面,例如下载用户名/密码认证方式的页面:
curl -u name:password www.freeoa.net

如果网络是通过http代理服务器出去的,而代理服务器需要用户名和密码,那么输入:
curl -U proxyuser:proxypassword http://curl.haxx.se

任何需要输入用户名和密码的时候,只在参数中指定用户名而空着密码,curl可以交互式的让用户输入密码。

引用
有些网络资源访问的时候必须经过另外一个网络地址跳转过去,这用术语来说是:referer--引用。
对于这种地址的资源,curl也可以下载:
curl -e http://curl.haxx.se daniel.haxx.se

伪装成特定浏览器
有些网络资源首先需要判断用户使用的是什么浏览器,符合标准了才能够下载或者浏览。
此时curl可以把自己“伪装”成任何其他浏览器:
curl -A "(Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1479.0 Safari/537.36)" URL

这个指令表示curl伪装成了Chrome 28.0版,用户平台是Windows 7。

使用:curl -A "Mozilla/4.73 [en] (X11; U; Linux 2.2.15 i686)" URL
此时curl变成了Netscape,运行在x86平台的Linux上了。

使用网站的Cookie
Cookie是服务器经常使用的一种记忆客户信息的方法。如果cookie被记录在了文件中,那么使用命令:
curl -b stored_cookies_file www.freeoa.net

curl可以根据旧的cookie写出新cookie并发送到网站:
curl -b cookies.txt -c newcookies.txt www.freeoa.net

加密HTTP
如果是通过OpenSSL加密的https协议传输的网页,curl可以直接访问:
curl https://that.secure.server.com

使用http证书
如果是采用证书认证的http地址,证书在本地,那么curl这样使用:
curl -E mycert.pem https://that.secure.server.com

表单处理
Form通常用来收集并向网站提交信息。提交信息的方法有两种,GET方法和POST方法。
GET方法
curl "www.freeoa.net/article.cgi?id=1905&med=get"

POST方法,POST方法和GET方法的区别在于GET方法使用的时候,浏览器中会产生目标URL,而POST不会。
curl -d "id=1905&med=post" www.freeoa.net/article.cgi

curl -F upload=@localfilename -F med=post URL
这个命令将本地的文件用POST上传到服务器。

PUT方法
HTTP协议文件上传的标准方法是使用PUT,此时curl命令使用-T参数:
curl -T uploadfile www.freeoa.net/receive.cgi

在curl中设置自定义的HTTP头

当你使用curl向一个URL发送HTTP请求的时候,它会使用一个默认只包含必要的头部字段(如:User-Agent, Host, and Accept)的HTTP头。浏览器与Web服务器是通过http协议通讯的,而http请求头中包含了客户端的一些信息,其中包括:浏览器类型、当前页面的来源页面,cookies等。

在一些个例中,或许你想要在一个HTTP请求中覆盖掉默认的HTTP头或者添加一个新的自定义头部字段。例如,你或许想要重写“HOST”字段来测试一个负载均衡,或者通过重写"User-Agent"字符串来假冒特定浏览器以解决一些访问限制的问题。为了解决所有这些问题,curl提供了一个简单的方法来完全控制传出HTTP请求的HTTP头。你需要的这个参数是“-H” 或者 “--header”。为了定义多个HTTP头部字段,"-H"选项可以在curl命令中被多次指定。

例如:以下命令设置了3个HTTP头部字段。也就是说,重写了“HOST”字段,并且添加了两个字段("Accept-Language" 和 "Cookie")
$ curl -H 'Host: 192.168.20.111' -H 'Accept-Language: zh_cn' -H 'Cookie: ID=2950' http://www.freeoa.net

对于"User-Agent", "Cookie", "Host"这类标准的HTTP头部字段,通常会有另外一种设置方法。curl命令提供了特定的选项来对这些头部字段进行设置:
-A (or --user-agent): 设置 "User-Agent" 字段.
-b (or --cookie): 设置 "Cookie" 字段.
-e (or --referer): 设置 "Referer" 字段.
-H:指定其他头字段/自定义头字段

例如,以下两个命令是等效的,这两个命令同样都对HTTP头的"User-Agent"字符串进行了更改。
$ curl -H "User-Agent: my browser" http://www.freeoa.net
$ curl -A "my browser" http://www.freeoa.net
$ curl -e qq.com -A Spada1.0 -H "Authed: yes" http://www.freeoa.net/news.psp

构造的请求是这样的:
GET / HTTP/1.1
User-Agent: Spada1.0
Host: www.freeoa.net/
Accept: */*
Referer: qq.com
Authed: yes

显示HTTP头信息
-I: 只显示响应头信息
-i: 同时显示响应头和响应数据
-D log.txt: 显示响应数据并将响应头保存

数据读取范围(RANGES)
curl -r 0-9 http://www.freeoa.net  //读取最开始的10个字节
curl -r -10 http://www.freeoa.net/  //读取最后的10个字节

文件下载/断点续传
-o filename:指定本地保存文件名称
-O:本地保存文件使用默认名称
-C -:断点续传

curl -C - -O http://dl.org/file.7z

过程信息/调试信息显示
curl -v http://www.freeoa.net/
curl --trace log.txt http://www.freeoa.net/
curl --trace-ascii log-ascii.txt http://www.freeoa.net/


来路伪装(referer)

从A页面点击进入B页面,那B页面的来路就是A页面的URL。伪装来路十分简单,有两种方法:1、使用上面的"--referer"参数或"-e参数";2、直接使用"-H"参数设置http头,下面分别介绍两种方法。

curl -e or curl --referer

-e, --referer <URL>
(HTTP) Sends the "Referrer Page" information to the HTTP server. This can also be set with the -H, --header flag of course. When used with -L, --location you can append ";auto" to the --referer URL to make curl automatically set the previous URL when it follows a Location: header. The ";auto" string can be used alone, even if you don't set an initial --referer.

1)、"-e/--referer"参数方式:
# 告诉http服务器,我是从qq.com来的
curl -v -e http://qq.com  http://www.freeoa.net

# 告诉http服务器,我是从baidu.com搜"freeoa"关键词点进来的
curl --referer https://www.baidu.com/s?wd=freeoa  http://www.freeoa.net
 
2)、"-H"参数的方式:
# 告诉http服务器,我是从163过来的
curl -H "Referer: http://www.163.com"  http://www.freeoa.net

浏览器伪装(user-agent)

浏览器对应的"User-Agent"字符串。可以直接在Chrome中的"开发者工具"的"网络"标签查看http请求头获得。获得对应浏览器的"User-Agent"字符串后,同样可以通过两种方式告诉http服务器我用的浏览器类型:
1)、"-A/--user-agent"参数方式:
# 告诉http服务器,我是通过微信内置浏览器访问
# UA='Mozilla/5.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Mobile/18A365 MicroMessenger/6.0 NetType/WIFI';
# curl -A "$UA" http://www.freeoa.net
 
# 告诉http服务器,我是通过Firefox浏览器访问
# UA='Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0';
# curl --user-agent "$UA" http://www.freeoa.net

2)、"-H"参数方式:
# 告诉网站,我是百度蜘蛛爬取
# UA="Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)";
# curl -H "User-Agent: $UA" http://www.freeoa.net

数据提交简介

URL encoding

Percent-encoding, also known as URL encoding, is technically a mechanism for encoding data so that it can appear in URLs. This encoding is typically used when sending POSTs with the application/x-www-form-urlencoded content type, such as the ones curl sends with --data and --data-binary etc.

The command-line options mentioned above all require that you provide properly encoded data, data you need to make sure already exists in the right format. While that gives you a lot of freedom, it is also a bit inconvenient at times. To help you send data you have not already encoded, curl offers the --data-urlencode option. This option offers several different ways to URL encode the data you give it.

Can use it like --data-urlencode data in the same style as the other --data options. To be CGI-compliant, the data part should begin with a name followed by a separator and a content specification. The data part can be passed to curl using one of the following syntaxes:

"content": This will make curl URL encode the content and pass that on. Just be careful so that the content does not contain any = or @ symbols, as that will then make the syntax match one of the other cases below!

"=content": This will make curl URL encode the content and pass that on. The initial '=' symbol is not included in the data.

"name=content": This will make curl URL encode the content part and pass that on. Note that the name part is expected to be URL encoded already.

"@filename": This will make curl load data from the given file (including any newlines), URL encode that data and pass it on in the POST.

"name@filename": This will make curl load data from the given file (including any newlines), URL encode that data and pass it on in the POST. The name part gets an equal sign appended, resulting in name=urlencoded-file-content. Note that the name is expected to be URL encoded already.



HTTP 的 POST 请求通常是用于提交数据,可以通过这篇文章来了解各种提交方式:四种常见的 POST 提交数据方式。做 Web 后端开发时,不可避免地要自己给自己发请求来调试接口,这里要记录的内容是如何使用命令行工具 curl 来进行各种方式的 POST 请求。

1、application/x-www-form-urlencoded

最常见的一种 POST 请求,用 curl 发起这种请求也很简单。
$ curl localhost:3000/api/basic -X POST -d 'hello=world'

2、multipart/form-data

这种请求一般涉及到文件上传,后端对这种类型请求的处理也复杂一些。

$ curl localhost:3000/api/multipart -F raw=@raw.data -F hello=world

3、application/json

$ curl localhost:3000/api/json -X POST -d '{"hello": "world"}' --header "Content-Type: application/json"

跟发起 application/x-www-form-urlencoded 类型的 POST 请求类似,-d 参数值是 JSON 字符串,并且多了一个 Content-Type: application/json 指定发送内容的格式。

这个例子和 application/x-www-form-urlencoded 中的例子发起的请求,到了 Web 后端经过解析后,得到的结果都是 hello: world 键值对。

4、将文件内容作为要提交的数据

如果要提交的数据不像前面例子中只有一个'hello: world'键值对,数据比较多,都写在命令行里很不方便,也容易出错,那么可以把数据内容先写到文件里,通过 -d @filename 的方式来提交数据。这是 -d 参数的一种使用方式,所以前面用到 -d 参数的地方都可以这样用。

实际上就是把 -d 参数值写在命令行里,变成了写在文件里。跟 multipart/form-data 中上传文件的 POST 方式不是一回事。@符号表明后面跟的是文件名,要读取这个文件的内容作为 -d 的参数。

例如,有一个 JSON 文件 data.json 内容如下:
{
    "hello": "world",
    "site": "freeoa",
    "sets": ["net", "org"]
}

就可以通过
$ curl localhost:3000/api/json -X POST -d @data.json --header "Content-Type: application/json"

来提交数据。

如果要用 application/x-www-form-urlencoded 方式提交,后端解析出来同样的数据,那么 -d 的参数是这样的(注意数组参数的写法)
hello=world&site=freeoa&sets[]=net&sets[]=org

把这个字符串直接作为 -d 的参数或者把它写到文件 data.txt 然后通过 -d @data.txt 的方式,发起 POST 请求,行为和结果是一样的。

$ curl localhost:3000/api/basic -X POST -d 'hello=world&site=freeoa&sets[]=net&sets[]=org'
$ curl localhost:3000/api/basic -X POST -d @data.txt

Request Type
-X POST
-X PUT

content type header
-H "Content-Type: application/x-www-form-urlencoded"
-H "Content-Type: application/json"

data
form urlencoded: -d "param1=value1&param2=value2" or -d @data.txt
json: -d '{"key1":"value1", "key2":"value2"}' or -d @data.json

POST application/x-www-form-urlencoded

application/x-www-form-urlencoded is the default:
curl -d "param1=value1&param2=value2" -X POST http://localhost:3000/data

explicit:
curl -d "param1=value1&param2=value2" -H "Content-Type: application/x-www-form-urlencoded" -X POST http://localhost:3000/data

with a data file

curl -d "@data.txt" -X POST http://localhost:3000/data

POST application/json

curl -d '{"key1":"value1", "key2":"value2"}' -H "Content-Type: application/json" -X POST http://localhost:3000/data

with a data file

curl -d "@data.json" -X POST http://localhost:3000/data

data.json
{
  "key1":"value1",
  "key2":"value2"
}


data.txt
param1=value1&param2=value2


表单处理之Post Json

使用出curl发送json body时,需要加header -H 'Content-Type: application/json' ,否则content type就是application/x-www-form-urlencoded,那么这时候后端的@RequestBody是接收不到的,这点一定要注意。

curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"id":100}' http://host.freeoa.net/addart

curl --header "Content-Type: application/json" --request POST --data '{"username":"xyz","password":"xyz"}' http://localhost:3000/api/login

curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"id":100}' http://localhost/api/postJsonReader.do

curl -v -i -X POST -H "Content-Type: application/json; charset=UTF-8" -d "{\"key\":\"val\"}" http://localhost:8080/appname/path

curl -v -XPOST -d '{"areaCode":"510"}' 'http://172.16.13.200/api/deptServiceOpenRest/deptHandler'

Note that -request POST is optional if you use -d, as the -d flag implies a POST request.

-H is short for --header, -d for --data

use -H 'Accept: application/json' to add accept type header

use -H 'Content-Type: application/json' to add content type header

Try to put your data in a file, say body.json and then use:
curl -H "Content-Type: application/json" --data @body.json http://localhost:8080/ui/webapp

带验证提交
curl -v --proxy '' --basic -u FreeOA:password -X POST -H "Content-Type: application/json" \
--data-binary '{"value":"30","type":"Tip 3","Module":"T3","Group":null,"name":"Dog 3","description":null,"identity":"Deneme 3","version":2,"systemId":3,"active":true}' http://my.freeoa.net/post

curl -XPOST your_address/api -F comment='{"who":"some_one", "desc":"get it"}'

文件上传
curl -T - ftp://site.org/data.txt //从stdin读取内容并上传保存为data.txt(数据输入后回车)
echo "xxxxx" | curl -T - ftp://site.org/data.txt //从stdin读取内容并上传保存为data.txt
curl -T filename ftp://site.org/ //上传本地文件
curl -T filename -u user:pass ftp://site.org/ //上传本地文件,指定ftp服务器的身份验证信息
curl -T filename ftp://site.org/data.txt //上传本地文件,远程名称为data.txt
curl -a -T filename ftp://site.org/data.txt //上传本地文件,上传内容会追加到原始远程文件之后

curl和wget都支持限制下载速度,手册页中直接提到了这两个选项。

--limit-rate <speed>
Specify the maximum transfer rate you want curl to use. This feature is useful  if you  have a limited pipe and you'd like your transfer not to use your entire bandwidth. The given speed is measured in bytes/second, unless a suffix is appended.  Appending  'k'  or 'K' will count the number as kilobytes, 'm' or M' makes it megabytes, while 'g' or 'G' makes it gigabytes. Examples: 200K, 3m and 1G.

例如: curl --limit-rate 431K

man of curl: --limit-rate specify the maximum transfer rate you want curl to use. This feature is useful if you have a limited pipe and you'd like your transfer not to use your entire bandwidth.

The  given speed is measured in bytes/second, unless a suffix is appended.  Appending 'k' or 'K' will count the number  as  kilo-bytes,  'm'  or M' makes it megabytes, while 'g' or 'G' makes it gigabytes. Examples: 200K, 3m and 1G.

The given rate is the average speed counted  during  the  entire transfer. It means that curl might use higher transfer speeds in short bursts, but over time it uses no more than the given rate.

If you also use the -Y/--speed-limit option, that option will take precedence and might cripple the rate-limiting slightly, to help keeping the speed-limit logic working.

If this option is used several times, the last one will be used.

关于更多对http的操作,可以参考其官方文档

wget与curl主要区别在于:
wget它的主要优点是它具有递归下载功能。
wget仅命令行,没有lib或任何东西,但是curl的功能由libcurl支持。
curl支持FTP,FTPS,HTTP,HTTPS,SCP,SFTP,TFTP,TELNET,DICT,LDAP,LDAPS,FILE,POP3,IMAP,SMTP,RTMP和RTSP。wget支持HTTP,HTTPS和FTP。
curl可以比wget在更多的平台上构建和运行。
wget在自由软件copyleft许可证(GPL)下发布,curl根据自由软件许可许可证(MIT衍生产品)发布。
curl提供上传和发送功能,wget仅提供纯HTTP POST支持。

可以在以下链接中查看更多详细信息:curl vs wget

测试Web服务器的trace/track方法

1)、使用curl工具
curl -v -X TRACE http://www.yourserver.com

Running it against an Apache server with TraceEnable Off correctly returns HTTP/1.1 405 Method Not Allowed

This also works on HTTPS sites, provided that cURL has the correct information supplied to the SSL layer. This is the lazy man's check of Google
curl --insecure -v -X TRACE https://www.google.com/

Web服务器如果禁用了trace方法,则会为客户端返回405错误。

2)、openssl
openssl s_client -connect example.com:443

TRACE / HTTP/1.1
host: example.com    (press enter twice)
或者
OPTIONS / HTTP/1.1
host: example.com

使用gnutls同理,比curl要麻烦一点。

3)、netcat
nc www.myhost.com 80
TRACE /mypage.html HTTP/1.1
Host: www.myhost.com

返回
HTTP/1.1 405 Method Not Allowed
Server: Apache-Coyote/1.1
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1
Content-Type: text/html;charset=utf-8
Content-Length: 1125

4)、perl的http-tools

关于trace选项参数

curl offers two other options that you use instead of -v.
--trace [filename] will save a full trace in the given file name. You can also use '-' (a single minus) instead of a file name to get it passed to stdout. You would use it like this:
$ curl --trace dump.rs http://example.com
Copied!
When completed, there is a 'dump.rs' file that can turn out pretty sizable. 不过输出默认为16进制,可以使用--trace-ascii [filename]来将输出友好可读的形式。

--trace-time:输出时间度量

一次性下载多个文件
download the response output in a file named as the remote file using the -O (--remote-name) option

1.使用for语句
for user_id in {1,2};
do
    curl -s -O -XGET https://reqres.in/api/users/$user_id
done

2.--remote-name-all
use the --remote-name-all option over the multiple -O (–remote-name) options for downloading multiple files

curl -v --remote-name-all http://192.168.8.1/bin/{monsys.pl,record.pl}

3.使用wget代替curl来完成
wget utility to download multiple files using the brace syntax:
wget --quiet http://192.168.8.1/bin/{monsys.pl,record.pl}


Starting from 7.68.0 curl can fetch several urls in parallel. This example will fetch urls from urls.txt file with 3 parallel connections:
curl --parallel --parallel-immediate --parallel-max 3 --config urls.txt

urls.txt:
url = "freeoa.net"
output = "freeoa1.html"
url = "freeoa2.net"
output = "freeoa2.html"
url = "freeoa3.net"
output = "freeoa3.html"
...



该文章最后由 阿炯 于 2024-09-05 17:21:27 更新,目前是第 2 版。