A extração de dados científicos de serviços web frequentemente exige a simulação de requisições que seriam feitas manualmente através de formulários HTML. No contexto de modelos geofísicos, como o IGRF (International Geomagnetic Reference Field), os parâmetros de entrada geralmente incluem coordenadas geográficas e a data formatada em anos decimais.
Conversão de Data para Anos Decimais
Muitos modelos de processamento geofísico não utilizam o formato de data convencional (dia/mês/ano), mas sim uma rperesentação decimal. Abaixo, apresenta-se uma implementação em Python para realizar essa conversão considerando anos bissextos:
def calcular_ano_decimal(ano, mes, dia):
def verificar_bissexto(a):
return (a % 4 == 0 and a % 100 != 0) or (a % 400 == 0)
dias_por_mes = [31, 29 if verificar_bissexto(ano) else 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
total_dias_ano = 366 if verificar_bissexto(ano) else 365
# Soma os dias dos meses anteriores ao mês atual
dia_no_ano = sum(dias_por_mes[:mes - 1]) + (dia - 1)
return ano + (dia_no_ano / total_dias_ano)
# Exemplo de uso para 01 de Dezembro de 2016
ano_formatado = calcular_ano_decimal(2016, 12, 1)
print(f"Ano Decimal: {ano_formatado}")
Simulação de Requisição POST para Coleta de Dados
Para obter dados diretamente do serviço do British Geological Survey (BGS), é necessário realizar uma requisição HTTP do tipo POST para o script CGI responsável pelo processamento. A eficácia da coleta depende do envio correto dos cabeçalhos (headers) e do corpo da mensagem (payload), emulando o comportamento de um navegador real.
import requests
def requisitar_dados_geomagneticos():
url_endpoint = "http://www.geomag.bgs.ac.uk/cgi-bin/igrfsynth"
# Configuração dos parâmetros do formulário
form_data = {
'name': 'pesquisador_bot',
'coord': '1', # 1 para Geodetic, 2 para Geocentric
'date': '2016.92', # Data convertida em ano decimal
'alt': '150', # Altitude em km
'latd': '60', # Graus de Latitude
'latm': '0', # Minutos de Latitude
'lond': '120', # Graus de Longitude
'lonm': '0', # Minutos de Longitude
'degmin': 'y', # Formato de graus/minutos
'tot': 'y', # Intensidade Total (F)
'dec': 'y', # Declinação (D)
'inc': 'y', # Inclinação (I)
'hor': 'y', # Intensidade Horizontal (H)
'nor': 'y', # Componente Norte (X)
'eas': 'y', # Componente Leste (Y)
'ver': 'y', # Componente Vertical (Z)
'map': '0', # Gerar mapa (0 = não)
'sv': 'n' # Variação secular (n = não)
}
# Cabeçalhos para evitar bloqueios simples de User-Agent
cabecalhos = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/110.0',
'Referer': 'http://www.geomag.bgs.ac.uk/data_service/models_compass/igrf_form.shtml',
'Origin': 'http://www.geomag.bgs.ac.uk',
'Content-Type': 'application/x-www-form-urlencoded'
}
try:
sessao = requests.Session()
resposta = sessao.post(url_endpoint, data=form_data, headers=cabecalhos)
if resposta.status_code == 200:
with open("resultado_igrf.html", "w", encoding="utf-8") as arquivo:
arquivo.write(resposta.text)
print("Dados salvos com sucesso em 'resultado_igrf.html'.")
else:
print(f"Erro na requisição: Código {resposta.status_code}")
except Exception as e:
print(f"Ocorreu uma falha na conexão: {e}")
if __name__ == "__main__":
requisitar_dados_geomagneticos()
Ao lidar com sites que utilizam CGI ou proteções contra automação, é crucial observar se o servidor exige a manutenção de cookies de sessão. O uso de requests.Session() ajuda a persistir o estado da conexão, o que pode ser necessário caso o servidor valide a navegação prévia na página do formulário antes de aceitar o anvio dos dados.