Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

[Sugestão] Desafio: lendo dados com vários parâmetros

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...')
1 resposta
solução!

Olá, Marinaldo! Como vai?

Muito bem! Continue resolvendo os desafios e compartilhando com a comunidade Alura.

Observei que você explorou o uso do chardet para detectar a codificação de arquivos, utilizou muito bem o csv.Sniffer() para identificar o separador dos dados e ainda compreendeu a importância do tratamento de exceções com múltiplas tentativas de leitura para garantir a robustez do seu código.

Uma dica interessante para o futuro é usar o parâmetro on_bad_lines='skip' no read_csv() para ignorar linhas malformadas automaticamente, quando necessário. Dessa forma:

df = pd.read_csv(buffer, sep=sep, encoding=enc, skiprows=3, on_bad_lines='skip', low_memory=False)

Resultado: Linhas com erro de formatação são ignoradas e o carregamento do DataFrame continua normalmente.

Isso faz seu código lidar ainda melhor com arquivos imprevisíveis.

Ícone de sugestão Para saber mais:

Sugestão de conteúdo para você mergulhar ainda mais sobre o tema:

Alguns materiais estão em inglês, mas é possível compreendê-los usando o recurso de tradução de páginas do próprio navegador.

Fico à disposição! E se precisar, conte sempre com o apoio do fórum.

Abraço e bons estudos!

AluraConte com o apoio da comunidade Alura na sua jornada. Abraços e bons estudos!