2011-12-26 20 views
22

Bir web sitesinden bazı sayfaları indirmek istiyorum ve ben başarıyla curl kullanarak yaptım ama indirme yöneticilerinin çoğu gibi bir seferde birden çok sayfa curl indirme eğer merak ediyorum İşleri biraz hızlandırın. curl komut satırı yardımcı programında bunu yapmak mümkün mü?Curl komut satırı yardımcı programını kullanarak paralel indirme

kullanıyorum geçerli komut Burada 1'den 10'a kadar sayfaları indirerek ve 1.html adlı bir dosyada saklayarak am

curl 'http://www...../?page=[1-10]' 2>&1 > 1.html 

olduğunu. Ayrıca, curl'un, her URL'nin çıkışını URL.html dosyaya ayırmak mümkün mü, URL, işlemdeki sayfanın gerçek URL'sidir.

+0

İçerik uzunluğunu bulmak için önceden istekte bulun, tekil çoklu yüklemeleri birleştirmek, çok işlemli geçiş yapmak, parçaların sırasını korumak ve sıralı sırada olduğunuz sırada onlara katılmak için '--range' komutunu kullanın. Çoğu geliştiricinin yaptığı şeydir (örneğin: [htcat projesi] (https://github.com/eladkarako/htcat)) –

cevap

22

Eh, curl sadece basit bir UNIX işlemidir. Paralel olarak çalışan ve çıktılarını farklı dosyalara gönderen bu curl işlemlerinin çoğuna sahip olabilirsiniz. Yerel dosyayı oluşturmak için URL'nin dosya adı kısmını Sadece -O seçeneğini kullanın (detaylar için man curl).

Aşağıdaki

gibi bir şey kullanabilirsiniz
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 
+3

100 sayfa indirmek zorunda olduğumu varsayalım ... scriptiniz aynı anda 100 kuruş örneğine başlayacaktır (Şebekeyi tıkayabilir) ... herhangi bir zamandaki gibi bir şey yapabilir miyiz, yalnızca X kıvrımları koşuyor ve bir tanesi işini bitirir bitirmez, senaryo başka bir örneği başlatıyor ... iş çizelgeleme 'tür? Yine de cevap için –

+0

+1. –

+0

Ravi .. bu daha zorlaşıyor. Birden çok işlem tarafından sunulan bir iş kuyruğuna ihtiyacınız var. Basit bir çözüm, tüm işleri UNIX 'batch' komutuna göndermektir ('man batch' deneyin). Sistem yükü belirli bir eşiğin altında olduğunda işleri yürütür. Bu yüzden çoğu iş sıraya konacak ve bir seferde sadece birkaç tanesi çalışıyor olacak. – nimrodm

0

Kıvrılma konusunda emin değilim, ancak bunu wget kullanarak yapabilirsiniz.

wget \ 
    --recursive \ 
    --no-clobber \ 
    --page-requisites \ 
    --html-extension \ 
    --convert-links \ 
    --restrict-file-names=windows \ 
    --domains website.org \ 
    --no-parent \ 
     www.website.org/tutorials/html/ 
4

Curl da parçaya bölerek bir dosyanın indirilmesini hızlandırabilir : Burada

$ 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. 

otomatik bukle ile başlatacak bir script Eşzamanlı işlemlerin istenen sayısı: https://github.com/axelabs/splitcurl

2

Paralel komutların başlatılması için, neden saygıdeğer make c'yi kullanmayın? ommand çizgi programı .. Parallell yürütme ve bağımlılık takibi ve neyi destekler.

Nasıl? Dosyaları indirirken dizininde, aşağıdaki içeriğe sahip bir yeni adlı dosyayı Makefile oluşturun:

# 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 
# [email protected] is the target filename e.g. 1.html 
%.html: 
     curl -C - 'http://www...../?page='$(patsubst %.html,%,[email protected]) -o [email protected] 
     mv [email protected] [email protected] 

NOT son iki satır, bir sekme karakteriyle başlar (yerine 8 boşluk) gerekir ya da irade yapmak dosyayı kabul etmiyor.

Şimdi

sadece çalıştırın:

make -k -j 5 

ben 1.html.tmp yılında çıktı depolar ve bukle komut ardından başarılı yalnızca bir sonraki satırda mv komutuyla 1.html (ile yeniden adlandırılır kullanılan bukle komut). Bu nedenle, bazı indirme başarısız olursa, aynı make komutunu yeniden çalıştırabilirsiniz ve ilk kez indirilemeyen dosyaları indirmeye/yeniden yüklemeye devam edecektir. Tüm dosyalar başarıyla indirildikten sonra, yapılacak daha fazla bir şey olmadığını bildirirsiniz, bu nedenle "güvenli" olmak için bir kez daha çalışmanın bir zararı yoktur.

(-k anahtarı bile tek indir arızalanması durumunda dosyaların geri kalanını indirirken tutmak için yapmak söyler.)

+0

"-j 5", paralel olarak en fazla 5 kıvrım komutunu çalıştırmayı söyler. –

+0

Başarısız indirme işlemine devam etmesine izin verdiği ve herhangi bir unix sisteminde hem sağlam hem de kullanılabilir olan 'make' kullanıldığından, gerçekten en iyi çözüm. – nimrodm

31

Benim cevabım biraz geç, ama mevcut tüm cevapları sadece biraz düşmek inanıyoruz kısa. Bu gibi şeyler yapma biçimim, alt işlemlerde belirli sayıda komut çalıştırabilen xargs ile ilgilidir. Ben kullanacağı

tek satırlık basit geçerli:

$ seq 1 10 | xargs -n1 -P2 bash -c 'i=$0; url="http://example.com/?page${i}.html"; curl -O -s $url' 

Bu, bazı açıklama garanti. -n 1 kullanımı, bir kerede tek bir giriş bağımsız değişkenini işlemek için xargs bildirir. Bu örnekte, 1 ... 10 numaralarının her biri ayrı ayrı işlenir. Ve -P 2, her bir giriş bağımsız değişkeni işleninceye kadar, her biri tek bir bağımsız değişkenle ilgilenen 2 alt işlemin her zaman çalışmasını sağlamak için xargs bildirir.

Bunu MapReduce olarak kabukta düşünebilirsiniz. Ya da belki sadece Harita aşaması. Ne olursa olsun, makinenizi bombaladığınızdan emin olmadan çok fazla iş yapmanın etkili bir yoludur. Bir kabukta bir döngüde benzer bir şey yapmak mümkündür, ancak bu yönetimin, xargs'un bu harika kullanımının ne kadar harika olduğunu anladıktan sonra oldukça anlamsız görünmeye başlayan süreç yönetimini gerçekleştirin.

Güncelleme: xargs numaralı örneğimin geliştirilebileceğinden şüpheleniyorum (en azından Mac OS X ve -J bayrağındaki BSD). GNU Parallel'in ile komut yanı biraz daha az hantaldır: Sisteminiz pidof veya pgrep gibi komutlar varsa sürecinin sınırlı sayıda kolaydır

parallel --jobs 2 curl -O -s http://example.com/?page{}.html ::: {1..10} 
+3

Ayrıca, xargs'ın tam özellikli bir sürümüne sahipseniz, aşağıdakileri de yapabilirsiniz: 'seq 1 10 | xargs -I {} -P2 - curl -O -s 'http://example.com/?page {} .html' – Six

2

Run, bir süreç adı verilen (pids dönmek Kaç kişi çalıştıklarını anlatıyor. Böyle

şey:

#!/bin/sh 
max=4 
running_curl() { 
    set -- $(pidof curl) 
    echo $# 
} 
while [ $# -gt 0 ]; do 
    while [ $(running_curl) -ge $max ] ; do 
     sleep 1 
    done 
    curl "$1" --create-dirs -o "${1##*://}" & 
    shift 
done 

böyle çağırmak için:

script.sh $(for i in `seq 1 10`; do printf "http://example/%s.html " "$i"; done) 

script bukle hat test edilmedi.

İlgili konular