Fazendo o download com wget sem saber o índice final

1

Estou baixando algumas medidas com o wget, que estão na forma de

http://www.somewhere.com/sub-somewhere052/image0001.jpg  
http://www.somewhere.com/sub-somewhere052/file0001.txt  

até

http://www.somewhere.com/sub-somewhere052/image0099.jpg  
http://www.somewhere.com/sub-somewhere052/file0099.txt  

O problema é que esses dois números mudam de teste para teste (este foi o teste 052 ), e cada teste tem um número de arquivos desconhecido (adiantado para mim). No entanto, todos eles são chamados da mesma coisa (eles não são chamados em algum lugar , é claro) e isso é conhecido.

Como posso fazer com que o wget "passe por" sub-somewhere001 / image0001.jpg para imagexxxx.jpg (onde xxxx é desconhecido), até que ele atinja o arquivo que não existe mais, e então mova para (após filexxxx.txt) para somewhere002 / ... e assim por diante?

Em suma, como lidar com a situação "vá até que não haja mais nada"?

    
por Rook 09.03.2012 / 04:45

2 respostas

3

A partir de man wget , você pode ver que ele usa a convenção usual de valor de retorno do Unix - 0 significa que nenhum erro, qualquer outra coisa é um erro. Contanto que você não espere outros tipos de erros (por exemplo, falha na rede ou coisas assim), ou seja, você espera que, se não fizer o download de qualquer coisa, significa que não há arquivo, você pode usar algo assim:

get_tf_simulated() {
  t=$1
  if [ $t -lt 3 ]; then
    f=$3
    s=$((2 * $t))
    if [ $f -lt $s ]; then
      return 0
    fi
  fi
  return 1
}

get_tf_real() {
  tp=$2
  fp=$4
  inf=$5
  ext=$6
  # Get http://example.com/test<test number>/<image or file><file number>.<jpg or txt>
  wget -Otest$tp_file$fp_$inf.$ext http://example.com/test$tp/$inf$fp.$ext
}

get_tf() {
  echo --- Getting $*
  get_tf_simulated $*
  #get_tf_real $*
}

get_all() {
  get_tf $t $tp $f $fp image jpg
  ret_val=$?
  if [ $ret_val -ne 0 ]; then
    return $ret_val
  fi
  get_tf $t $tp $f $fp file txt
}

for t in {1..999}; do
  tp='printf %3.3d $t'
  got_one=no
  for f in {1..9999}; do
    fp='printf %4.4d $f'
    get_all $t $tp $f $fp
    if [ $? -ne 0 ]; then
      echo Failed, going next
      break
    fi
    got_one=yes
  done
  if [ $got_one == 'no' ]; then
    echo Nothing more
    break
  fi 
done

Descomente a linha direita na função get_all . Atualmente, ele será simulado e a saída será assim (desde que você tenha salvo o acima para mkt.sh ):

$ ./mkt.sh 
--- Getting 1 001 1 0001 image jpg
--- Getting 1 001 1 0001 file txt
--- Getting 1 001 2 0002 image jpg
Failed, going next
--- Getting 2 002 1 0001 image jpg
--- Getting 2 002 1 0001 file txt
--- Getting 2 002 2 0002 image jpg
--- Getting 2 002 2 0002 file txt
--- Getting 2 002 3 0003 image jpg
--- Getting 2 002 3 0003 file txt
--- Getting 2 002 4 0004 image jpg
Failed, going next
--- Getting 3 003 1 0001 image jpg
Failed, going next
Nothing more

Nota: eu não testei o wget , mas você pode usar isso para testar em alguns arquivos:

wget -Otest$tp_file$fp_$inf.$ext http://example.com/test$tp/$inf$fp.$ext; echo $?

Basta substituir $tp , $fp , $inf e $ext , conforme necessário. por exemplo semelhante ao que você deu:

wget -Otest052_file0001_file.txt http://www.example.com/sub-somewhere052/file0001.txt; echo $?

Isso deve ecoar 8 para 404, do man wget :

8   Server issued an error response.

Se isso funcionar, o script deve funcionar, esperando que não haja erros de digitação nessa linha. :)

    
por 09.03.2012 / 06:05
0

Se o site retornar uma resposta 404 , wget definirá a variável $? como um valor diferente de zero (especificamente 8, mas quem se importa). Você pode testar isso.

Acho bash bastante confuso, então aqui está um em Python (2.7.2). Deve funcionar, mas não posso testar diretamente sem um site útil. isso depende do servidor retornar uma resposta 404 apropriada.

#! /usr/bin/python

basepath = "http://www.somewhere.com/sub-somewhere"
imgpre = "/image"
imgpost = ".jpg"
txtpre = "/txt"
txtpost = ".txt"

import os
import urllib2

directorynum = 1
filenum = 1

while True:
    pathdir = basepath + str(directorynum).zfill(3)

    if filenum == 1:
        try:
            os.makedirs(pathdir[7:])
        except OSError, e:
            print "Error creating directory: " + e.strerror

    pathimg = pathdir + imgpre + str(filenum).zfill(4) + imgpost
    pathtxt = pathdir + txtpre + str(filenum).zfill(4) + txtpost
    try:        
        print "Getting " + pathimg
        resp = respimg = urllib2.urlopen(pathimg)
        with open(pathimg[7:], "wb") as f:
            f.write(respimg.read())

        print "Getting " + pathtxt
        resp = resptxt = urllib2.urlopen(pathtxt)
        with open(pathtxt[7:], "w") as f:
            f.write(resptxt.read())

        filenum += 1

        continue
    except urllib2.HTTPError, e:
        if e.code == 404:
            print "Error: 404"
            print "Got " + str(filenum - 1) + " from directory " + str(directorynum) + ", incrementing directory."
            directorynum += 1
            filenum = 1
            continue
        else:
            print "An unexpected error (" + resp.code + resp.msg + ") has occurred."
            break

Ele também deve rodar bem no Windows (é só se livrar do arquivo #! /usr/bin/python e salvar como .py , embora um interpretador python deva ser instalado)

    
por 09.03.2012 / 07:01