Boa parte dos desenvolvedores de software um dia já precisou desenvolver um cadastro de clientes, com nome, telefone, endereço, etc. Ou quem sabe um cadastro de fornecedores, de empresas, enfim, na maioria destes cadastros é preciso armazenar o endereço da pessoa, firma, ou qualquer outra entidade.

E quando se desenvolve um cadastro de endereço, uma das necessidades mais comuns é a de poder informar apenas o CEP (Código de Endereçamento Postal) e o próprio sistema apresentar as demais informações (logradouro, bairro, cidade e estado).

Para suprir essa necessidade, geralmente se recorre a um dos seguintes métodos:

  • Manter um banco de dados local com as informações de "todos" os CEPs do país e usar esse banco para consulta (geralmente é uma tabela no próprio banco da aplicação).
  • Realizar a consulta através da web, consumindo um web service que ofereça esse serviço.

As duas formas, como em tudo na vida, tem seus “prós e contras”, por exemplo:

  • Em um banco de dados local, dependendo da configuração das máquinas, rede, etc, a consulta pode ser mais rápida, uma vez que não depende de internet. Porém, esse banco de dados com todos os CEPs do Brasil não é distribuído gratuitamente por um órgão de confiança. Além disso, pode surgir novos CEPs e essas informações teriam de ser atualizadas na base de dados com frequência.
  • Acessar um web service nos poupa de manter um banco de dados local e da responsabilidade de ter de atualizá-lo sempre que surgir um novo CEP. Mas para consumir um web service, obrigatoriamente é necessária uma conexão com a internet. E além disso é preciso ter um web service seguro, estável e, dependendo do projeto, gratuito.

Neste artigo, veremos uma solução bastante próxima da segunda forma citada, mas estaremos consumindo um web service da forma tradicional. Na prática, estaremos utilizando a página de consulta de CEP do site dos correios. Enviaremos os dados da consulta através de uma requisição POST (passando parâmetro na URL) e obteremos como resultado o código da página de resultados. A partir dela, buscaremos apenas os elementos na estrutura HTML que apresentam o resultado em si.

Página dos Correios com resultado de pesquisa por CEP
Figura 1: Página dos Correios com resultado de pesquisa por CEP.

Como vemos na Figura 1 o resultado da consulta por CEP é apresentado em uma tabela HTML com cinco colunas. Ao receber a resposta da requisição, localizaremos essa tabela na estrutura da página e extrairemos apenas os valores das colunas.

Neste artigo será utilizado um projeto do tipo ASP.NET Web Forms, mas o mesmo código poderia ser usado para Windows Forms, por exemplo, bastando adaptar a interface.

Então comecemos criando um web site ASP.NET a partir do menu FILE > NEW > Web Site...e selecionando o template ASP.NET Web Forms Site.

Na página principal (default.aspx) vamos inserir apenas um TextBox, um Button e um Literal para exibir o resultado com formatação HTML, mas este poderia ser exibido em TextBoxes, LabelsM, ou qualquer outro controle. Então podemos substituir o conteúdo do ContentPlaceHolder MainContent pelo conteúdo da Listagem 1.

Listagem 1: Elementos da interface da página principal utilizados para consulta.
<h1>Consultar CEP</h1>
<asp:TextBox ID="txtCEP" runat="server" MaxLength="8"/>
<asp:Button ID="btnConsultar" runat="server" Text="Consultar" OnClick="btnConsultar_Click"/>
<hr/>
<asp:Literal ID="litResultado" runat="server"/>

O próximo passo é implementar o método btnConsultar_Click para tratar o evento OnClick do botão. O “segredo” da consulta está nesta parte, apresentada na Listagem 2.

Listagem 2: Consultado o CEP através de uma requisição ao site dos Correios.

HttpWebRequest requisicao = (HttpWebRequest)WebRequest.Create(
"http://www.buscacep.correios.com.br/servicos/dnec/consultaLogradouroAction.do?
Metodo=listaLogradouro&CEP=" + txtCEP.Text + "&TipoConsulta=cep");
HttpWebResponse resposta = (HttpWebResponse)requisicao.GetResponse();

int cont;
byte[] buffer = new byte[1000];
StringBuilder sb = new StringBuilder();
string temp;

Stream stream = resposta.GetResponseStream();

do
{
    cont = stream.Read(buffer, 0, buffer.Length);
    temp = Encoding.Default.GetString(buffer, 0, cont).Trim();
    sb.Append(temp);

} while (cont > 0);

string pagina = sb.ToString();

if (pagina.IndexOf("<font color=\"black\">CEP NAO ENCONTRADO</font>") >= 0)
{
    litResultado.Text = "<b style=\"color:red\">CEP não localizado.</b>";
}
else
{
    string logradouro = Regex.Match(pagina,
"<td width=\"268\" style=\"padding: 2px\">(.*)</td>").Groups[1].Value;
    string bairro = Regex.Matches(pagina,
"<td width=\"140\" style=\"padding: 2px\">(.*)</td>")[0].Groups[1].Value;
    string cidade = Regex.Matches(pagina,
"<td width=\"140\" style=\"padding: 2px\">(.*)</td>")[1].Groups[1].Value;
    string estado = Regex.Match(pagina,
"<td width=\"25\" style=\"padding: 2px\">(.*)</td>").Groups[1].Value;
    string resultado = String.Format(
"Logradouro: {0} <br/> Bairro: {1} <br/> Cidade: {2} <br/> Estado: {3}",
logradouro, bairro, cidade, estado);
    litResultado.Text = resultado;
}

Primeiramente efetuamos a requisição, recebemos uma resposta em formato stream e o transformamos em string. O conteúdo da variável página é nada mais nada menos que o código HTML da pagina apresentada na Figura 1. Utilizando essa variável, nós localizamos apenas trechos específicos que indicam o resultado da consulta. Caso o CEP seja localizado, buscamos por uma tabela, como se vê na Figura 1, caso contrário, é apresentada a mensagem “CEP NÃO ENCONTRADO” entre tags <font>. Se encontramos essa mensagem na página, isso indica que o CEP procurado não foi localizado, então informamos ao usuário apresentando uma mensagem equivalente no Literal.

Se o CEP for localizado, utilizamos a classe Regex para encontrar apenas as informações que nos interessam, ou seja, o logradouro, o bairro, a cidade e o estado. O CEP também é exibido na tabela, mas como já temos essa informação, não precisamos obtê-la novamente a partir do resultado da consulta.

Na Figura 2 podemos ver a aplicação em execução, consultando um CEP existente.

Consultando CEP existente
Figura 2: Consultando CEP existente.

Para testar, podemos também digitar um CEP inválido e pressionar o botão Consultar. O resultado é apresentado na Figura 3.

CEP não localizado
Figura 3: CEP não localizado.

Aqui todo o código foi posto no evento OnClick do botão, mas em uma aplicação real poderíamos extrair um método e reaproveitar este código em várias partes do sistema. Também caberia criar uma classe para tratar essa consulta e retornar o resultado de forma que se pudesse acessar cada campo do endereço consultado.

Com algum conhecimento de C#, é possível adequar este exemplo a várias situações.

O código fonte encontra-se disponível para download no topo desta página, em C# e VB.net.