Formatos e fontes de dados 4 min de leitura

Parsing de CSV: separadores, aspas, codificações e exemplos em várias linguagens

Tudo sobre a leitura de CSV: separadores, aspas, codificações, arquivos problemáticos do Excel e exemplos de código em Python, PHP, JavaScript e Go.

EW
Equipe Web-Scraping.biz
Coleta de dados para as demandas do negócio
Publicado: 26 fevereiro 2025

CSV (Comma-Separated Values) é o formato tabular mais simples que existe: as linhas do arquivo correspondem às linhas da tabela e os valores dentro de cada linha são separados por vírgula ou outro caractere. Nele chegam as exportações dos CRMs e ERPs, os downloads do Excel, os relatórios das plataformas de publicidade e de analítica. O formato parece trivial, e justamente por isso é onde mais se cometem erros. Este artigo faz parte do nosso panorama do parsing de documentos e é dedicado a como ler CSV corretamente.

Por que o «split por vírgulas» é um erro

A tentação de fatiar o CSV à mão — line.split(",") — todo mundo sente, e quase sempre termina em bugs. A razão é que o CSV tem escape: um valor com vírgula dentro é envolvido em aspas, e as aspas dentro de um valor são duplicadas.

csv
sku,name,price
101,"Moedor de café, manual",3490
102,"Bule ""Retrô""",2190

Aqui "Moedor de café, manual" é um único valor, não dois, e Bule "Retrô" contém aspas. Qualquer split manual vai quebrá-lo. Por isso usa-se sempre um leitor de CSV pronto: ele conhece as aspas, o escape e as quebras de linha dentro das células.

Separadores, codificações e BOM

Apesar do «comma» no nome, o separador muitas vezes acaba sendo o ponto e vírgula (;): é assim que o Excel salva os arquivos nas configurações regionais onde a vírgula é o separador decimal — a brasileira entre elas. Também aparecem a tabulação (TSV) e a barra vertical. Um bom parser sabe detectar o separador automaticamente ou o aceita como parâmetro.

O segundo problema constante é a codificação. Os arquivos dos sistemas de gestão antigos chegam com frequência em windows-1252 (latin-1), e não em UTF-8. Além disso, os arquivos do Excel muitas vezes começam com um BOM (uma marca invisível no início) por culpa do qual o nome da primeira coluna é lido como sku em vez de sku. Cura-se indicando a codificação correta na leitura (em Python, encoding="utf-8-sig", que elimina o BOM sozinha).

Python

A biblioteca padrão inclui o módulo csv, suficiente na maioria dos casos. O mais prático é o DictReader, que entrega cada linha como um dicionário conforme os cabeçalhos.

python
import csv

with open("prices.csv", encoding="utf-8-sig", newline="") as f:
    reader = csv.DictReader(f, delimiter=";")
    for row in reader:
        print(row["sku"], row["name"], row["price"])

Quando o CSV é grande ou é preciso analisá-lo em tempo real — filtrar, agrupar, calcular —, recorre-se ao pandas. Uma única linha lê o arquivo para uma tabela (DataFrame).

python
import pandas as pd

df = pd.read_csv("prices.csv", sep=";", encoding="utf-8-sig")
expensive = df[df["price"] > 3000]
print(expensive[["sku", "name"]])

O pandas também é prático para converter: esse mesmo DataFrame é salvo com um único comando de volta em CSV, Excel ou JSON.

JavaScript / Node.js

No navegador e no Node, o parser mais popular é o Papa Parse: detecta o separador automaticamente, entende os cabeçalhos e sabe trabalhar com fluxos.

javascript
const Papa = require("papaparse");
const fs = require("fs");

const file = fs.readFileSync("prices.csv", "utf-8");
const result = Papa.parse(file, { header: true, skipEmptyLines: true });

for (const row of result.data) {
  console.log(row.sku, row.name, row.price);
}

Para os pipelines de servidor com arquivos grandes, escolhe-se com mais frequência o csv-parse — o parser em fluxo do ecossistema Node CSV.

PHP

A função nativa fgetcsv já incorpora o tratamento das aspas, então basta para as tarefas simples.

php
<?php
$f = fopen("prices.csv", "r");
$headers = fgetcsv($f, 0, ";");

while (($row = fgetcsv($f, 0, ";")) !== false) {
    $record = array_combine($headers, $row);
    echo $record["sku"] . " — " . $record["name"] . "\n";
}
fclose($f);

Para um trabalho mais confortável — com filtragem, seleção de colunas e conversão de codificações — usa-se a biblioteca league/csv.

Go

A biblioteca padrão de Go traz o pacote encoding/csv, que cobre a maioria dos casos, separador fora do padrão incluído.

go
package main

import (
    "encoding/csv"
    "fmt"
    "os"
)

func main() {
    f, _ := os.Open("prices.csv")
    defer f.Close()

    r := csv.NewReader(f)
    r.Comma = ';'
    rows, _ := r.ReadAll()

    for _, row := range rows[1:] { // pulamos a linha de cabeçalho
        fmt.Println(row[0], row[1], row[2])
    }
}

Quando o CSV deixa de dar conta

O CSV funciona enquanto os dados são planos. Assim que aparecem aninhamento, várias tabelas em um mesmo arquivo, formatação, fórmulas ou células mescladas, isso já não é tarefa para CSV, e sim para o parsing de Excel. E o contrário também vale: se o original em Excel é complexo demais para ser lido diretamente, muitas vezes exporta-se primeiro para CSV e processa-se de maneira uniforme. E se o CSV é, no fundo, um despejo de eventos ou de linhas de um registro, dê uma olhada nas abordagens dos artigos sobre o parsing de TXT e o parsing de logs.

Se os seus downloads chegam com codificações «flutuantes», separadores que mudam de uma entrega para outra ou aspas quebradas, nós os unificamos e configuramos um parsing estável com a carga do resultado no sistema de que você precisa.