Rav*_*pta 23 unix linux shell curl
我想从一个网站下载一些页面并且我成功地使用了它,curl但我想知道如果以某种方式一次curl下载多个页面就像大多数下载管理器一样,它会加速一些事情.是否可以在curl命令行实用程序中执行此操作?
我正在使用的当前命令是
curl 'http://www...../?page=[1-10]' 2>&1 > 1.html
Run Code Online (Sandbox Code Playgroud)
在这里,我从1到10下载页面并将它们存储在一个名为的文件中1.html.
此外,是否可以curl将每个URL的输出写入单独的文件,例如URL.html,URL正在处理的页面的实际URL.
ndr*_*nen 41
我的回答有点迟了,但我相信所有现有的答案都有点短暂.我这样做的方式是xargs,它能够在子进程中运行指定数量的命令.
我将使用的单线,简单地说:
$ seq 1 10 | xargs -n1 -P2 bash -c 'i=$0; url="http://example.com/?page${i}.html"; curl -O -s $url'
Run Code Online (Sandbox Code Playgroud)
这需要一些解释.使用-n 1指令一次xargs处理单个输入参数.在此示例中,1 ... 10每个数字都单独处理.并-P 2指示xargs保持2个子进程始终运行,每个子进程处理一个参数,直到所有输入参数都已处理完毕.
您可以将其视为shell中的MapReduce.或者也许只是地图阶段.无论如何,它是一种有效的方法来完成大量工作,同时确保您不会对您的机器进行分叉.可以在shell中的for循环中执行类似的操作,但最终会进行流程管理,一旦您意识到这种使用方式xargs有多么疯狂,这似乎毫无意义.
更新:我怀疑我的示例xargs可以改进(至少在Mac OS X和带有-J标志的BSD上).使用GNU Parallel,命令也不那么笨拙:
parallel --jobs 2 curl -O -s http://example.com/?page{}.html ::: {1..10}
Run Code Online (Sandbox Code Playgroud)
nim*_*odm 26
好吧,curl这只是一个简单的UNIX进程.您可以将这些curl进程并行运行,并将其输出发送到不同的文件.
curl可以使用URL的文件名部分生成本地文件.只需使用该-O选项(man curl详情).
您可以使用以下内容
urls="http://example.com/?page1.html http://example.com?page2.html" # add more URLs here
for url in $urls; do
# run the curl job in the background so we can start another job
# and disable the progress bar (-s)
echo "fetching $url"
curl $url -O -s &
done
wait #wait for all background jobs to terminate
Run Code Online (Sandbox Code Playgroud)
小智 14
从 7.66.0 开始,该curl实用程序终于内置了对在单个非阻塞进程中并行下载多个 URL 的支持xargs,在大多数情况下,与后台生成相比,它应该更快且资源效率更高:
curl -Z 'http://httpbin.org/anything/[1-9].{txt,html}' -o '#1.#2'
Run Code Online (Sandbox Code Playgroud)
这将并行下载 18 个链接并将它们写入 18 个不同的文件,也是并行的。Daniel Stenberg 对此功能的官方公告在这里:https : //daniel.haxx.se/blog/2019/07/22/curl-goez-parallel/
Ser*_*ron 10
从7.68.0curl开始可以并行获取多个url。此示例将从具有 3 个并行连接的文件中获取 url urls.txt:
curl --parallel --parallel-immediate --parallel-max 3 --config urls.txt
Run Code Online (Sandbox Code Playgroud)
网址.txt:
url = "example1.com"
output = "example1.html"
url = "example2.com"
output = "example2.html"
url = "example3.com"
output = "example3.html"
url = "example4.com"
output = "example4.html"
url = "example5.com"
output = "example5.html"
Run Code Online (Sandbox Code Playgroud)
curl并且wget无法并行下载单个文件,但还有其他选择:
aria2(用 C++ 编写,可在 Deb 和 Cygwin 存储库中找到)
aria2c -x 5 <url>
Run Code Online (Sandbox Code Playgroud)
axel(用 C 语言编写,可在 Deb 存储库中找到)
axel -n 5 <url>
Run Code Online (Sandbox Code Playgroud)
wget2(用 C 语言编写,可在 Deb 存储库中找到)
wget2 --max-threads=5 <url>
Run Code Online (Sandbox Code Playgroud)
lftp(用 C++ 编写,可在 Deb 存储库中找到)
lftp -n 5 <url>
Run Code Online (Sandbox Code Playgroud)
hget(用 Go 编写)
hget -n 5 <url>
Run Code Online (Sandbox Code Playgroud)
pget(用 Go 编写)
pget -p 5 <url>
Run Code Online (Sandbox Code Playgroud)
Curl还可以通过将文件拆分为多个部分来加速文件的下载:
$ man curl |grep -A2 '\--range'
-r/--range <range>
(HTTP/FTP/SFTP/FILE) Retrieve a byte range (i.e a partial docu-
ment) from a HTTP/1.1, FTP or SFTP server or a local FILE.
Run Code Online (Sandbox Code Playgroud)
这是一个脚本,它将使用所需数量的并发进程自动启动curl:https: //github.com/axelabs/splitcurl
对于启动并行命令,为什么不使用古老的make命令行实用程序。它支持并行执行和依赖项跟踪等功能。
怎么样?在下载文件的目录中,创建一个名为Makefile以下内容的新文件:
# which page numbers to fetch
numbers := $(shell seq 1 10)
# default target which depends on files 1.html .. 10.html
# (patsubst replaces % with %.html for each number)
all: $(patsubst %,%.html,$(numbers))
# the rule which tells how to generate a %.html dependency
# $@ is the target filename e.g. 1.html
%.html:
curl -C - 'http://www...../?page='$(patsubst %.html,%,$@) -o $@.tmp
mv $@.tmp $@
Run Code Online (Sandbox Code Playgroud)
注意最后两行应以TAB字符(而不是8个空格)开头,否则make将不接受该文件。
现在,您只需运行:
make -k -j 5
Run Code Online (Sandbox Code Playgroud)
我使用的curl命令将输出存储在其中1.html.tmp,只有curl命令成功执行后,它将被重命名为1.html(通过mv下一行的命令)。因此,如果某些下载失败,则可以重新运行同一make命令,它将恢复/重试第一次下载失败的文件。一旦成功下载了所有文件,make将报告您无事可做,因此再运行一次以确保“安全”没有害处。
(该-k开关告诉make即使一次下载失败也会继续下载其余文件。)