quarta-feira, 21 de novembro de 2012

Recuperando conteúdo de uma Tag HTML de uma URL

Recentemente precisei recuperar o conteúdo de uma tag html de uma URL para um propósito específico.

O Youtube, fez o favor de remover as famosas Tags dos vídeos de suas páginas, juntamente com o atributo de mesmo nome de sua API de integração. Com isso, não consegui mais peguar as tags para atualizar os vídeos de um projeto.

Percebi porém , que se procurasse no código fonte de cada página de vídeo, lá estavam a maioria, (senão todas) das tags no html <meta name="keywords">. Motivo pelo qual acredito que ainda esteja lá seria por busca e indexação dos vídeos.

Para recuperá-las, procurei algum pacote do python para fazer o parse do html e me deparei com o
Beautiful Soup. Ele pode ser instalado com o comando dentro do seu ENV:

pip install BeautifulSoup

E também possui uma documentação bem completa no link: http://www.crummy.com/software/BeautifulSoup/bs3/documentation.html

Criei uma def para fazer o trabalho, vamos a ela:


def get_tags(youtube_id):

	response = urllib2.urlopen('http://www.youtube.com/watch?v=%s' % youtube_id )
	html = str( response.read() )

	xmlSoup = BeautifulStoneSoup(html)

	tags = xmlSoup.findAll(attrs={"name" : "keywords"})[0]
	tags = str(tags)
	tags = tags.replace('\n','')

	return tags


Será retornado uma string com o conteúdo da tag meta keywords, sendo possível fazer todos os tratamentos necessários, como transformar em uma tupla, inserir no banco, etc.

Para outras tags, recomendo uma olhada na documentação do BeautifulSoup, pois tem várias formas de encontrar o que deseja.

hasta!

sexta-feira, 31 de agosto de 2012

Removendo acentos e caracteres especiais de nomes de arquivos durante o upload

Pior coisa para um programador, são nomes de arquivos com acentos, espaços e caracteres especiais. Pior que isso só os usuários malditos que insistem em continuar com esse procedimento infeliz.

Para resolver o problema de uma vez por todas, sempre que tiver um ImageField ou um FileField em seu model, utilize da seguinte maneira:
def retira_acento_upload(objeto, arquivo):
 """
 Essa função irá normalizar como um slug, o nome do arquivo que está sendo gravado e, irá gravá-lo
 em /media/uploads/APPNAME_CLASSNAME/ANO/nome_do_arquivo_normalizado.extensao
 """
 import os, datetime
 from django.template.defaultfilters import slugify
 caminho = str( '%s/%s/%s' % ( objeto._meta.app_label, objeto.__class__.__name__, datetime.datetime.now().year ) ).lower()
 nome, ext = os.path.splitext( arquivo )
 url = slugify( nome[:15] )
 return os.path.join( 'uploads', caminho, url+ext )

class SuaClasse(models.Model):
    ...
    arquivo = models.FileField(upload_to=retira_acento_upload)
    ...

Customize o return da def acima da maneira que desejar. No exemplo acima, o arquivo será enviado para uploads/<nome_da_app>/<nome_da_classe>/<ano_atual>/<nome_do_arquivo_nomalizado>.<extensão>

hasta!






segunda-feira, 27 de agosto de 2012

Extraindo os links de um campo HTML com expressão regular

Desenvolvendo uma ferramenta para mala direta, é importante que os links sejam contabilizados para poder mensurar os resultados.

Mas como fazer isso, sendo que o html será um campo RichText (django-ckeditor) com quantos links o usuário desejar?

O ckeditor gera no banco de dados, um campo do tipo Text e grava o conteúdo inserido em HTML. Para extrairmos os links, basta utilizarmos a mágica da expressão regular.

A estrutura ficou assim:

  • MalaDireta: Uma classe que contém o conteúdo html a ser enviado
  • Links: Uma classe que amarzenará os links gerados pela classe anterior 
Na classe MalaDireta, sobrescreva o método save e deixe-o da seguinte forma:

def save(self):
    self.link_set.all().delete()

    for u in re.findall(r'href=[\'"]?([^\'" >]+)', self.html):
        L = Link(
            maladireta = self,
            link = u,
        )
        L.save()
        self.corpo = self.corpo.replace(u, "%s/verify_url/%s" % (settings.SITE_URL,L.id))
    super(MalaDireta, self).save()

Desta forma, sempre que for alterada, a mala direta irá excluir todos os links vinculádos a ela, e inserir os novos links presentes no corpo.

Depois é só fazer uma view mapeada para a url inserida no replace acima, para contabilizar a visita, e fazer o redirect para o link original.


  • A expressão regular acima, foi testada e consegue recuperar as urls com os seguintes padrões: http://www.sua_url.com http:// 
  • www.sua_url.com.br http:// 
  • www.sua_url.com#sua_ancora http:// 
  • www.sua_url.com?seu_parametro=seu_valor 
  • http:// www.sua_url.com?seu_parametro=seu_valor#sua_ancora 
  • https://www.sua_url.com?seu_parametro=seu_valor#sua_ancora 
  • https://www.sua_url.com?seu_parametro1=seu_valor1&seu_parametro2=seu_valor2#sua_ancora 
  • https://www.sua_url.com/sua_pasta/?seu_parametro1=seu_valor1&seu_parametro2=seu_valor2#sua_ancora 

hasta!