使用Curl命令行实用程序并行下载

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)

  • 另请注意,如果您拥有xargs的全功能版本,则可以执行以下操作:`seq 1 10 | xargs -I {} -P2 - curl -O -s'http://example.com/?page {} .html'` (3认同)

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)

  • 假设我必须下载100页...你的脚本将同时启动100个卷曲实例(可能会阻塞网络)...我们可以在任何给定的时间点执行某些操作,只有`curl`的X实例正在运行,一旦其中一个完成它的工作,脚本就会启动另一个实例...某种"作业调度"? (5认同)
  • GNU [`parallel`](https://manpages.debian.org/jessie/moreutils/parallel.1.en.html) 可以限制“jobslots”的数量。([例子](https://gist.github.com/CMCDragonkai/5914e02df62137e47f32)) (2认同)

小智 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)


rus*_*tyx 8

curl并且wget无法并行下载单个文件,但还有其他选择:


AXE*_*abs 5

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


Jon*_*lin 5

对于启动并行命令,为什么不使用古老的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即使一次下载失败也会继续下载其余文件。)