Chico-Espertice 0 – 1 Python

Às vezes chego a uma página qualquer e é-me impossibilitado um simples copy-paste do conteúdo. Fico doido. Especialmente quando se trata de uma página cheia de publicidade não-solicitada e não-evitável que tem zero direitos sobre o conteúdo que alberga.

Aconteceu-me isso hoje numa página de letras de músicas do site Metrolyrics. Como detesto estas merdices, fica aqui um exemplo curto de Python e o seu uso para ler páginas web, e o módulo re (expressões regulares) para extrair e substituir padrões.

Comecemos por usar o módulo urllib2 para descarregar a página. Na verdade, descarregamos o código-fonte da página o que é exactamente o que eu quero.

import urllib2

link="www.metrolyrics.com/one-and-only-lyrics-adele.html"
pag=urllib2.urlopen(link)

Tendo a informação da página na variável pag, temos que extrair o que queremos. Ora, como os senhores do MetroLyrics se acham espertos, em vez de terem o texto simples na página decidiram codificá-lo em código ASCII. Na verdade, até simplificam o trabalho para extrair a letra! Usando expressões regulares, podemos facilmente filtrar toda a informação. Sem entrar em detalhes, expressões regulares, ou RE (de regular expressions) é uma espécie de mini-linguagem de programação cuja existência tem o único propósito de encontrar padrões em texto.

Em Python, precisamos do módulo re para as usar. Não é fácil, mas com jeitinho são bastante úteis e eficientes, e evitam múltiplas chamadas das funções split(), strip(), e replace(). Em primeiro lugar, há que definir a expressão que queremos procurar. Há toda uma sintaxe própria para as expressões regulares, mas como este caso é relativamente simples, o exemplo é fácil de perceber. Sabendo que cada caracter foi codificado em ASCII (que são entre 2 e 3 números), e empacotado entre &# e ; (e.g. G) vamos procurar por combinações de 2 ou 3 numeros que estejam entre estes caracteres. Por uma questão de simplicidade de leitura do código e também de performance, compilamos a expressão antecipadamente.

import re

# Definimos entre [] os caracteres a procurar
# e entre {,} o numero de ocorrências que pretendemos encontrar.
ascii_re = re.compile('&#[0-9]{2,3};')
ascii = re.findall(ascii_re, pag)

Ficamos então com todos os caracteres agora guardados numa lista. Toca então de converter de ascii para caracteres e unir tudo numa só string. Nos caracteres ASCII estão também a pontuação e os espaços. Só faltam as quebras de linha!

chars = ''.join([chr(int(ascii_code)) for ascii_code in ascii])

Por último só nos falta tratar das quebras de linha. Podemos ver que as linhas começam com maiúsculas ou parêntesis e que não há pontos finais. A linha anterior acaba ou numa letra minúscula ou num parêntesis. Usando de novo expressões regulares, desta vez para substituir no texto, ficamos com:

newline_re = re.compile('([a-z\(\)])([A-Z\(])')
formatted_lyrics = re.sub(newline_re, r"\1\n\2", chars)
print formatted_lyrics.strip("'")

E pronto. Fica em baixo o “script” completo:

import re
# Definimos entre [] os caracteres a procurar
# e entre {,} o numero de ocorrências que pretendemos encontrar.
ascii_re = re.compile('&#[0-9]{2,3};')
ascii = re.findall(ascii_re, pag)
chars = ''.join([chr(int(ascii_code)) for ascii_code in ascii])
newline_re = re.compile('([a-z\(\)])([A-Z\(])')
formatted_lyrics = re.sub(newline_re, r"\1\n\2", chars)
print formatted_lyrics.strip("'")

Referências:

  1. http://docs.python.org/library/urllib2.html
  2. http://docs.python.org/library/re.html
  3. http://en.wikipedia.org/wiki/Regular_expression

3 thoughts on “Chico-Espertice 0 – 1 Python

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s