Como converter CEP para endereço

O CEP (Código de Endereçamento Postal) no Brasil foi criado com objetivo de organizar a postagem das correspondências de forma lógica. O sistema foi criado pela Empresa Brasileira de Correios e Telégrafos em 1971 e desde maio de 1992 contam com oito dígitos (formato 00000-000). Cada dígito corresponde à seguinte informação:

  • X0000-000: Região
  • 0X000-000: Sub-região
  • 00X00-000: Setor
  • 000X0-000: Subsetor
  • 0000X-000: Divisor de subsetor
  • 00000-XXX: Sufixo de distribuição

Os três algarismos após o hífen são denominados de sufixo e destinam-se à identificação individual de localidades de baixa demanda (CEP genérico, o “000”), logradouros (CEP comum, entre 001 e 899) ou lotes de grandes receptores (CEP especial, acima de 900).

Regiões postais (primeiro algarismo). Fonte: Correios
Regiões postais (primeiro algarismo). Fonte: Correios

Veja mais sobre a estrutura e relações entre regiões e códigos no site dos Correios. Nesse outro site, existe uma lista com as faixas de CEP para cada estado e região.

Busca de endereço pelo CEP

Através do site dos Correios é possível digitar um valor de CEP e obter as informações da rua, bairro e cidade/estado através desse link: Busca CEP – Endereço.

Mas e se precisar converter muitos CEPs em endereço? Nesse caso, veja essas duas rotinas (um shell script que chama um arquivo php) para automatizar o trabalho.

Conversão de CEP para endereço

O shell script a seguir lê um arquivo linha por linha, cada uma com um valor de CEP (com hífen), e executa o script em PHP que imprime as informações em um arquivo no formato CSV.

#!/bin/bash
## Script para converter CEP em endereço

# Criar/limpar arquivo para receber endereços
rm lugares.csv; touch lugares.csv
# Ler arquivo com CEP em cada linha
cat lista_cep.txt | while read cep; do
	php convert_cep.php $cep
done

O script em PHP recebe o CEP como argumento e faz uma consulta ao site dos Correios para obter as informações do endereço, retornando uma tabela. A rotina também pega os campos da tabela, converte os caracteres HTML para UTF-8 e imprime em arquivo com quebra de linha para cada CEP consultado.

#!/usr/bin/php
<?php

// Recebe CEP como argumento
$cep = $argv[1];
//echo "CEP: ".$cep."\n";

// Montar link com requisições via post
$ch = curl_init();
curl_setopt_array($ch, array
			(
				CURLOPT_URL 			=> "http://www.buscacep.correios.com.br/sistemas/buscacep/resultadoBuscaCepEndereco.cfm",
				CURLOPT_POST			=> TRUE,
				CURLOPT_POSTFIELDS		=> "relaxation={$cep}&TipoCep=ALL&semelhante=N&Metodo=listaLogradouro&TipoConsulta=relaxation&StartRow=1&EndRow=10&cfm=1",
				CURLOPT_RETURNTRANSFER	=> TRUE
			));

// Faz a requisicao, retorna o conteudo do endereco e encerra
$saida = curl_exec($ch);
curl_close($ch);

// Codifica conteudo para utf-8
$saida = utf8_encode($saida);

// Pega apenas o conteúdo das tds e transforma em um array
$campoTabela = "";
preg_match_all('@<td (.*?)<\/td>@i', $saida, $campoTabela);

// mostra o conteudo
//print_r($campoTabela);

// Converte caracteres HTML de cada elemento de array e grava em variável
$temp = strip_tags($campoTabela[0][0]);
$rua = html_entity_decode($temp);
$temp = strip_tags($campoTabela[0][1]);
$bairro = html_entity_decode($temp);
$temp = strip_tags($campoTabela[0][2]);
$cidade_estado = html_entity_decode($temp);
$temp = strip_tags($campoTabela[0][3]);
$cep = html_entity_decode($temp);

// Imprime saída para arquivo com quebra de linha
$arquivo = "lugares.csv";
$fh = fopen($arquivo, 'a') or die("can't open file");
//$linha = $rua.",".$bairro.",".$cidade_estado.",".$cep."\n";
// Substitui barra por traço, elimina espaços em branco e tira acentuação
$temp = $cidade_estado.",".$cep."\n";
$str = strtr($temp, ['/' => '-',' ' => '']);
$linha = strtr(utf8_decode($str), utf8_decode('àáâãäçèéêëìíîïñòóôõöùúûüýÿÀÁÂÃÄÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝ'), 'aaaaaceeeeiiiinooooouuuuyyAAAAACEEEEIIIINOOOOOUUUUY');
fwrite($fh, $linha);
fclose($fh);

?>

No código, ainda estão comentadas uma linha que serve para imprimir o array inteiro com o conteúdo da tabela e outras linhas (no final) para realizar substituições do texto de saída, inclusive para retirar acentos e caracteres especiais.

Obs.: Para o script acima funcionar no terminal Linux, você deve instalar o PHP (atualmente na versão 7) e o pacote CURL (“sudo apt-get install php php-curl”).

Faixas de CEP

Os Correios distribuíram faixas de CEP para todos os municípios e unidades federativas do Brasil. Por exemplo, a faixa de CEP do estado de São Paulo é “01000-000 a 19999-999”, ou seja, todos os CEPs dentro desse intervalo são de bairros e cidades dentro do estado de SP. Isso não significa que todos os valores nesse intervalo sejam válidos (por exemplo, o CEP 01029-901 retorna um endereço, mas o 01029904 não). Caso os Correios optem por criar mais CEPs para uma localidade com grande crescimento de atividade, os novos códigos deverão estar dentro da faixa reservada ao lugar. Existem três cidades com faixas bipartidas de CEP: São Paulo, Brasília e Nova Iguaçu.

A busca da faixa de CEP pode ser realizada através do site dos Correios, disponibilizada nesse link. Toda consulta exibe a faixa de CEPs do estado no topo e as da cidade consultada embaixo – a cidade sempre vai ter uma faixa “total do município”, mas também pode possuir intervalos específicos (dentro da faixa total) conforme o tamanho e distribuição de pessoas e atividades no lugar. Para consultar as faixas de todas as cidades de um estado, basta não preencher o campo de cidade, escolhendo apenas uma UF na lista.

Obtenção das faixas de CEP para cada município

O script em PHP utilizado acima pode ser adaptado para obter as faixas de CEP a partir de uma lista de cidades trabalhando em cima da URL e dos POSTFIELDS. Também é possível fazer um trabalho um pouco mais “braçal” realizando uma consulta para cada estado e copiando as tabelas em arquivos do tipo UF.txt, todos em uma mesma pasta. Então, rodar o seguinte shell script para organizar a informação em um só arquivo com uma coluna contendo os nomes das cidades e outra com as respectivas faixas de CEP:

#!/bin/bash
## Script para arrumar faixas de CEP

rm faixas_cep.csv; touch faixas_cep.csv
# Selecionar cada arquivo salvo com o a sigla do estado
for file in `ls *.txt`; do
	uf=$(echo $file | awk -F '.' '{print $1}')
	# Substituir tabulação por vírgula e só pegar faixa de CEP total do município
	sed 's/\t/,/g' $file | grep "Total do município" > temp
	# Para cada cidade ...
	while read linha; do
		# Selecionar segunda coluna com os valores de CEP
		faixacep=$(echo $linha | awk -F ',' '{print $2}')
		# Acertar nome da cidade para comparação
		cidade=$(echo $linha | awk -F ',' '{print $1}' | sed -e 'y/áÁàÀãÃâÂéÉêÊíÍóÓõÕôÔúÚüçÇ -/aAaAaAaAeEeEiIoOoOoOuUucC__/' | sed -e 's/_//g')
		temp=$(echo $cidade | sed -e 's|["'\'']||g' | sed -e 's/DA/daA/' | sed -e 's/dA/daA/' | sed -e 's/DO/doO/' | sed -e 's/dO/doO/')
		cidade=$temp
		cidadeuf=$cidade"-"$uf
		# Gravar arquivo somente com faixas de CEP
		echo $cidadeuf","$faixacep >> faixas_cep.csv
		
		# Comparar com lista que contém mais informações sobre cidades
		linha_cidade=$(grep ','$cidadeuf',' cidades.csv)
		nlinhas=$(grep ','$cidadeuf',' cidades.csv | wc -l)
		if [ "$nlinhas" == "1" ]; then
			echo $cidadeuf "OK"
			echo $linha_cidade","$faixacep >> faixas_cep.csv
		else
			echo $cidadeuf "com problemas" >> faixas_cep.csv
		fi
	done < temp
done
rm -f temp

Como o site dos Correios só dispõe de busca de cidade pelo nome, qualquer erro de digitação ou caractere especial que não esteja exatamente igual ao valor da base de dados do site pode inviabilizar uma busca. Para evitar esse tipo de problema, o script inclui uma conversão do nome por extenso da cidade para um padrão: . O nome da cidade nesse padrão será utilizado para comparar com uma outra tabela que contenha o nome da cidade nesse mesmo padrão e outras informações úteis (código IBGE, população, área, etc).

Para converter endereço em latitude e longitude, clique no link e veja os scripts, baseados na API do Google Maps.

Compartilhe :)

2 comments

Leave a Reply

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.