Python como wget

Inspirado por este e-mail, resolvi tentar escrever um `wget -r` em Python. Com a ajuda do BeautifulSoup, bastou meia-hora para chegar numa prova de conceito bem interessante…

#!/usr/bin/env python

"""
Proof-of-concept Python implementation for `wget -r`.

Downloads only what looks like files.
That is: it isn't really recursive (yet). :)
"""

from urllib import urlopen, urlretrieve
from urlparse import urlsplit
import sys
import os

from BeautifulSoup import BeautifulSoup

URL = 'http://humberto.digi.com.br'

print "Opening", URL, "..."
b = BeautifulSoup(urlopen(URL).read())

links = [a['href'] for a in b.findAll('a')]
internal = [l for l in links if l.startswith(URL)]

# urlsplit:
#
# (u'http',
#  u'humberto.digi.com.br',
#  u'/wp-content/uploads/2008/03/delimport.png',
#  '',
#  '')

site_name = urlsplit(URL)[1]
if not os.path.isdir(site_name):
    os.mkdir(site_name)
os.chdir(site_name)

def reporthook(*a):
    sys.stdout.write('.')

for url in internal:
    # Gets only the file path, stripping first '/'
    path = urlsplit(url)[2][1:]
    print path,
    if not path or path.endswith('/'):
        # Looks like a directory, skip
        print 'skip'
        continue
    # Replicate directory structure
    dirname, fname = os.path.split(path)
    if dirname and not os.path.isdir(dirname):
        os.makedirs(dirname)

    urlretrieve(url, path, reporthook)

    print "OK"

Esse artigo é dedicado ao FTP Offline [2001-2008] da Diginet, feito em PHP com wget.

5 Responses to “Python como wget”

  1. Caio Says:

    show!

    Estou usando algo parecido, em python também, mas com mechanize ao invés do Beautiful Soap.

  2. Karlisson Says:

    Fuderoso. Testei seu código original, depois mudei a variável URL pra baixar meu site. Depois mandei baixar uma imagem e então deu erro de má formação de HTML =D

  3. humberto Says:

    Karlisson, como eu falei, o código está bem cru ainda. É só um ponto de partida para fazer algo mais interessante (como ter a opção de baixar só um arquivo, e não vários).

  4. Jonatas Oliveira Says:

    Massa. Não conhecia o BeautifulSoup. Saudades de programar em Python, é tudo tão mais… simples!

    Gostei da dedicatória. :)

  5. Rodrigo Wanderley Says:

    A idéia legal desse código é ver como é fácil extender o código como, por exemplo, converter links externos (http://foo.com/bar/arq.txt) para internos (./bar/arq.txt) basta um re.sub() no início.

    Outras coisas como criar banco de seção e resumir downloads interrompidos basta importar um ou dois módulos que fica fácil.

    Basta passar por cima do código do wget para você ter idéia das acrobacias que tem que serem feitas para implementar isto em C *sem* adicionar muitas dependências. Em Python consegue se fazer *muito* apenas usando as bibliotecas padrão.

Leave a Reply