Solucionado (ver solução)
Solucionado
(ver solução)
10
respostas

Programa para pegar em uma página web eventos (python e Beautifulsoup)

Objetivo: pegar os eventos em http://www.bhaktiyogapura.com/2018/03/calendario-vaisnava-marco-2018/

A cada mês, a URL muda apenas o fina, por exemplo, em abril será:

http://www.bhaktiyogapura.com/2018/03/calendario-vaisnava-abril-2018/

import requests
from bs4 import BeautifulSoup
import re

url = 'http://www.bhaktiyogapura.com/2018/03/calendario-vaisnava-marco-2018/'
response = requests.get(url, verify=False)
data = response.text
#soup = BeautifulSoup(data, "html5lib")
soup = BeautifulSoup(data, "lxml")
# aqui você seleciona o que você quer recuperar
r = soup.find("div",{'class':'the_content_wrapper'})
p = r.find_all("p")
# Aqui você itera em todos os páragrafos da agenda.
for linha in p:
    print(linha.text)

O código funciona mas imprime tudo. Gostaria de imprimir assim:

28 de Março 2018 – Quarta
Dvādaśī, G, 05:60, Maghā
-Quebra do jejum para Rio de Janeiro 05:60 às 09:58am
-Quebra do jejum para São Paulo: 06:13 às 10:12am
-Quebra do jejum para Brasília:  06:17 às 10:17am
-Quebra do jejum para Belo Horizonte:  06:02 às 10:01am
-Quebra do jejum para Vitória:  05:47 às 09:47am

Apenas as linhas que tem "-" no formato acima e não tudo! Alguma sugestão?

10 respostas

Edson, não entendi muito bem como você gostaria de imprimir. Esse formato quer você mostrou é o formato que o seu código retorna. Ou você não quer a data?

Eu gostaria de imprimir assim:

28 de Março 2018 – Quarta
Dvādaśī, G, 05:60, Maghā
-Quebra do jejum para Rio de Janeiro 05:60 às 09:58am
-Quebra do jejum para São Paulo: 06:13 às 10:12am
-Quebra do jejum para Brasília:  06:17 às 10:17am
-Quebra do jejum para Belo Horizonte:  06:02 às 10:01am
-Quebra do jejum para Vitória:  05:47 às 09:47am

Ou seja, pegando apenas o que começa com "-"

O meu programa está imprimindo TUDO!

Mas do jeito que você está fazendo imprime assim, Edson.

20 de Março 2018 – Terça
Tritīyā, G, 05:57, Aśvinī

21 de Março 2018 – Quarta
Caturthī, G, 05:57, Bhāranī

23 de Março 2018 – Sexta
Saptamī, G, 05:58, Rohiṇī

24 de Março 2018 – Sábado
Astamī, G, 05:58, Mṛgaśīrśa

Mas as saídas acima nao servem pois não têm o evento começando com "-"

Gostaria de imprimir apenas as linhas que tenham algo começando com "-" e suas respectivas datas!

solução!

Ahhh, agora entendi o que quis dizer! Um gerador pode resolver elegantemente seu problema:

def gera_blocos():
    linhas = []
    for linha in p:
        texto_linha = linha.text
        if texto_linha == '\xa0':
            if len(linhas) > 2:
                yield '\n'.join(linhas)
        elif texto_linha[0].isdigit():
            linhas.clear()
        linhas.append(texto_linha)

blocos = gera_blocos()
for bloco in blocos:
    print(bloco)
    print()

Não sei se você conhece a funcionalidade dos geradores no Python, então vou tentar explicar direitinho :). Uma função geradora, que é essa que eu criei nesse código, é uma função que retorna um objeto gerador iterador quando chamada. Em vez de usar a palavra chave return ela usa yield, que permite múltiplos retornos. Quando iteramos por um objeto gerador iterador, como fizemos com o laço for, aí sim obtemos o retorno que especificamos no yield.

Criamos uma lista vazia de linhas no começo. Para cada linha da nossa lista de tags p, pegamos o texto dentro da tag. Se esse texto for igual a '\xa0', que (por algum motivo) é o caractere que esse site usa em tags p de quebra de linha, aí checamos o tamanho da lista de linhas. Sabemos que no site, todo bloco tem pelo menos duas linhas, no estilo:

01 de Março 2018 – Quinta
Pūrṇimā, G, 05:49, Maghā

então a quantidade de linhas tem que ser maior que 2, já que só queremos os blocos que tenham itens (-). Se a quantidade for maior que 2, então retornamos todas as linhas separadas por uma quebra de linha.

Caso a linha não seja esse caractere ('\xa0'), então checamos se o primeiro caractere dela é um número. Se for, sabemos que é a primeira linha de um bloco, porque é uma linha com a data. Assim, podemos limpar nossa lista de linhas, porque sabemos que um novo bloco está começando.

Então, adicionamos a linha em nossa lista de linhas do bloco.

Eu imagino que isso esteja bem confuso, mas tenta ver com calma o código e a explicação e depois pode perguntar tudo que ficou difícil de entender!

Muito obrigado! Vou estudar a explicação com calma e depois retorno aqui!

Não hesita em perguntar aqui (ou em outro tópico do fórum) qualquer confusão, eu sei que não ficou muito claro :/! Abrações pra você, Edson!

Em breve vai sair um post no blog da Alura a respeito de geradores no Python, aí você vai poder entender um pouco mais!

Se eu trocar a url para:

url = "http://www.bhaktiyogapura.com/2018/02/calendario-vaisnava-fevereiro-2018/"

Ele ainda imprimi alguns valores indesejados:

28 Fevereiro 2018 – Quarta
Caturdaśī, G, 05:48, Āśleṣā


28 Fevereiro 2018 – Quarta
Caturdaśī, G, 05:48, Āśleṣā

Opa, Edson, é só adicionar um continue caso a linha seja aquele '\xa0' para isso não entrar na lista, dessa forma:

def gera_blocos():
    linhas = []
    for linha in p:
        texto_linha = linha.text
        if texto_linha == '\xa0':
            if len(linhas) > 2:
                yield '\n'.join(linhas)
            else:
                continue
        elif texto_linha[0].isdigit():
            linhas.clear()
        linhas.append(texto_linha)

blocos = gera_blocos()
for bloco in blocos:
    print(bloco)
    print()

Muito obrigado de novo! Vou aguardar o artigo sobre geradores! Uma ótima Páscoa!