Czy istnieje równoległy wget? Coś w stylu fping, ale tylko do pobierania?

15

Znalazłem tylko puf (moduł pobierania równoległego adresu URL), ale nie mogłem zmusić go do odczytania adresów URL z pliku; coś jak

 puf < urls.txt

też nie działa.

System operacyjny zainstalowany na serwerze to Ubuntu.

Moonwalker
źródło
Można to zrobić za pomocą biblioteki Python i pycurl oraz odrobiny logiki kleju w skrypcie. Ale nie znam do tego „konserwowego” narzędzia.
Keith
@Keith Czy to podejście jest lepsze niż używanie biblioteki asynchronicznej jako gevent w urllib?
Moonwalker
Urllib nie jest przeznaczony do używania asynchronicznego. Libcurl ma własną pętlę asynchroniczną i może być skonfigurowany do wykonywania co najmniej 1000 jednoczesnych pobrań przy użyciu interfejsu „multi”.
Keith,
@ Keith Podoba mi się twoja odpowiedź, więc czy mógłbyś napisać ją jako „prawdziwą” odpowiedź, aby ją należycie uznać?
Moonwalker,

Odpowiedzi:

25

Używając GNU Parallel ,

$ parallel -j $ {jobs} wget <urls.txt

lub xargsz GNU Findutils ,

$ xargs -n 1 -P $ {jobs} wget <urls.txt

gdzie ${jobs}jest maksymalna ilość wgetchcesz, aby uruchomić jednocześnie (ustawienie -naby 1dostać jedną wgetinwokację w każdym wierszu urls.txt). Bez -j/ -P, parallelbędzie uruchamiać tyle zadań jednocześnie, ile rdzeni procesora (co niekoniecznie ma sens w przypadku wgetograniczenia przez sieciowe operacje we / wy) i xargsbędzie uruchamiane jedno po drugim.

Jedną z fajnych funkcji, która parallelma już za sobą, xargsjest oddzielenie wyników równolegle uruchomionych zadań, ale jeśli nie przejmujesz się tym, xargsistnieje większe prawdopodobieństwo, że zostaną wstępnie zainstalowane.

efemeryczny
źródło
Optymalne jobszależy od wielu czynników: opóźnienia ścieżki, przepustowości ścieżki, zasad serwera zdalnego itp.
dhchdhd
2

Możesz to zaimplementować za pomocą Pythona i biblioteki pycurl. Biblioteka pycurl ma interfejs „multi”, który implementuje własną parzystą pętlę, która umożliwia wiele jednoczesnych połączeń.

Jednak interfejs jest raczej podobny do C, a zatem nieco nieporęczny w porównaniu z innym, bardziej „Pythonowym” kodem.

Napisałem dla niego opakowanie, które tworzy na nim bardziej kompletnego klienta podobnego do przeglądarki. Możesz użyć tego jako przykładu. Zobacz moduł pycopia.WWW.client . HTTPConnectionManager otacza interfejs wielofunkcyjny.

Keith
źródło
2

Działa to, i nie będzie lokalne ani zdalne DoS, przy odpowiednich dostosowaniach:

(bandwidth=5000 jobs=8; \
 parallel      \
   --round     \
   -P $jobs    \
   --nice +5   \
   --delay 2   \
   --pipepart  \
   --cat       \
   -a urls.txt \
     wget                                \
       --limit-rate=$((bandwidth/jobs))k \
       -w 1                              \
       -nv                               \
       -i {}                             \
)
dhchdhd
źródło
1

Część strony podręcznika GNU Parallel zawiera przykład równoległego rekurencyjnego wgeta.

https://www.gnu.org/software/parallel/man.html#EXAMPLE:-Breadth-first-parallel-web-crawler-mirrorer

HTML jest pobierany dwukrotnie: raz w celu wyodrębnienia linków i raz w celu pobrania na dysk. Inne treści są pobierane tylko raz.

Jeśli nie potrzebujesz rekurencyjności, odpowiedź efemerii wydaje się oczywista.

Ole Tange
źródło
Tylko spóźniona informacja, że ​​każde „rozwiązanie” równoległe plus wget jest z natury nieefektywne, ponieważ wymaga dwukrotnego pobierania zawartości , powolnego z powodu pobierania wielu faz, a także nie jest przyjemne dla sysopsów, którzy muszą płacić za całe marnowanie przepustowości, ponieważ nie używaj wydajnego rozwiązania.
dhchdhd
0

Ofiary twojego pobierania równoległego nie będą rozbawione: oczekują, że jedno połączenie będzie obsługiwać każdego klienta, a skonfigurowanie kilku połączeń oznacza ogólnie mniej klientów. (Tj. Jest to uważane za niegrzeczne zachowanie).

vonbrand
źródło
1
Ale może pobierał pliki z różnych serwerów, więc to nie miałoby zastosowania.
Renan
Oprócz tego, co powiedział @vonbrand, można uzyskać coś w rodzaju „Zbyt wielu połączeń” i nie można pobrać wszystkich plików. I może być nieco wolniejszy (na przykład ponowne użycie jednego połączenia HTTP w porównaniu do utworzenia kilku połączeń HTTP)
golimar
2
Tak długo, jak utrzymujesz rozsądny numer, nie jest to wielka sprawa. Np. W momencie pisania tego tekstu Firefox używał 15 połączeń na serwer, gdy nie korzystał z połączeń trwałych (od tego czasu zmieniono na próbowanie połączeń trwałych, które są ograniczone do 6 na serwer). Inne przeglądarki używają podobnych liczb.
derobert