Criando Web crawlers em Python – Parte II
Ir para Criando Web crawlers em Python – Parte I
Ir para Criando Web crawlers em Python – Parte III
No post anterior, eu mostrei como recuperar informações básicas de uma página da Web usando urllib, urllib2 e BeautifulSoup. Neste post eu mostrarei como enviar dados via GET e POST.
Há um excelente guia sobre urllib2: o urllib2 – The Missing Manual que foi de grande valia nos meus estudos. Nele, pode-se encontrar as informações sobre envio de informações do tipo GET e POST para o servidor. Isso será útil, pois é assim que a busca do SourceForge (e da maioria dos outros portais) funcionam.
Vamos dar uma olhada na URL do na pesquisa por “Python” no SF:
http://sourceforge.net/search/?type_of_search=soft&words=python
Bem, isso indica que temos que enviar duas variáveis para o SF.net: type_of_search (sempre igual à soft) e words (que é a nossa busca). Um exemplo de código que faria essa busca poderia ser esse:
base_url = 'http://sourceforge.net'
busca = raw_input('Pesquisar por: ')
variaveis_get = urllib.urlencode({'type_of_search':'soft','words':busca})
req = urllib2.Request(base_url+'/search/',variaveis_get)
response = urllib2.urlopen(req).read()
print response
Se der tudo certo, você deveráver o código fonte da página do SF que contém os resultados da pesquisa.
Feito isso, vamos analisar como a marcação do SF é organizada na busca:
O Firebug nos ajuda a não perder tanto tempo assim analisando código. De acordo com o que pudemos obter, podemos dividir as informações que queremos dessa forma:
- O resultado da busca está dentro de uma tabela com o id=”searchtable”.
- Um resultado da busca está sempre dentro de um td com classe description.
- O nome do projeto está dentro de um link dentro de um h2 dentro desse td “description”.
- O link de download se encontra na próxima td da mesma linha da tabela.
Exibindo as informações dos projetos
Agora nós temos como buscar nossa informação e como filtra-la. Como disse no post anterior, eu iria mostrar alguns usos mais avançados do BeautifulSoup, principalmente no que diz respeito à percorrer o documento. O próximo passo será mostrar as informações dos projetos que aparecem no resultado da nossa busca. Podemos fazer isso da seguinte forma:
import urllib,urllib2
base_url = 'http://sourceforge.net'
busca = raw_input('Pesquisar por: ')
variaveis_get = urllib.urlencode({'type_of_search':'soft','words':busca})
req = urllib2.Request(base_url+'/search/',variaveis_get)
response = urllib2.urlopen(req).read()
soup = BeautifulSoup(response)
# procura pela tabela com id=searchtable
tabela = soup.find('table',{'id':'searchtable'})
#retorna uma lista com todas as linhas (<tr>) da tabela
linhas_tabela = tabela.findAll('tr')
i=0
for linha in linhas_tabela:
i+=1
#encontra a primeira coluna (descricao) da linha
coluna_descricao = linha.find('td')
#o atributo contents contem uma lista com o conteudo da tag
nome_projeto = coluna_descricao.find('a').contents[0]
descricao_projeto = coluna_descricao.contents[2].strip()
print 'Projeto '+str(i)+': '+nome_projeto
print descricao_projeto
print '--------------------------------'
Legal, não? Isso é uma demonstração básica do poder que o BeautifulSoup tem para percorrer e extrair informações em (X)HTML. O mais interessante de tudo é que quase todos os métodos da classe BeutifulSoup.Tag retornam a própria referência, o que quer dizer que podemos fazer chains (cadeias) de comando como essas:
nome_do_primeiro_projeto_da_pesquisa = soup.find('table',{'id':'searchtable'}).findAll('tr')[0].find('td').find('a').contents[0]Isso é realmente muito útil quando se quer economizar código. E o mais interessante de tudo: é bem legível (mas não necessariamente fácil de interpretar… quem ler seu código assim terá que ter uma boa noção do BeautifulSoup).
Baixando os arquivos do projeto
Essa parte é relativamente fácil. O SF é um serviço muito bom, até para o nosso pequeno experimento ![]()
A URL que o link “Download Now” aponta sofre 3 redirects até o arquivo final. Tudo isso serve para o SF determinar a sua localização e apontar o mirror mais próximo de você. Então a única coisa que precisamos fazer é passar esse link para o wget (um programa bem útil para download de arquivos na Web presente na maioria das distribuições Linux. Um clone para Windows pode ser encontrado aqui) e ele irá baixar o projeto para nós. Simples, não?
Então vamos ao código:
import urllib,urllib2
from subprocess import call
base_url = 'http://sourceforge.net'
busca = raw_input('Pesquisar por: ')
variaveis_get = urllib.urlencode({'type_of_search':'soft','words':busca})
req = urllib2.Request(base_url+'/search/',variaveis_get)
response = urllib2.urlopen(req).read()
soup = BeautifulSoup(response)
# procura pela tabela com id=searchtable
tabela = soup.find('table',{'id':'searchtable'})
#retorna uma lista com todas as linhas da tabela
linhas_tabela = tabela.findAll('tr')
i=0
links_download = []
for linha in linhas_tabela:
i+=1
coluna_descricao = linha.find('td')
nome_projeto = coluna_descricao.find('a').contents[0]
link_download = linha.find('a',{'class':'downloadnow'})['href']
links_download.append(link_download)
descricao_projeto = coluna_descricao.contents[2].strip()
print 'Projeto '+str(i)+': '+nome_projeto
print descricao_projeto
print '--------------------------------'
opcao = int(raw_input('Qual projeto gostaria de baixar? '))
opcao_url = base_url+links_download[opcao-1]
call(['wget',opcao_url]) #chama o wget com o link para download
A única coisa que eu fiz de novo foi adicionar o link de download em uma lista e perguntar ao usuário qual projeto ele deseja baixar. Então, eu passei o link de download para o wget que fez o serviço de baixar o arquivo pra mim. Pronto! Nosso crawler de exemplo do SF.net está pronto ![]()
No proximo post eu mostrarei como guardar valores de sessão para percorrermos páginas protegidas por senha. See ya!


[...] Ir para: Criando Web Crawlers em Python – Parte II [...]
Criando Web crawlers em Python – Parte I « Herberth Amaral
7 Mar 10 at 11:49
Estou acompanhando esta série de posts religiosamente. É interessante esta abordagem de construir algo passo a passo, é motivador aprender coisas novas a medida que se progride em algum projeto. Vejo vocês nos próximos episo… Digo, posts !
Edmar Ferreira
7 Mar 10 at 18:48
Créu velocidade 2! (vai até o 5?)
Mto bacana a série de posts, mesmo pra alguém q é leigo em Python como eu.
Keep good work!
Elvis Guimarães
8 Mar 10 at 20:10
hahahaha, depende.
Se vc tiver usando multithread vai até a velocidade 64, ou 128 ou sei lá
A minha intenção é ir até o 5º post, mas vai depender do assunto e da empolgação
herberthamaral
8 Mar 10 at 21:00
[...] parte II desta série de tutoriais, eu mostrei como criar um mini crawler para o SourceForge.net, com [...]
Criando Web crawlers em Python - Parte III | Herberth Amaral
22 Mar 10 at 14:01
[...] Web crawlers (distribuidos) em Python – Parte IVOutros posts da série:Parte IParte IIParte IIINa parte III eu mostrei como criar um simples sistema de recuperação de informações [...]
Criando Web crawlers (distribuidos) em Python - Parte IV | Herberth Amaral
6 May 10 at 10:35
Muito bom este seu post, Herberth. Já clareou muita coisa para mim. O tema principal do meu trabalho de diplomação é recuperação da informação e vou precisar de um pequeno web crawler e python era uma das minha opções, pois é suportado pelo Google Apps Engine. Só gostaria de saber as referências que você utilizou, se não for pedir muito, afinal tenho de documentar tudo.
De qualquer forma, já foi de muita ajuda. O início é muito complicado, há tantas possibilidades. Acho que Python rodando nos servidores Google vai ser a melhor saída. Tenho de ver como as instâncias vão representar na quota gratuita. rsrsrs, o problema agora é a base de dados. O Google Apps Engine usa um sistema de armazenamento próprio. Vou ter de fazer um benchmark, porque não sei se vai “compensar” usar um servidor remoto para fugir do padrão do GEngine.
Muito obrigado.
messala
24 Jun 10 at 17:36
Olá Messala,
Eu não utilizei nenhuma referência ‘acadêmica’ no crawler, mas os seguintes conteúdos foram de muita ajuda:
http://www.voidspace.org.uk/python/articles/urllib2.shtml (urllib2: The Missing Manual)
http://www.crummy.com/software/BeautifulSoup/ (BeautifulSoup – documentação oficial)
Você pode achar esses links no texto também.
De qualquer forma, eu recomendo o uso do BeautifulSoup se você não precisar mexer com o software no futuro, pois ele está entrando em depreciação. Uma boa alternativa é o lxml: http://codespeak.net/lxml/
Até mais!
Herberth Amaral
24 Jun 10 at 18:05
Muito obrigado pela atenção.
Nessa nossa área, as ferramentas que utilizamos estão sempre à mercê do desuso. Obrigo pelo conselho.
Boa tarde e bom trabalho.
messala
24 Jun 10 at 18:46