Webservice – Consulta de CEP diretamente ao site dos correios

Postado por: Felipe Roberto em
Correios

Até pouco tempo, tinhamos um site onde podiamos fazer consultas via get, ou até baixar a base de dados utilizada de forma gratuita. Mas seu maior problema para todos que já utilizaram tal base era o fato desta ser muito antiga. Com isso surgia o problema de ruas e bairros com nomes errados ou até mesmo não existentes. O tempo passou, a base ficou ainda mais velha e o site passou a cobrar pelos serviços. Mas não tem problema, os correios que antes tinham um sistema que não permitia se aproveitar dos dados (gerava as respostas em imagens), hoje nos disponibiliza uma versão mobile que facilmente nos permite tratar as respostas.

Para criarmos nosso próprio webservice em PHP vamos simular o comportamento realizado pelo site através de requisições cURL.

Aqui incluimos biblioteca phpQuery (http://code.google.com/p/phpquery/ que permite manipular conteúdo html atrvés de seleções tipo jquery/css):

include('phpQuery-onefile.php');

Após criamos uma função para fazermos requisições via cURL, para depois tratarmos com o phpQuery.

function simple_curl($url,$post=array(),$get=array()){
	$url = explode('?',$url,2);
	if(count($url)===2){
		$temp_get = array();
		parse_str($url[1],$temp_get);
		$get = array_merge($get,$temp_get);
	}

	$ch = curl_init($url[0]."?".http_build_query($get));
	curl_setopt ($ch, CURLOPT_POST, 1);
	curl_setopt ($ch, CURLOPT_POSTFIELDS, http_build_query($post));
	curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, 1);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	return curl_exec ($ch);
}

Depois de ambiente preparado, mãos as teclas. Aqui esta o cep a ser consultado:

$cep = $_GET['cep'];

Fazemos uma chamada POST direta aos correios http://m.correios.com.br/movel/buscaCepConfirma.do. Para entender, acesse a url pelo navegador e faça uma consulta, nosso webservice fará o mesmo, mas atráves do servidor.

Aqui é onde capturamos o HTML através da chamada cURL, enviando os parametros necessários.

$html = simple_curl('http://m.correios.com.br/movel/buscaCepConfirma.do',array(
	'cepEntrada'=>$cep,
	'tipoCep'=>'',
	'cepTemp'=>'',
	'metodo'=>'buscarCep'
));

Fazemos o phpQuery ler o HTML capturado:

phpQuery::newDocumentHTML($html, $charset = 'utf-8');

Aqui tratamos os dados com o phpQuery a função pq(), é equivalente ao $() do jQuery $(#id elemento.classe).html() em jQuery, e em PHP pq(#id elemento.classe)->html(). Então temos nosso logradouro, bairro, cidade/uf e cep:

$dados = 
array(
	'logradouro'=> trim(pq('.caixacampobranco .resposta:contains("Logradouro: ") + .respostadestaque:eq(0)')->html()),
	'bairro'=> trim(pq('.caixacampobranco .resposta:contains("Bairro: ") + .respostadestaque:eq(0)')->html()),
	'cidade/uf'=> trim(pq('.caixacampobranco .resposta:contains("Localidade / UF: ") + .respostadestaque:eq(0)')->html()),
	'cep'=> trim(pq('.caixacampobranco .resposta:contains("CEP: ") + .respostadestaque:eq(0)')->html())
);

Como nem tudo é perfeito, temos que tratar as informações de cidade/uf que vem ‘grudadas’:

$dados['cidade/uf'] = explode('/',$dados['cidade/uf']);
$dados['cidade'] = trim($dados['cidade/uf'][0]);
$dados['uf'] = trim($dados['cidade/uf'][1]);
unset($dados['cidade/uf']);

Pronto, basta agora imprimir no formato json e começar a fazer as requisições via ajax:

die(json_encode($dados));

Ao invés do phpQuery, podiamos ter usado o YQL, porém teriamos dobrado o numero de requições, pois chamariamos o servidor do yahoo que por sua vez chamaria o servidor dos correios

Façaa aqui o download dos arquivos de exemplo.

Posts Relacionados

Confira também outros artigos interessantes postados aqui no blog.

Gostou desse post?

Assine o nosso Feed RSS, siga-nos no Twitter, ou simplesmente nos recomende a seus amigos!

Sobre Felipe Roberto

Desenvolvedor PHP na Luego.

123 Responses to “Webservice – Consulta de CEP diretamente ao site dos correios”

  1. Alexsandro disse:

    Bacana, será que os correios irá disponibilizar pra SEDEX e PAC também?

  2. GustavoPulga disse:

    Nossa, muito bom isso. Usando essa ideia aí vou me livrar de diversos problemas que tenho em minhas aplicações.

    Parabéns pelo post!

  3. Excelente post eim, usando a base dos correios ela sempre estara atualizada. Vlw

  4. Com certeza com este post a vida fica mais fácil… A web deve funcionar assim mesmo, colaboração entre empresas para melhorar a produtividade de todos.
    Parabéns!!!

  5. bruno disse:

    preciso de uma url com https, alguém aqui conhece?

  6. Só pra adicionar…

    Em caso de erro de CEP não encontrado:

    newDocumentHTML(self::$html, $charset = ‘utf-8′);
    $errCEP= array(‘erro’=> trim(pq(‘.erro:eq(0)’)->html()));

    if(empty($errCEP["erro"])){

    $dados =
    array(
    ‘logradouro’=> trim(pq(‘.caixacampobranco .resposta:contains(“Logradouro: “) + .respostadestaque:eq(0)’)->html()),
    ‘bairro’=> trim(pq(‘.caixacampobranco .resposta:contains(“Bairro: “) + .respostadestaque:eq(0)’)->html()),
    ‘cidade/uf’=> trim(pq(‘.caixacampobranco .resposta:contains(“Localidade / UF: “) + .respostadestaque:eq(0)’)->html()),
    ‘cep’=> trim(pq(‘.caixacampobranco .resposta:contains(“CEP: “) + .respostadestaque:eq(0)’)->html())
    );

    }else{

    echo “CEP não localizado!!!”;

    }

  7. Julio Akira disse:

    Qual o risco de derepente os correios bloquer as requisiçoes ou simplemente alterar a formatação com frequencia ?

    Ainda tem o risco do sistema deles ficarem off line.

    Falo isso pois tinha problemas em uma webservice de consulta de frete, e como solução implementei a tabela de preços dentro do sistema, como a tabela sofre nom maximo 2 alterações anuais, o cliente mesmo altera.

    Att

    Julio

    • Cleiton disse:

      Acredito se dependermos se o servidor ficar off-line ou não, acaba que nós não utilizaremos nenhum WebService.

      Porém acredito que essa liberação dos Correios seja uma “falha”, não acredito que o mesmo fique liberado por muito tempo.

      Porém o script está muito bom e funcional, eu mesmo já fiz muitas alterações e implementei ao ExtJS com Zend PHP!

      Att,
      Cleiton.

  8. Ale disse:

    Os resultados estão retornando com acentuação incorreta. Alguém sabe como corrigir?

    • Verifique as encodações: do arquivo, da resposta e do seu retorno.
      Utilize utf8_encode/utf8_decode (de acordo com a necessidade) e sete o cabeçalho no php com a função header e também no html também. Se tudo estiver com o mesmo cabeçalho não haverá mais problema.

      • Sergio Nader disse:

        Felipe, parabéns pela iniciativa. Estou retomando a programação em PHP (que deixei faz muitos anos) e apanhando para fazer São Paulo aparecer no lugar de “S\u00e3o Paulo”. Verifiquei tudo o que podia (como o arquivo php está sendo salvo, coloquei os headers de html com o charset, usei header() e confesso que estou perdido. Qualquer ajuda será mais do que bem-vinda!
        Obrigado

      • Opa Sergio, seu problema é outro. Na verdade não é um problema. Veja que no fim do script esta sendo usado a função json_encode. Esta transforma um array php numa string em json. A string acaba sendo encodada para formato de url (faça o teste: echo rawurlencode(‘são paulo’)).
        Esse script foi desenvolvido para ser utilizado diretamente por uma requisição ajax. Se eventualmente você precisar manipular esses dados via php, basta você não usar o json_encode e você ainda terá o array php.

      • Sergio Nader disse:

        Felipe, tem toda a razão. Bastou eu imprimir a matriz $dados com print_r e deu tudo certo. Muitíssimo obrigado!

  9. Luiz INOVA disse:

    Ta maneiro o codigo mas precisa ser aperfeiçoado cotem muitos erros ainda!

  10. Opa gente!
    Resolvi compartilhar no GitHub (https://github.com/feliperoberto/correios-cep). Assim todos juntos podemos melhorar o webservice e não ficar dependente da boa vontade dos correios em disponibilizar um assim como fez com os demais serviços.
    Aguardo a colaboração de todos.
    Abraço.

  11. Michel Isoton disse:

    A grande falha deste script é que ele pega apenas resultados da primeira página. Se você buscar por um nome de rua, por exemplo, há a chance de vir dezenas e dezenas de páginas de resultados.

    • Opa Michel, na verdade o objetivo desse serviço é apenas buscar por ceps. Cabe ao desenvolvedor validar a entrada de dados impedindo a busca por endereços (pois os Correios não validam a entrada de dados, e a busca por um cep válido irá retornar apenas 1 resultado). Trata-se de um tutorial que esta um pouco desatualizado. Veja a versão no github e sinta-se a vontade para ajudar a melhorar.

      • Michel Isoton disse:

        Opa, e aí Felipe, tudo bem?
        Então, estou trabalhando em um e-Commerce, em que a busca de CEP através do endereço se faz necessária.
        Estive olhando os códigos e adaptando, porém, até agora só consigo pegar os resultados da segunda página. Sei que para pegar o resto dos resutlados, é necesasário ir fazendo requisições, passando o parâmetro ‘metodo’ como ‘proximo’, e ‘numPagina’ como a pagina atual. Porém, as requisições não retornam nada.

        Pretendo continuar tentando, e se conseguir algo, entro em contato para disponibilizar aqui.

    • Pronto Michel, atualizei o código para permitir a busca de endereço. Coloquei seu crédito lá.

  12. Felipe disse:

    Parabéns pelo post. Agora com esse phpQuery da pra fazer paradas bacana.

  13. Hudson disse:

    ola amigos, antes de tudo queria dar os parabéns pelo artigo pois esta perfeito… o seu código faz tudo o propõe a fazer!
    queria contribuir apenas com um alerta…
    Tanto para os usuários de Windows e de Linux, o cURL (função utilizada para adquirir uma requisição http) não faz parte do PHP por padrão, essa função precisa ser instalada e habilitada no php.ini para quem usa uma distribuição Linux baseada no debian é só executar o “apt-get install php5-curl” como super usuário no terminal e pronto… agora pra quem usa Windows eu não sei rsrsrs eu nunca usei apache e php no Windows rsrsr…. se bem que No PHP existem quatro formas de você acessar uma URL externa: usando a função fopen(), usando a função fsockopen(), usando a biblioteca cURL e usando a classe HTTP_Request…. eu gosto do cURL por que é mais facil de usar… mas mesmo assim valeu, o artigo esta muito bom… tomei a liberdade e testar e da de 10 x 0 no que eu tinha feito parabéns mesmo cara!!! faloww

    • Obrigado Hudson, inclusive só utilizei curl pois em meu servidor não estava habilitado fazer fopen para outros sites.
      e recentemente descobri que para habilitar bastava usar o simples comando ini_set(“allow_url_fopen”, 1);
      valeu por sua contribuição, com o fopen o código fica inclusive mais enxuto.

  14. Hudson disse:

    cara, eu fatorei o codigo e notei que ele retorna um array de com os dados e tal… mas se eu por um CEP como 58114000
    que retorna:
    cep = 58444000
    estado = PB
    os demias campos do array retornarão vazios dai eu fiz uma função que faz o seguinte:

    function validaArrayEndereco($cep, $listaEndereco){
    $endereco = array();
    $html = endereco_dne_correios::simple_curl(‘http://m.correios.com.br/movel/buscaCepConfirma.do’,array(
    ‘cepEntrada’=>$cep,
    ‘tipoCep’=>”,
    ‘cepTemp’=>”,
    ‘metodo’=>’buscarCep’
    ));
    phpQuery::newDocumentHTML($html, $charset = ‘utf-8′);

    foreach ($listaEndereco as $chave => $valor){
    $dados = trim(pq(‘.caixacampobranco .resposta:contains(“‘.$valor.’”) + .respostadestaque:eq(0)’)->html());
    if (strlen($dados) > 0 ){
    $endereco[$chave] = $dados;
    }
    }
    return $endereco;
    }

    ai nesse ponto vc passa os campos que vc gostaria que fossem preenchito e recebe apenas os que realmente existe:

    $dados = validaArrayEndereco($cep, array(
    ‘logradouro’ => ‘Logradouro: ‘,
    ‘bairro’ => ‘Bairro: ‘,
    ‘municipio/estado’ => ‘Localidade / UF: ‘,
    ‘cep’ => ‘CEP: ‘
    ));

    e por fim se a variavel $dados retornar uma array vazio é, sera por que não encontrou o CEP, caso contrario retornas só os
    dados que encontra, ve oque vc acha…

    faloww

    • Então Hudson, essa versão que você corrigiu já esta defasada. Há um tempo eu mudei da versão mobile dos correios, pois a versão desktop tinha os dados mais consistentes.
      Talvez por isso tenha sentido a necessidade de criar essa segunda validação. Tentei testar seu código, mas no momento os servidores dos correios parecem estar fora do ar (ao menos na minha maquina, rs).
      Verifique a versão que temos no github (https://github.com/feliperoberto/correios-cep/), se nela ainda houver a necessidade, pode dar um commit (aproveita que o código tá aberto, rs)!

      • da para testar aqui! http://cepcorreios.phpfogapp.com/?cep=58114000 ( no momento deste comentário o link não funcionava pois o server dos correios estava fora do ar, espero que volte logo)

      • Felipe tudo bem??
        esse link http://cepcorreios.phpfogapp.com/?cep=58114000 é oficial dos correios??? você sabe qual a variável dos resultados?

        obrigado.

      • Felipe Roberto disse:

        Sim, este servidor esta rodando uma das versões do webservice que criei no tutorial.
        O retorno dele é um json com cidade, uf, bairro, logradouro e cep.

      • deixa eu te explicar como o meu funciona, trabalho com ecommerce e minha programação hoje para busca de cep é:
        cep = $.trim($(‘input[name="postcode"]‘).val().replace(‘-’, ”));
        $.getScript(“http://cep.republicavirtual.com.br/web_cep.php?formato=javascript&cep=”+cep, function(){
        if(resultadoCEP["resultado"] == “1″){
        $(‘input[name="address_1"]‘).val(unescape(resultadoCEP["tipo_logradouro"])+” “+unescape(resultadoCEP["logradouro"]));
        $(‘input[name="address_2"]‘).val(unescape(resultadoCEP["bairro"]));
        $(‘input[name="city"]‘).val(unescape(resultadoCEP["cidade"]));
        $(‘input[name="company"]‘).focus();
        $(‘select[name=\'zone_id\']‘).load(‘index.php?route=account/register/estado_autocompletar&estado=’+unescape(resultadoCEP["uf"]));

        se você perceber verá que ele busca no site o endereço e retorna na variavel: resultadoCEP os valores.

        eu não entendo muito de programação, acho que preciso da variavel do seu retorno para poder incluir em minha lojinha. obrigado

    • Ok, entendi sua dúvida.
      o código será mais ou menos essa:

      $(‘[name="usuario[cep]“]’).bind(‘keyup blur’, function(){
      var $cep = $(this);
      var cep = $(this).val();
      cep = cep.replace(‘-’,”);
      if(cep.length == 8){
      $.getJSON(‘api/correios/cep.php’,{cep:cep},function(endereco){
      $cep.data(‘dados_cep’,endereco);
      if(endereco.uf){
      $(‘[name="usuario[complemento]“]’).val(”);
      $(‘[name="usuario[cep]“]’).val(endereco.cep);
      $(‘[name="usuario[logradouro]“]’).val(endereco.logradouro ? endereco.logradouro : ”);
      $(‘[name="usuario[numero]“]’).val(endereco.numero ? endereco.numero : ”);
      $(‘[name="usuario[bairro]“]’).val(endereco.bairro ? endereco.bairro :”);
      $(‘[name="usuario[cidade]“]’).val(endereco.cidade ? endereco.cidade : ”);
      $(‘[name="usuario[uf]“]’).val(endereco.uf ? endereco.uf : ”);
      }
      });
      }
      });

  15. valdeir disse:

    Valeu!! Ajudou bastante!!

  16. Olá Felipe, parabéns pelo artigo !

    Fiz a seguinte modificação para buscar os endereços pelo logradouro ou pelo cep trazendo um array como resultado, assim como funciona no site dos Correios.

    $dados = array();
    for($i=2; $ilength-1; $i++)
    {
    $dados[] =
    array(
    ‘logradouro’=> trim(pq(‘.ctrlcontent table tr:eq(‘.$i.’) td:eq(0)’)->text()),
    ‘bairro’=> trim(pq(‘.ctrlcontent table tr:eq(‘.$i.’) td:eq(1)’)->text()),
    ‘cidade’=> trim(pq(‘.ctrlcontent table tr:eq(‘.$i.’) td:eq(2)’)->text()),
    ‘uf’=> trim(pq(‘.ctrlcontent table tr:eq(‘.$i.’) td:eq(3)’)->text()),
    ‘cep’=> trim(pq(‘.ctrlcontent table tr:eq(‘.$i.’) td:eq(4)’)->text())
    );
    }
    echo(json_encode($dados));

    Se puder coloque no Git.

    Até mais !!!

  17. [...] Script base para implementação da busca do CEP por Ajax: http://www.pinceladasdaweb.com.br/blog/2012/01/31/webservice-consulta-de-cep-diretamente-ao-site-dos… [...]

  18. Rodolfo disse:

    Para que utilizar uma biblioteca gigante dessas, só para gerar uma requisição curl e recuperar os dados ?? isso é doidera.

    • O tutorial tem como objetivo principal mostrar as possibilidades de consumo de informação independente da disponibilização destas através de webservices oficiais.
      A biblioteca phpquqery foi utilizada para facilitar o entendimento, já que todo desenvolvedor conhece os seletores css (aqueles usados no tão popular jquery). Pode-se utilizar a manipulação direta do DOM por funções PHP ou até mesmo ir limpando via expressão regular se você for um ninja.
      Quanto a utilização do curl, esta pode ser substituída pela file_get_contents (usei curl, pois poderia vir ser necessário modificar o cabeçalho para simular acesso de um navegador).

  19. Michel Isoton disse:

    E ainda, a maioria das hespedagens deixa o http wrapper desabilitado e bloqueado, ou seja, file_get_contents() não funcionaria para arquivos remotos. cURL resolve isto. Mas o que o amigo falou sobre a biblioteca é real. Criando uma funçãozinha extra no código, com 4 ou 5 linhas, dá pra manipular o DOM de forma bem fácil… é interessante abordar isto.

  20. KARLOS EDUARDO disse:

    Olá, muito bom o código ..foi de grande valia ,,, para meu projeto … obrigado..

  21. olá, como eu faço para fazer a consulta?? eu tenho que colocar no no botão do campo cep para buscar no arquivo php??

    não entendi

  22. Felipe Roberto disse:

    O arquivo php é o webservice. Você fará uma requisição GET com o parâmetro cep e ele ira retornar um objeto json com os dados referentes a consulta(CEP, logradouro, bairro, cidade e uf).
    Por tratar-se de um webservice o retorno da requisição precisara ser tratado. Com jquery é fácil, basta usar a função getJSON.

    • cara acho que consegui dar um passo, veja http://opusconsultoria.com.br/loja/cep.php?cep=SEUCEP

      mas uma dúvida qual é a variável de retorno?? pq eu preciso colocar no meu código

      cep = $.trim($(‘input[name="postcode"]‘).val().replace(‘-’, ”));
      $.getScript(“http://opusconsultoria.com.br/loja/cep.php?cep=”+cep, function(){
      if(dados["resultado"] == “1″){
      $(‘input[name="address_1"]‘).val(unescape(dados["logradouro"])+” “+unescape(dados["logradouro"]));
      $(‘input[name="address_2"]‘).val(unescape(dados["bairro"]));
      $(‘input[name="city"]‘).val(unescape(dados["cidade"]));
      $(‘input[name="company"]‘).focus();
      $(‘select[name=\'zone_id\']‘).load(‘index.php?route=account/register/estado_autocompletar&estado=’+unescape(dados["uf"]));
      }else{
      $(‘input[name="address_1"]‘).focus();
      alert(“Endereço do cep não encontrado. Digite o endereço manualmente!”);
      }

      o resultado disso tudo, eu vi no arquivo cep.php que a variavel dados é a resposta de tudo, mas não rolou :( tem alguma luz? rs

  23. Quilson disse:

    Não sei quanto tempo vai ficar disponível este recurso mas foi nota 1000. Obrigadão pela contribuição.

    Se alguém ainda não achou no link a seguir tem os outros serviços via mobile que podem ser aproveitados.
    http://m.correios.com.br/movel/index.do

    • pois é, a ideia é essa mesmo.
      ja implementei também o de código de rastreio.
      e gostaria que todos contribuíssem no github (https://github.com/feliperoberto/correios-cep).
      com o q temos lá no github já da pra listar busca de endereços, achar o endereço de um cep e saber onde esta sua encomenda.

      • Quilson disse:

        Felipe,

        Sabe o que seria bom aproveitar pra fazer em paralelo? Um esquema para puxar para uma tabela SQL a base de dados dos Correios pra se no caso os Correios entrarem numa de bloquear este recurso teriamos uma base de dados CEP atualizada e free.

        Mexo melhor com Delphi do que PHP(fraquinho), vou ver se pego as séries de CEP utilizadas no correio e crio um programinha para fazer este BD.

        Utilizei este esquema seu em meu programa delphi e ficou filé mesmo. Muis uma vez obrigado por compartilhar.

      • Legal a iniciativa, só vai com calma para não alertar o pessoal da TI deles, vai que notam um consumo muito grande e seguido e então implementem alguma barreiras tipo captcha.

      • Quilson disse:

        Ok, vou ver se faço isso na madruga quando o servidor é menos exigido. Qualquer novidade posto aqui. Valeu pela força e atençào.

      • na verdade não me referia apenas ao horario da execução, mas também a frequência.

      • Quilson disse:

        Tem como regular uma frequencia e também não fazer em sequencia de faixa de cep para não chamar atenção e também alterar o ip a cada X requisições, creio que o conjunto já dá uma camuflada.

        O que deve rolar com o tempo se notarem alguma coisa é aquele esquema que tem no rastreamento de objetos “Resolva a expressão: 2 + 3 “, no Delphi acho que resolvo fácil mas no PHP nem sei.

  24. Wilton disse:

    Ola Felipe…Parabens seu script é muito bom mesmo…
    tenho uma duvida…tem como fazer uma pesquisa do CEP quando ja tenho o endereco do cliente ??? fazer o inverso que vc fez ai ?

    • da sim, na verdade o que você digitar ele vai buscar!
      se digitar cep ele tras o endereço preciso, se não ele vai listar as possibilidades. no caso se digitar texto vai conseguir encontrar.
      vale lembrar que a busca dos correios não é perfeita que nem o google, as vezes pode ser difícil encontrar o que procura.
      no código q tenho no github (https://github.com/feliperoberto/correios-cep) está um pouco mais atualizado, lá ele filtra para busca de cep ou endereço e retorna 1 objeto ou 1 array de objetos. da uma olhada.

  25. Felipe disse:

    Olá Felipe tudo bem?!?!

    Seguinte baixei seus códigos para substituição do meu código, mas apenas rodando o cep.php com o cep 13140284 de maneira alguma consigo fazer o charset funcionar corretamente… como posso fazer para Paulínia não aparecer como Paul\u00ednia?

    Obrigado e parabens pela iniciativa

    • Na verdade seu problema não esta no charset. Esse ‘Paul\u00ednia’ esta encodado para json (encodado tipo url, para passar por querystring), teste no console: decodeURI(‘Paul\u00ednia’).
      Se você der um eval no objeto json, tipo (getJSON do jquery), vai ver paulínia escrito corretamente, no entanto se tiver modificado o código para usar diretamente pelo php basta não usar a função json_encode() do finalzinho;

  26. Denis disse:

    Olá obrigado pela publicação desta dica. Foi bastante útil para mim.

  27. Mike disse:

    Achei legal pra quem precisa de uma base com dados de ruas, ceps, cidades e países atualizada online e offline. http://www.rua-cep-cidade-paises.info #ruas #ceps #cidades #paises

  28. Leonardo disse:

    Olá Felipe tudo bem? tenho uma sugestão e um pedido de ajuda.
    Sugestão é que por exemplo o cep 12230901 é um condomínio é no endereço aparece o nome do condomínio e não a rua, poderia ser criado um campo separado para esse nome do local.
    Pedido de ajuda tenho uma ferramenta integradora com o VirtueMart um sistema de ecommerce para Joomla está bem parecido com o seu mas não consigo adapta-lo poderia te passar para me ajudar? Se sim pode me mandar um email com seu email que mando o código :D
    Abraço

  29. Parabéns pelo excelente TRABALHO!!! Muito bom mesmo!

  30. Felipe concertei sua versão mobile, agora ele retorna aquele tipo de CEP que te falei sem o nome do cliente só o endereço, mas está com problemas de acentuação como posso te enviar?
    Abraço

  31. Demerval disse:

    Valeu Felipe muito bom o seu trabalho, fiz alguns ajustes para se adequar a minha aplicação e funcionou legal. Parabéns pelo TRABALHO.

  32. Michel disse:

    Parabéns pelo código Felipe.
    Estou tentando buscar por um nome de rua onde deveriam retornar vários registros, porém ele retorna apenas um. É assim mesmo, ou estou fazendo algo errado?

    Obrigado

  33. Vix Michel, já verifiquei e o problema surgiu qndo voltei para a versão mobile dos correios para adaptar ao novo retorno de nome de cliente no caso de ceps como 12230-901, no entanto a funcionalidade de busca parou de funcionar. Tenta recuperar uma versão antiga no github, se não é só descomentar a outra função cep (acho que chama cepDesktop). Se conseguir corrigir na própria versão mobile atualize lá no github.
    Um dos problemas esta no elemento do looping da busca que são dois (formando lista alternada) mas eu programei só para as impares.

  34. Wanderson Valério disse:

    Olá. Muito bom e prático esse código. Encontrei apenas uma deficiência. Seria possível validar o cep, ou seja, se o usuário informar um cep não valido, ele retorna tudo vazio.

    Ansioso por uma resposta.

    Obrigado.

  35. geraldo disse:

    Caro Felipe
    Gostaria de parabenizado pelo post, foi o melhor que encontrei até agora, parabéns

  36. X1alex disse:

    Felipe legal seu Post, por que não utilizamos direto a API de maps do google digitei o meu cep na barra de procura do Maps do google e retornou o endereço corretinho, será que não temos essa posibilidade, lembrando concerteza o servidor do google deve é mais rapido para uma requisição do que o dos correios.

  37. Gustavo Melo disse:

    Cara vc acha difícil implementar isso em Java para desktop? Estou precisando muito fazer essa mesma coisa, só que entendo muito pouco de php, será que vc pode me dar uma ajudinha?

    • Puts Gustavo, não programo em java.
      Mas vou tentar ajudar.
      O que você deverá fazer é entender como fazer um webscrapper em java e tratar o respectivo conteúdo. Em php eu usei o PHPQuery que deu uma tremenda mão na roda na hora de limpar o resultado dos correios.

  38. Parabéns pelo Webservice! Muito útil e bem explicado. E melhor ainda o pessoal que ajuda. Estão todos de parabéns.

  39. Lucas Bertoni disse:

    Pessoal, o site mobile dos correios está fora do ar por aqui, sendo assim, parou de funcionar, alguém sabe se é definitivo ou temporário?

  40. Olá Felipe e pessoal boa tarde,

    Então depois de utilizar este script por este ano todo em vários sistemas e aplicativos notei como ele tinha uma queda na recuperação dos dados dos Correios e alguma vez na vida eu utilizei um banco de dados comprado dos Correios.

    Procurei aqui e encontrei as fontes deste banco de dados que originalmente era em Access em um CD e na época passei para MySQL.

    As tabelas estão assim:
    – Este era um CD que os Correios vendia para empresas (nem sei se vende ainda) com códigos internos, nomes sem acentos, abreviações e outras.
    – Cada tabela é separada e são relacionadas entre si por códigos (uf, cidades, bairros e logradouros).
    – A codificação é UTF8 com HTML Encode.
    – A tabela logradouros está dividida em 4 arquivos por causa do tamanho (Comece a importação pelo 0).
    – Foi exportada direto do PHPMyAdmin, ou seja, pode ser importada diretamente.
    – A data destes dados é entre 2002 e 2004, não me recordo de jeito nenhum o ano exato.

    Bom o objetivo deste compartilhamento é adiantar o trabalho caso queiram manter aquela idéia de ter uma redundância no casos que em cai o sistema dos Correios, no meu caso eu fiz isso, estou usando com redundância rebatendo em um webservice interno caso falhe os dados dos Correios.

    Espero ter ajudado, abaixo os links das tabelas e boas festas a todos !!!

    http://www.iautomate.com.br/apps/correios/cep_tbluf.sql.gz (1KB)
    http://www.iautomate.com.br/apps/correios/cep_tblcidades.sql.gz (163KB)
    http://www.iautomate.com.br/apps/correios/cep_tblbairros.sql.gz (371KB)
    http://www.iautomate.com.br/apps/correios/cep_tbllogradouros-0.sql.gz (3.628MB)
    http://www.iautomate.com.br/apps/correios/cep_tbllogradouros-1.sql.gz (4.120MB)
    http://www.iautomate.com.br/apps/correios/cep_tbllogradouros-2.sql.gz (4.403MB)
    http://www.iautomate.com.br/apps/correios/cep_tbllogradouros-3.sql.gz (1.177MB)

    Obs.: Felipe me retorne quando baixar os arquivos pois não vou manter no site por muito tempo.

  41. Júlio disse:

    Felipe, seus códigos estavam funcionando perfeitamente na minha aplicação.
    Porém hoje (08/01), as dados simplesmente pararam de retornar. Isso é normal, por quanto tempo pode ficar assim?
    alguém mais teve este problema?
    Obrgado,
    Júlio

    • Sim Júlio, infelizmente.
      Trata-se de uma instabilidade constante nos sites dos correios.
      Inclusive o Luciano complementou esse webservice. Ele criou um mecanismo para em casos de falhas como a que você passou, o sistema reconheça e faça uma consulta alternativa em uma base de dados local com dados antigos dos correios (é uma base antiga que roda a internet faz tempo, mas certamente irá quebrar o galho por conta da frequência de instablidade dos sites dos correios.

      Quanto as instabilidades, notei que nem sempre são simultâneas na versão desktop e mobile dos sites dos correios. Sendo assim um mecanismo muito eficiente seria se pudéssemos fazer 3 consultas. Primeira tentativa na versão mobile, depois na desktop e finalmente na base local.

      • Gustavo Déo disse:

        Bom dia…

        há tempos que venho procurando uma base de dados atualizada… Mas infelizmente não há uma versão gratuita…
        Então eu desenvolvi um projeto em delphi onde importei todas as cidades do IBGE e estou fazendo consulta no site dos correios http://m.correios.com.br/movel/buscaCepConfirma.do e tratando os dados e inserindo na tabela do cep.. resumindo… é um trabalho de operário… pois não sei quais os ceps existem e quais não existem… mas poderiamos reunir forças e cada um fazer a consulta de uma faixa de cep.. e depois reunir os bancos… assim teríamos uma tabela de cep atualizada dos correios… Quem se propõe a ajudar???

      • Gustavo Déo disse:

        A consulta e o tratamento dos dados é feito de forma dinâmica… O trabalho de operário é pelo fato de ter que consultar do 00000-000 até o 99999-999.

      • Felipe dá para testar o codido utilizando localhost? Estou tentando e está direcionando para o local de down dos seus arquivos.

      • Felipe dá para testar o codigo utilizando localhost? Estou tentando e está direcionando para o local de down dos seus arquivos.

      • Da sim Cleiton, algo deve estar mal configurado.

  42. Joel Ramos disse:

    Caro Felipe, boa noite!

    Parabéns a você e a todos os demais colaboradores pela busca de um produto final que atenda aos anseios e necessidades técnicas de todos os projetos.
    Acompanhei todos os comentários sobre o projeto e para onde ele caminha, ou seja termos uma solução online e offline simultaneamente, para colaborar com tal intuito e poupar o trabalho de operário de nosso colega Gustavo Déo, creio que Eu possa fornecer ao projeto gratuitamente a base de CEP BR atualizada até março/2010, para tanto queira me contatar por email para viabilizarmos o envio da mesma, pois é um BD grande.
    Forte Abraço a todos os colegas.

  43. Maik Tomé disse:

    Show, muito bom a dia e exemplos!

  44. Bruno disse:

    Gostei do post, mas não consegui usar. Tem um exemplo disso funcionando?

  45. Muito boa a ideia!
    Adaptei a linguagem java, e funcionou perfeitamente!

    Parabéns!

  46. Alberto Rodrigues disse:

    Olá.
    Parabéns!
    Muito Legal.
    Como eu chamo a rotina?
    Chamei assim: http://www.meier.globobairros.com.br/cep.php?cep=20940050

    Funcionou, mas as informações veio todas esquisitas.

    {“logradouro”:”Rua do Parque”,”bairro”:”S\u00e3o Crist\u00f3v\u00e3o”,”cep”:”20940050″,”cidade”:”Rio de Janeiro”,”uf”:”RJ”}

    Como faço para resolver quando o endereço tiver acentuações?
    Grato.

  47. Anderson Amann disse:

    Estou usando a versão mobile alguém conseguiu pegar os dados da segunda página em diante na pesquisa por endereço? Quando faço a requisição passando os valores:
    ‘metodo’=>’Proximo’
    ‘numPagina’=>1
    Para mim retorna duas linhas null.

  48. isaaclopes disse:

    Ola,
    No caso de consulta com endereço a versão do git traz apenas um resultado no foreach.
    segue exemplo de correção
    GIT: ‘cliente’=> trim(pq(‘.caixacampobranco .resposta:contains(“Cliente: “) + .respostadestaque:eq(0)’)->html()),
    CORRECAO: ‘cliente’=> trim(pq($tr)->find(‘.resposta:contains(“Cliente: “) + .respostadestaque:eq(0)’)->html()),

    outra coisa quando tem mais de um resultado ele cria duas caixa: caixacampobranco e caixacampoazul, precisa fazer o tratamento das duas, estou finalizando e ja envio!

    • isaaclopes disse:

      segue pode ser melhorada,
      traz todos os endereços
      $dados = array();
      $c = 0;
      $t = count(pq(‘.caixacampobranco’));
      $i = count(pq(‘.caixacampoazul’));

      foreach (pq(‘.caixacampobranco’) as $tr) {
      $dados[$c] = array(
      ‘cliente’=> trim(pq($tr)->find(‘.resposta:contains(“Cliente: “) + .respostadestaque:eq(0)’)->html()),
      ‘endereco’=> trim(pq($tr)->find(‘.resposta:contains(“Endereço: “) + .respostadestaque:eq(0)’)->html()),
      ‘logradouro’ => trim(pq($tr)->find(‘.resposta:contains(“Logradouro: “) + .respostadestaque:eq(0)’)->html()),
      ‘bairro’ => trim(pq($tr)->find(‘.resposta:contains(“Bairro: “) + .respostadestaque:eq(0)’)->html()),
      ‘cidade/uf’ => trim(pq($tr)->find(‘.resposta:contains(“Localidade / UF: “) + .respostadestaque:eq(0)’)->html()),
      ‘cep’ => trim(pq($tr)->find(‘.resposta:contains(“CEP: “) + .respostadestaque:eq(0)’)->html())
      );
      $dados[$c]['cidade/uf'] = explode(‘/’,$dados[$c]['cidade/uf']);
      $dados[$c]['cidade'] = trim($dados[$c]['cidade/uf'][0]);
      $dados[$c]['uf'] = trim($dados[$c]['cidade/uf'][1]);
      unset($dados[$c]['cidade/uf']);
      if($dados[$c]['endereco']){
      $dados[$c]['logradouro'] = $dados[$c]['endereco'];
      }
      unset($dados[$c]['endereco']);
      $c += 1;
      }
      if ($i > 0){
      foreach (pq(‘.caixacampoazul’) as $tr) {
      $dados[$t] = array(
      ‘cliente’=> trim(pq($tr)->find(‘.resposta:contains(“Cliente: “) + .respostadestaque:eq(0)’)->html()),
      ‘endereco’=> trim(pq($tr)->find(‘.resposta:contains(“Endereço: “) + .respostadestaque:eq(0)’)->html()),
      ‘logradouro’ => trim(pq($tr)->find(‘.resposta:contains(“Logradouro: “) + .respostadestaque:eq(0)’)->html()),
      ‘bairro’ => trim(pq($tr)->find(‘.resposta:contains(“Bairro: “) + .respostadestaque:eq(0)’)->html()),
      ‘cidade/uf’ => trim(pq($tr)->find(‘.resposta:contains(“Localidade / UF: “) + .respostadestaque:eq(0)’)->html()),
      ‘cep’ => trim(pq($tr)->find(‘.resposta:contains(“CEP: “) + .respostadestaque:eq(0)’)->html())
      );
      echo ”;
      $dados[$t]['cidade/uf'] = explode(‘/’,$dados[$t]['cidade/uf']);
      $dados[$t]['cidade'] = trim($dados[$t]['cidade/uf'][0]);
      $dados[$t]['uf'] = trim($dados[$t]['cidade/uf'][1]);
      unset($dados[$t]['cidade/uf']);
      if($dados[$t]['endereco']){
      $dados[$t]['logradouro'] = $dados[$t]['endereco'];
      }
      unset($dados[$t]['endereco']);
      $t += 1;
      }
      }

      • Anderson Amann disse:

        Então o site dos correios na versão mobile traz 10 resultados por página, na primeira página eu pego todos os ceps tranquilamente, aí eu crio outra requisição colocando os parâmetros ‘metodo’=>’Proximo’ e ‘numPagina’=>1 para pegar os 10 ceps da segunda página e assim por diante não retorna nada só duas linhas “null”. A minha dúvida é se alguém conseguiu. Se não vou ficar sempre com os 10 primeiros resultados.

      • Desconsiderem a versão mobile e usem a versão desktop. Há muitas incompatibilidades

  49. Anderson Amann disse:

    Pode ser, mas o problema é que as informações da versão desktop são cortadas, ficando difícil de conseguir com exatidão bairros e endereços extensos.

  50. Thiago disse:

    Felipe, parabéns pelo projeto!

    Estou com problemas, o retorno está vindo sempre vazio!
    http://www.tkmarinho.com/get_end.php?cep=31170170

    fiz o teste para ver o html q está vindo na class correio e vem o formulário mobile

    alguma luz?

    abs

Leave a Reply