Skip to content

Instantly share code, notes, and snippets.

@pedrovhb
Created May 25, 2017 02:05
Show Gist options
  • Save pedrovhb/50dc541a1d118f981f42e49e3b9e07df to your computer and use it in GitHub Desktop.
Save pedrovhb/50dc541a1d118f981f42e49e3b9e07df to your computer and use it in GitHub Desktop.
import requests # Para carregarmos a página da web
import bs4 # Para retirarmos informações do HTML
from datetime import datetime # Para sabermos o mês e ano atual
# As três primeiras letras de cada mês, usadas pra formar a URL.
# Botamos o primeiro elemento vazio porque os índices da lista começam a contar do 0.
# Assim, temos corretamente que months[1] = 'Jan', months[7] = 'Jul', etc.
months = ['', 'Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez']
# Nosso código do porto
code = '60245'
# Pegamos nosso ano atual
current_year = datetime.now().year
# Pegamos as três primeiras letras do mês atual
current_month = months[datetime.now().month]
# Formamos o link que vamos seguir
url = 'http://www.mar.mil.br/dhn/chm/box-previsao-mare/tabuas/{}{}{}.htm'.format(code, current_month, current_year)
print('Seguindo link:', url)
r = requests.get(url)
soup = bs4.BeautifulSoup(r.text, 'html.parser') # Criar uma "sopa" com o HTML que buscamos
# Aqui procuramos o elemento table, que contém os tr em que estamos interessados
# A função find acha só o primeiro elemento que corresponde ao indicado
table = soup.find(lambda tag: tag.name == 'table')
# O find_all, em contraste, retorna uma lista com todos os elementos que correspondem
# ao que pedimos e retorna uma lista com eles. Note que agora ao invés de procurarmos
# na sopa (página toda), procuramos só entre os elementos do table que achamos
tr_list = table.find_all(lambda tag: tag.name == 'tr')
last_seen_day = '' # Pra guardarmos o último dia visto
max_height = float('-INF') # Menor valor possível, pra futuras comparações
max_height_time = '' # Hora da maior altura
max_height_day = '' # Dia da maré com maior altura
min_height = float('INF') # Maior valor possível, pra futuras comparações
min_height_time = '' # Hora da menor altura
min_height_day = '' # Dia da maré com menor altura
# Pra cada tr na lista...
for tr in tr_list:
# Se houver algum elemento no tr com bgcolor #C0C0C0 (legenda), ignorar
if tr.find(lambda tag: tag.get('bgcolor') == '#C0C0C0') is not None:
continue # Quebrar o loop e ir pro próximo tr
# Se só houver um elemento td em tr, ignorar
if len(tr.find_all(lambda tag: tag.name == 'td')) == 1:
continue
# Se houver um elemento com bgcolor #D7D9E8, é um elemento com data
if tr.find(lambda tag: tag.get('bgcolor') == '#D7D9E8') is not None:
td_list = tr.find_all(lambda tag: tag.name == 'td')
# Vimos antes que a string que contém o dia está no elemento número 1 do tr
# Anotamos o último dia visto porque se uma das alturas for a maior ou menor, vamos guardá-las com esse dia
last_seen_day = td_list[1].text
# No elemento 4 está a altura da maré no horário dessa linha de tabela.
# Se ela for maior ou menor do que as outras vistas:
# - anotamos o valor como maior ou menor
# - anotamos o dia como o último dia visto
# - anotamos a hora como a hora dessa linha
if float(td_list[3].text) > max_height:
max_height = float(td_list[3].text)
max_height_time = td_list[2].text
max_height_day = last_seen_day
if float(td_list[3].text) < min_height:
min_height = float(td_list[3].text)
min_height_time = td_list[2].text
min_height_day = last_seen_day
continue # Quebrar loop e ir pro próximo tr
# Se houver um elemento com bgcolor #FFFFFF, é um elemento só com data e altura
if tr.find(lambda tag: tag.get('bgcolor') == '#FFFFFF') is not None:
td_list = tr.find_all(lambda tag: tag.name == 'td')
# Temos que lembrar que no elemento que só tem a hora e altura, diferente do que tem data,
# a altura está no elemento de número 3 e o horário no de número 2. Fora isso, a lógica é a mesma da de cima
if float(td_list[3].text) > max_height:
max_height = float(td_list[3].text)
max_height_time = td_list[2].text
max_height_day = last_seen_day
if float(td_list[3].text) < min_height:
min_height = float(td_list[3].text)
min_height_time = td_list[2].text
min_height_day = last_seen_day
print('===============')
print('Maré alta:', max_height, 'm')
print('Dia:', max_height_day)
print('Hora:', max_height_time)
print('===============')
print('Maré baixa:', min_height, 'm')
print('Dia:', min_height_day)
print('Hora:', min_height_time)
print('===============')
input()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment