Como uso o wget com uma lista de URLs e seus arquivos de saída correspondentes?

35

Suponha que seja list_of_urlsassim:

http://www.url1.com/some.txt
http://www.url2.com/video.mp4

Eu sei como usar isso com:

wget -i list_of_urls

Mas, e se o meu list_of_urlstiver isso, e todos eles retornarem arquivos adequados, como PDFs ou vídeos:

http://www.url1.com/app?q=123&gibb=erish&gar=ble
http://www.url2.com/app?q=111&wha=tcha&mac=allit

Para um único arquivo, eu poderia fazer isso:

wget -O some.txt "http://www.url1.com/app?q=123&gibb=erish&gar=ble"

Como uso wgetpara baixar essa lista de URLs e salvar os dados retornados no arquivo local apropriado?

Kit
fonte

Respostas:

33

Por padrão, o wget grava em um arquivo cujo nome é o último componente da URL que você passa para ele. Muitos servidores redirecionam URLs como http://www.url1.com/app?q=123&gibb=erish&gar=bleum URL diferente com um nome de arquivo bonito http://download.url1.com/files/something.pdf. Você pode dizer ao wget para usar o nome do URL redirecionado (ou seja something.pdf) em vez de app?q=123&gibb=erish&gar=blepassar a --trust-server-namesopção. Este não é o modo padrão porque, se usado de forma descuidada, pode levar à substituição de um nome de arquivo imprevisível no diretório atual; mas se você confia no servidor ou está trabalhando em um diretório que não contém outros arquivos preciosos, --trust-server-namesgeralmente é a coisa certa a usar.

Alguns servidores usam um Content-Dispositioncabeçalho em vez de redirecionamento para especificar um nome de arquivo. Passe a --content-dispositionopção para fazer com que o wget use esse nome de arquivo.

Portanto:

wget --content-disposition --trust-server-names -i list_of_urls

Se você ainda não está obtendo nomes de arquivos com boa aparência, pode especificar seu próprio nome. Suponha que você tenha um arquivo contendo linhas como

http://www.url1.com/app?q=123&gibb=erish&gar=ble foo.pdf
http://www.url2.com/app?q=111&wha=tcha&mac=allit bar.txt

Para fazer com que o wget faça o download dos arquivos com os nomes de arquivos especificados, supondo que não haja caracteres de espaço em branco na URL ou nos nomes dos arquivos:

err=0
while read -r url filename tail; do
  wget -O "$filename" "$url" || err=1
done <list_of_urls_and_file_names

A errvariável contém 0 se todos os downloads foram bem-sucedidos e 1 caso contrário, é possível return $errse você colocar esse trecho em uma função ou exit $errse esse trecho em uma sequência.

Se você não deseja especificar nada além dos URLs e não consegue obter nomes agradáveis ​​do servidor, pode adivinhar o tipo de arquivo e tentar obter pelo menos extensões significativas.

err=0
n=1
while read -r url; do
  if wget -O tmpfile "$url"; then
    ext=data
    case $(file -i tmpfile) in
      application/pdf) ext=pdf;;
      image/jpeg) ext=jpg;;
      text/html) ext=html;;
      text/*) ext=txt;;
    esac
    mv tmpfile "$n.$ext"
  else
    err=1
  fi
  n=$((n+1))
done

Adicione outros tipos conforme desejado. Se o seu filecomando não tiver a -mopção, deixe-o de fora e verifique o que fileretorna no seu sistema para os tipos de arquivo nos quais você está interessado. Se você possui um arquivo /etc/mime.typesno sistema, pode ler associações de tipos MIME a extensões de em vez de fornecer sua própria lista:

n=1
while read -r url; do
  if wget -O tmpfile "$url"; then
    mime_type=$(file -m tmpfile)
    ext=$(awk "$1 == \"$mime_type\" {print \$2; exit} END {print \"data\"}" /etc/mime.types)
    mv tmpfile "$n.$ext"
  else
    err=1
  fi
  n=$((n+1))
done
Gilles 'SO- parar de ser mau'
fonte
2

Você pode fazer um loop sobre as entradas no seu arquivo list_of_urls. Algo assim:

while read -r url; do
    wget -O foo $url
done < list_of_urls

Observe que você precisará adicionar sua própria maneira de determinar foopara cada entrada do list_of_urls(também, estou assumindo que este seja um arquivo no seu disco).

rahmu
fonte
Aqui está uma variação disso: crie um pequeno script com uma linha wget -O $2 $1. No arquivo list_of_urls, torne cada linha um URL, espaço em branco, um nome de arquivo (por exemplo, http://url1/blah&blah=whatever some.pdfuse o mesmo que acima, substituindo a linha wget por ./thatscript.sh $url. Nesse caso, $urlna verdade, é uma linha com uma URL e um nome de arquivo, é claro.
goldilocks
2
Variação 2: Coloque os URLs e nomes de arquivos em linhas alternadas e separadas no arquivo list_of_urls e use while read url; do read filename; wget -O $filename $url; done < list_of_urls.
Goldilocks
2

Você pode usar diretamente a wgetopção:

wget -r -i list_of_urls
Steph
fonte
Isso não funciona: -rativa o download recursivo. Os nomes dos arquivos não estão definidos corretamente.
Jofel