Webservice – Consulta de CEP diretamente ao site dos correios
Postado por: Felipe Roberto em
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.














Bacana, será que os correios irá disponibilizar pra SEDEX e PAC também?
Já tem disponível na versão mobile consulta de preços e prazos, rastreamento de objetos e endereço das agencias.
O principio é o mesmo, basta adaptar o código. Assim que der faço isso e posto o link dos outros serviços.
Eu acabei que vi aqui mesmo.. funciona bem :)
Recentemente a empresa que trabalho utiliza o iWService, para quem se interessar: http://www.iwservice.com.br
Nossa, muito bom isso. Usando essa ideia aí vou me livrar de diversos problemas que tenho em minhas aplicações.
Parabéns pelo post!
Excelente post eim, usando a base dos correios ela sempre estara atualizada. Vlw
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!!!
Alguem ja viu isso?
http://www.correios.com.br/webservices/
preciso de uma url com https, alguém aqui conhece?
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!!!”;
}
Opa, vlw pela contribuição!
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
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.
Ainda prefiro a API DevelMan.
[plain] http://api.develman.com/correios/cep.dm?v=
[json] http://api.develman.com/correios/cep.dm?json&v=
[xml] http://api.develman.com/correios/cep.dm?xml&v=
Inclusive, possuem um para verificar o nome da pessoa através do CPF:
[plain] http://api.develman.com/receita/cpf.dm?v=
[json] http://api.develman.com/receita/cpf.dm?json&v=
[xml] http://api.develman.com/receita/cpf.dm?xml&v=
Muito boa materia!
Krysoft, as API do develman são interessantes, porém não encontrei nenhuma documentação, se tiver um exemplo html da busca de CEP com json ou plain eu agradeceria.
basta informar o CEP ou CPF após o &v= no final da URL.
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.
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.
Felipe, tem toda a razão. Bastou eu imprimir a matriz $dados com print_r e deu tudo certo. Muitíssimo obrigado!
Ta maneiro o codigo mas precisa ser aperfeiçoado cotem muitos erros ainda!
Opa Luiz se quiser pode contribuir, o projeto esta no git.
Se não, pode fazer como os colegas fizeram ali em baixo, diga o problema e eu faço a correção.
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.
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.
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á.
Parabéns pelo post. Agora com esse phpQuery da pra fazer paradas bacana.
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.
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.
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 : ”);
}
});
}
});
cara só uma dúvida, você está buscando as informações no endereço api/correios/cep.php eu mantenho esse endereço ou troco até o caminho do meu arquivo cep.php?? abraço
isso, você deve trocar pelo seu arquivo (é que na pressa eu só copiei o que eu usei)
kkk desisto :P mas obrigado pelas dicas!
Valeu!! Ajudou bastante!!
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 !!!
Já não é o primeiro que sugere fazer buscas de endereço pelo mecanismo.
A princípio não era o objetivo, mas devido a necessidade vou implementar. Valeu pela contribuição, logo coloco no git.
Pronto, está lá. Atualizei o código e coloquei seu crédito.
[...] 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… [...]
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).
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.
Olá, muito bom o código ..foi de grande valia ,,, para meu projeto … obrigado..
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
Opa, respondi em lugar errado. Leia abaixo
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
Opa Leonardo, respondi ali em cima
fala mestre.. puxa cara eu vou testar hehe.. hiper ansioso! :) obrigado mesmo.. se rolar você não ajudará somente a mim.. mas a muitos pois vou compartilhar o código!! e terá seus créditos! :) vlw
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.
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.
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.
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.
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.
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;
Olá obrigado pela publicação desta dica. Foi bastante útil para mim.
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
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
No momento o site dos correios não esta abrindo este cep, embora o código consiga ver o resultado. Então dei uma debugada e percebi que esta informação de cliente (edifício) esta disponivel apenas na versão mobile.
nos proximos dias vou atualizar o código, passe dar uma olhada no github, se não pode fazer você mesmo que eu mesclo depois.
http://www.buscacep.correios.com.br/servicos/dnec/consultaLogradouroAction.do no site dos correios funciona me add no facebook
https://www.facebook.com/leonardoatrobles
Cep Especial
Cliente: Edifício Por do Sol
Endereço: Rua Porto Novo, 300
Bairro: Jardim Satélite
Localidade / UF: São José dos Campos/SP
CEP: 12230-901
Parabéns pelo excelente TRABALHO!!! Muito bom mesmo!
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
Opa, valeu Leonardo. Você fez em cima da versão do github? Se quiser pode inclusive enviar por lá, se não me envie para meu e-mail. contato@feliperoberto.com.br
Te mandei o email :D
Valeu Felipe muito bom o seu trabalho, fiz alguns ajustes para se adequar a minha aplicação e funcionou legal. Parabéns pelo TRABALHO.
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
Ops Michel, é assim mesmo, embora não devesse ser. Na verdade quando fiz as últimas atualizações não me atentei a este detalhe. Vou verificar e tentar corrigir.
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.
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.
A versão atual no github retorna um array vazio, então no js é só você validar: // if(resposta.length === 0) alert(‘cep não encontrado’);
Caro Felipe
Gostaria de parabenizado pelo post, foi o melhor que encontrei até agora, parabéns
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.
Pois então x1alex, já testei isso e nem sempre a busca é tão efetiva. Veja o meu cep (08773-380), ele não retorna o endereço.
Teste em : http://maps.googleapis.com/maps/api/geocode/json?address=08773-380&sensor=false ou https://maps.google.com.br/maps?q=08773-380&sugexp=chrome,mod%3D16&um=1&ie=UTF-8&hl=pt-BR&sa=N&tab=wl
Ainda que a busca fosse mais rápida não acredito que seja um fator decisório pois certamente não deve ser tão mais rápido a fim de justificar o delay de atualização de dados. Lembre-se, que quem gera e atualiza os endereços e ceps são os correios, portanto se alguém terá a base atualiza com exatidão e constância certamente será os Correios.
Verdade a posibilidade dos correios ficou bem mais viavel no final das contas, Valeu, pela tentativa.
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.
Parabéns pelo Webservice! Muito útil e bem explicado. E melhor ainda o pessoal que ajuda. Estão todos de parabéns.
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?
É temporário, mas é comum sair do ar. A versão desktop é mais estável embora eu já tenha visto cair também.
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.
Excelente contribuição Luciano. Infelizmente estou viajando e não vou conseguir baixar. Sugiro que envie esse arquivos ao github assim ficará disponível a todos e de imediato. Em todo caso, ao voltar de férias lhe procuro para ter acesso novamente ao sistema de redundância.
Beleza Felipe,
Deixarei até quando voltar assim poderá ver melhor depois.
Assim que voltar ao trabalho me avise.
Boas Festas e boa viagem !!!
Olá Felipe bom dia,
Retornando o contato enviado antes das festas de final d ano, retirarei hoje os links para o banco de redundância.
Peço que se ainda não baixou por favor faça hoje.
Até mais !!!
Opa Luciano fiz download hoje pela manhã. Obrigado.
Assim que possível eu atualizo no github
Beleza já retirei do ar.
Até mais e obrigado por avisar.
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.
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???
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.
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.
Boa noite Joel,
pode me enviar para meu email? contato@feliperoberto.com.br – é gmail fique tranquilo qnto ao tamanho do anexo. mas ficaria feliz se colocasse esses arquivos no github ( https://github.com/feliperoberto/correios-cep ), assim todos teriam acesos.
já possuo a versão de 2004 fornecida pelo Luciano Oliveira Borges, mas seria interessante ter uma versão mais recente.
[...] Consulta diretamente ao site dos correios [...]
Show, muito bom a dia e exemplos!
Gostei do post, mas não consegui usar. Tem um exemplo disso funcionando?
Tem sim Bruno, veja no seguinte comentário: http://www.pinceladasdaweb.com.br/blog/2012/01/31/webservice-consulta-de-cep-diretamente-ao-site-dos-correios/#div-comment-482672
Muito boa a ideia!
Adaptei a linguagem java, e funcionou perfeitamente!
Parabéns!
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.
A resposta parece esquisita pois esta encodada em json.
Uma aplicação front-end rapida se da através de uma requisição GET para a url da api e trata o retorno com eval, transformando a string json em um objeto javascript.
Veja o exemplo com jquery no seguinte comentário: http://www.pinceladasdaweb.com.br/blog/2012/01/31/webservice-consulta-de-cep-diretamente-ao-site-dos-correios/#div-comment-482672
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.
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!
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;
}
}
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
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.
Vix, então a situação fica complicada, já que a versão mobile também omite alguns dados complementares ( veja nos comentários ).
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
Recomendo usar a versão desktop. É a que uso atualmente.
Look: http://www.wscep.com