import pandas as pd
import io
import csv
import urllib.request
import chardet
# Função para detectar automaticamente o separador do CSV usando o csv.Sniffer
def detectar_separador(texto):
try:
return csv.Sniffer().sniff(texto[:1024]).delimiter
except:
return ',' # Se não conseguir detectar, usa vírgula como padrão
# Função que tenta ler os dados CSV a partir de bytes, testando múltiplas codificações
def ler_csv_bytes(bytes_data):
# Decodifica uma amostra para detectar o separador
texto_amostra = bytes_data.decode('utf-8', errors='ignore')
sep = detectar_separador(texto_amostra)
# Detecta o encoding dos bytes usando chardet
detected = chardet.detect(bytes_data)
encoding_detectado = detected['encoding'] or 'utf-8' # Usa utf-8 como fallback
# Lista de codificações para tentar, com a detectada primeiro
codificacoes = [encoding_detectado, 'utf-8', 'latin1', 'ISO-8859-1']
# Remove codificações duplicadas mantendo ordem
codificacoes = list(dict.fromkeys(codificacoes))
# Tenta ler o CSV com cada codificação até funcionar
for enc in codificacoes:
try:
buffer = io.BytesIO(bytes_data) # Reseta buffer a cada tentativa
# Lê CSV pulando as 3 primeiras linhas, evita baixo uso de memória
df = pd.read_csv(buffer, sep=sep, encoding=enc, skiprows=3, low_memory=False)
# Remove as últimas 9 linhas, se houver linhas suficientes
df = df.iloc[:-9] if len(df) > 9 else df
return df
except (UnicodeDecodeError, pd.errors.ParserError):
continue # Se falhar, tenta próxima codificação
# Se não conseguiu ler com nenhuma codificação, lança erro
raise ValueError('Não foi possível ler o CSV com as codificações comuns.')
if __name__ == '__main__':
# URL do arquivo CSV que será baixado
url = 'https://raw.githubusercontent.com/alura-cursos/Pandas/main/dados_sus.csv'
# Baixa os dados em bytes
with urllib.request.urlopen(url) as response:
dados_bytes = response.read()
# Lê os dados CSV usando a função que detecta encoding e separador
df_dados = ler_csv_bytes(dados_bytes)
# Exibe informações gerais do DataFrame
print(df_dados.info())
# Exibe as 10 primeiras linhas para visualização rápida
print(df_dados.head(10))
# Pausa a execução para o usuário poder ver a saída no terminal
input('\nPressione Enter para sair...')