atualizado: php, curl, cookies, sessions, cpf e site da receita federal

Edit: este código provavelmente não funciona mais, mas o princípio por trás dele deve funcionar sim. então, sinta-se à vontade para discutir nos comentários, mas não tenho planos de atualizá-lo tão cedo.

não é nem necessário informar mas, antes de qualquer coisa, vou dizer: aqui você não vai encontrar nada a respeito de cpfs falsos, burlagem de captcha, captura automática de cpfs ou quaisquer outras práticas consideradas anti-éticas ou mesmo ilegais. o propósito é puramente de estudo. se alguma informação aqui estiver em desacordo com as leis, peço que me informe e o texto será modificado/removido. entretanto, observando os termos de utilização do site da receita federal, não foi encontrado nada que estivesse em desacordo com o que foi exposto aqui.

update (23/11/2011): se você quer somente baixar os fontes, vai aqui:
http://cacovsky.googlecode.com/files/receita_atualizado.zip

esses dias estive brincando com o php-curl, uma extensão do php que permite fazer requisições http, https e ftp, suportando proxies, cookies e autenticação por usuário e senha. essa extensão do php é derivada de um programa em linha de comando chamado curl. o php-curl (assim como o curl) oferece muitos recursos mas, obviamente, abordarei aqui apenas os que me interessa; a referência completa você vai encontrar aqui, é tudo muito bem documentado.

the answer lies within (the source code!)

do outro lado da idéia, o site da receita federal fornece um serviço público de consulta de cpf; com esse serviço, é possível obter informações sobre a regularidade do documento, bem como uma assinatura eletrônica, nome completo, essas coisas. no rodapé do site tem informando que, para utilização correta, é necessário ter habilitada a gravação de cookies.

hum…

pode ser uma necessidade de alguns criar cadastros vinculados aos cpfs com algum grau de confiabilidade. entretanto, de forma gratuita na internet eu só encontrei funções que calculam a validade do cpf, através de dígitos verificadores. basicamente, é feito um cálculo matemático que assegura que os números digitados fazem sentido entre si. no caso do cpf, um cálculo sobre os 9 primeiros dígitos determinam quais seriam os dois dígitos finais. assim, se tiver algum número errado, é fácil verificar que tá errado, pois os dígitos verificadores não vão conferir.

assim, se uma pessoa informa um cpf num cadastro, é difícil para você saber se aquele cpf pertence realmente àquele que se diz dono dele. eu mesmo não encontrei (ainda bem) nenhum site em que você informe o nome e obtenha o cpf (ou vice-versa). já ouvi dizer de sites com webservices ou formulários que fornecem esse serviço de busca, mas cobrando por isso; entretanto, procurando rapidamente, não encontrei nenhum.

então, imaginei que fosse possível utilizar o php-curl para 1) acessar o site da receita para exibir na sua própria página o captcha que é exibido para confirmação no site da receita; 2) fazer com que o usuário digite o cpf e o captcha corretamente; 3) devolver para o site da receita os dados informados pelo usuário e 4) recuperar o nome do indivíduo. tudo isso de forma transparente para o usuário. vou mostrar a seguir como fiz isso.

como funciona a consulta pública do site da receita

primeiro e mais importante, o captcha é uma imagem gerada dinamicamente, com o objetivo de evitar requisições automáticas. o endereço da imagem é gerado na hora em que você o acessa, através de uma função javascript semelhante à seguinte:

function Image()
	{
	    var date = new Date();    	    document.write('<img id="imgCaptcha" border="0" alt="Imagem com os caracteres anti robô" src="http://www.receita.fazenda.gov.br/scripts/srf/intercepta/captcha.aspx?opt=image&v=' + date.getTime() + '" />')
	}

observe o parâmetro v (que recupera o valor de date.getTime()); eu não sei pra que ele serve. omitindo-o, não percebi diferenças, se descobrir, me avise🙂 . entretanto, eu optei por mater ele lá. o colega thiago ornellas informou que esse macete serve para que o navegador, a cada acesso que se faça na página, reconheça que se trata de uma nova imagem e, assim, realize forçosamente a atualização da imagem. (em php,  é possível definir a validade da imagem através da função header(), para prevenir caching; veja mais aqui)

investigando o formulário do site da receita, foi fácil perceber três informações do formulário que são enviadas via post;

  1. um campo de texto de nome “txtCPF”, com o cpf;
  2. um campo de texto de nome “idLetra”, com os dados do captcha;
  3. um botão do tipo submit, de nome “Enviar” e com valor “Consultar”;
cookie do site da receita federal

cookie do site da receita federal; o valor foi omitido por privacidade

esse cookie é definido na hora em que você, no seu navegador, acessa o site da receita.

exibindo o captcha da receita através do seu site

pense comigo: se você simplesmente exibisse a imagem diretamente no navegador do seu usuário, de quem seria o cookie definido pelo site da receita? seria do seu usuário! para que seu site, através do php-curl, pudesse recuperar o resultado após o usuário digitar as informações do captcha e do cpf, seria necessário que seu site tivesse os cookies para isso, right?

então temos nosso primeiro ponto: seu site php tem que ter os cookies guardados. o local recomendado para isso é a pasta temporária do sistema. em php, você pode obter essa pasta com a função sys_get_temp_dir() e pode criar um arquivo de nome único com a função tempnam(); seguindo recomendações dessa página, vi que uma forma recomendada para obter a pasta temporária é via “realpath(sys_get_temp_dir())”. é importante salientar que você precisa utilizar um arquivo temporário de nome único, uma vez que vários usuários poderão estar acessando o seu site ao mesmo tempo; então, para cada usuário, um cookie.

bom, então devemos utilizar a pasta temporária para armazenar os cookies. entretanto, observe que existem, pelo menos, duas situações em que deveremos “saber” o nome do nosso arquivo de cookie: 1) quando exibirmos o formulário com captcha recuperado da receita (nosso cookie deve estar guardadinho!) e; 2) quando formos consultar os dados com o cpf e o captcha informados pelo usuário. se seu cenário não for esse, é algo parecido a isso (mesmo que seja via ajax, etc, você ainda vai ter que saber a mesma informação em dois momentos distintos), para isso utilizaremos sessions.

está começando a complicar, mas vamos já acabar com isso! até agora, teremos a geração de um cookie por usuário que acessar a página e armazenaremos o nome desse cookie em uma variável de sessão. um último comentário: em sessão, vamos armazenar apenas o nome do arquivo. se armazenássemos o endereço completo do arquivo, um usuário experiente teria acesso a informações do seu sistema de arquivos, e isso pode representar uma falha de segurança; nós, server-side, já sabemos que é na pasta temporária.
segue como eu fiz isso, no início do script formulario.php:

<?php
	session_start();

	$dir_sep = DIRECTORY_SEPARATOR;

	$cookie_file = tempnam (realpath(sys_get_temp_dir()), "CURLCOOKIE");
	$_SESSION['cookie_file'] = substr($cookie_file, strrpos (tempnam (realpath(sys_get_temp_dir()), "CURLCOOKIE"), '/'));
?>
<html>
<head>
    <title>cpf hack</title>
</head>
...

seguindo adiante, as coisas ficam mais fáceis. apenas vamos pegar a imagem do site da receita, armazenar numa pasta local do servidor e exibi-la na página do usuário. para isso, é imprescindível ter permissão de escrita numa subpasta “images”:

...
<head>
 <title>cpf hack</title>
</head>
 <body>
 <?php

 $my_site = "http://localhost/receita/";

 //parte 1: acessar o site da receita e obter o cookie do captcha apropriadamente

 $url_imagem = "http://www.receita.fazenda.gov.br/scripts/srf/intercepta/captcha.aspx?opt=image&v=".time();
 $ch = curl_init ();
 curl_setopt ($ch, CURLOPT_URL, $url_imagem);
 curl_setopt ($ch, CURLOPT_COOKIEJAR, $cookie_file);
 curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
 $output = curl_exec ($ch); // the real thing

 $img_file_name = tempnam ("images/", "CURLGIF_");
 $img_data = imagecreatefromstring($output);
 imagegif($img_data, $img_file_name);

 $img_link = $my_site."images/".substr( $img_file_name, strrpos ($img_file_name , '/'));

 //detectando sistema operacional
 $os = strtoupper(php_uname('s'));
 //eh windows
 if (strpos($os, 'WIN')===TRUE) {
    $img_link = str_replace('\\','/',$img_link);
 }
 ?>

 <form method="post" action="consultar.php">
 CPF: <input type="text" name="txtCPF"/> <br />
 Captcha: <input type="text" name="idLetra"/> <br />
 <img src="<?php echo $img_link ?>" />  <br/>
 <input id="id_submit" name="Enviar" type="submit" value="Consultar"/>
 </form>
 </body>
</html>

veja que aqui eu gerei o link para a imagem, defini algumas opções do curl e fiz a requisição. depois criei a imagem, salvei-a num arquivo com um nome qualquer e depois exibi essa imagem no formulário do meu usuário.

não havia necessidade de se dividir o código php nesses três trechos, foi só pra falar uma parte de cada vez. entretanto, o session_start() tem que vir antes de qualquer informação ser enviada para o navegador do usuário.

voilá!

realizando a consulta no site da receita

depois dessa etapa inicial, essa segunda parte fica bem mais fácil. após o usuário inserir as informações e enviá-las, é só o seu site realizar o post no site da receita utilizando o mesmo cookie (que tá na minha variável de sessão). depois, neste exemplo, é feita uma pesquisa por strings específicas para capturar o nome da pessoa física, além de uma conversão de codificação. segue o código do arquivo consultar.php, conforme modificações sugeridas pelo leonardo felipe:

<?php
	session_start();

	//parte 2: realizar a requisição utilizando o mesmo cookie
	$url_requisicao = "http://www.receita.fazenda.gov.br/aplicacoes/atcta/cpf/ConsultaPublicaExibir.asp";

	$campos = $_POST;
	$campos_concat = '';
	$cookie_file = realpath(sys_get_temp_dir()).$_SESSION['cookie_file'];
	//die($cookie_file);
	$campos_concat = 'txtCPF='.$_POST['txtCPF'].'&idLetra='.$_POST['idLetra']."&Enviar".$_POST['Enviar'];

	$ch = curl_init();
	curl_setopt($ch,CURLOPT_URL,$url_requisicao);
	curl_setopt($ch,CURLOPT_POST, count($_POST));
	curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
	curl_setopt($ch,CURLOPT_POSTFIELDS,$campos_concat);
	curl_setopt ($ch, CURLOPT_COOKIEFILE, $cookie_file); //a-ha!
        curl_setopt($ch,CURLOPT_FOLLOWLOCATION, true);  // valeu, felipe!
	$result = curl_exec($ch);
	$result = iconv("ISO-8859-1","UTF-8",$result);

	//texto para localizar o nome
	$texto_antes = 'Nome da Pessoa Física:';
	$texto_depois = '</span>';

	if (!strpos($result, $texto_antes)){
		die('erro na consulta');
	}
	else{
		$result = substr($result,  strpos($result, $texto_antes));
		$result = substr($result, strlen($texto_antes) , strpos($result, $texto_depois));
		$result = str_replace ( $texto_depois , '' , $result);
		$result = trim($result);

		//close connection
		curl_close($ch);
		echo "<pre>";
		echo $result;
		echo "</pre>";
	}

?>

espero que tenham gostado! sugestões, críticas e comentários são muito bem-vindos!

algumas outras referências consultadas:

execute post with curl
php cookies example

update: se vocês estão atrás de um proxy, em ambas as utilizações do curl, vocês devem definir, além das opções anteriores, as seguintes opções:

        curl_setopt ($ch, CURLOPT_PROXY, "http://ip_do_servidor_proxy");
        curl_setopt ($ch, CURLOPT_PROXYPORT, porta_do_servidor_proxy);

update 2: para baixar os fontes, vai aqui:
http://cacovsky.googlecode.com/files/receita.zip

update 3: o código não estava funcionando no windows, mas já foi corrigido. era um problema com o separador de diretório / no linux e \ no windows.


160 Comentários on “atualizado: php, curl, cookies, sessions, cpf e site da receita federal”

  1. Thiago Ornellas disse:

    Fala Caco, blz?
    Cuidado com o “lado negro da força”.😀
    Muito bom post. Parabéns!
    Quanto a sua dúvida:
    observe o parâmetro v (que recupera o valor de date.getTime()); eu não sei pra que ele serve. omitindo-o, não percebi diferenças, se descobrir, me avise . entretanto, eu optei por mater ele lá.
    É o seguinte: quando se a atualiza uma imagem via javascript, que é o caso, alguns navegadores ao perceberem que é a mesma (endereço e nome da image) não fazem a requisição para o servidor o captcha não é atualizado. Assim quando você coloca um valor aleatório, neste caso
    date.getTime()
    o navegador interpreta como sendo um coisa nova e faz a requisição ao servidor.
    Posso estar enganado mais no Firefox/W7 ocorre isso. Então se você colocar ali
    Math.random();
    deve funcionar da mesma forma – Não testei, mas deve.

  2. Gladson Reis disse:

    Bom dia , obrigado pela atenção, se vc tiver msn/email, ficaria mais tranquilo !
    acesse ai http://www.stonestecnologia.com.br/cpf. Ele sempre retorna erro na consulta
    ja revisei o codigo nao tem nada nele que comprometa isso.
    alguma configuração no Browse ?

    • cacovsky disse:

      acho melhor a gente discutir aqui mesmo, porque sua dúvida pode ser a dúvida de outra pessoa.

      olha, o que eu sugiro é você partir da raiz do problema. provavelmente, é um erro não diretamente associado ao código.

      esse erro acontece quando a expressão !strpos($result, $texto_antes)) é verdadeira, ou seja, quando a página requisitada não contém o texto “Nome da Pessoa Física:”. por algum motivo, a página que você tá obtendo é diferente da esperada. você pode tentar executar o seguinte:

      echo $result;

      isso em vez do if-else do final. aí você vê a página que tá sendo carregada e por que motivo é diferente do esperado.

      • Gladson Reis disse:

        Grande !! Obrigado mais uma vez.
        Infelismente o meu codigo aki nao funcionou, fiz varios teste
        debuguei e tudo mais…
        mas o retorno sempre volta nulo ou vazio.
        Voce teria este codigo ai funcionando em algum lugar pra eu testar ?

        nao sei se é o meu servidor q esta mal configurado ou sei la.
        preciso disso urgente , e seu site foi o unico que achei com uma
        forma mais descritiva do exemplo, e pra melhorar usando as URLs da receita federal !
        🙂

  3. bia disse:

    bom dia, testei o código, mas sempre retorna erro.
    Comentei o if-else no final e coloquei o echo $result; para testar, e parece a seguinte mensagem:

    Object Moved
    This object may be found here.erro na consulta

    O que está dando errado?

    • bia disse:

      Aliás… nem o captcha está mostrando.. ele grava normal na pasta tmp… se eu acessar posso ver as imagens lá… mas não mostra na index

  4. cacovsky disse:

    tô vendo que tem muita gente com problemas para executar o código. eu refiz os passos no meu computador copiando o código que está na postagem e funcionou tranquilo. no meu caso, eu estou atrás de um proxy, o que pode ser o problema de alguém também, mas já atualizei a postagem com esse detalhe.

    antes de qualquer coisa, peço a quem tiver experimentando problemas que altere a opção dsiplay_errors de Off para On no arquivo php.ini. isso é imprescindível na hora de debugar.

    pensando rapidamente no que pode acontecer no caso de vocês, imagino algumas situações:

    – a extensão curl está habilitada no php.ini?
    – o uso de sessões está habilitado no php.ini?
    – a subpasta “images” possui permissão de leitura E escrita para o servidor web (linux principalmente)?
    – vocês estão testando com cpfs sabidamente válidos?

    se vocês ainda estão enfrentando problemas, podem entrar em contato comigo pelo twitter @Cacovsky

    sempre à disposição o/

  5. Filipe disse:

    Opa, amigo também estou enfrentando o mesmo problema do pessoal.

    Object Moved
    This object may be found here.

    Alguma luz?🙂

    Quanto ao problema de não aparecer a IMG no formulário, resolvi com o comando: chmod(“$img_link”, 0666); uma vez que o script ta criando sem permissão de leitura.

    • cacovsky disse:

      o código continua executando corretamente, disso eu não tenho dúvida. eu preciso que você dê mais detalhes a respeito do erro que pode estar ocorrendo. já checou os passos anteriores?

  6. simplesmente perfeito…
    algumas alterações e tudo ok

  7. Beto disse:

    Caco, me diga uma coisa, existe a possibilidade de fazer esta pesquisa mas com cnpj?
    Ex: o mesmo que uma consulta de cep la no republicavirtual onde a pessoa informa o cep e recebe o endereço completo como retorno. Gostaria de informar um cnpj e receber todos os dados da empresa. Há como?
    valeu

  8. Jonh disse:

    Cara, o meu nem grava os arquivos na pasta, tem alguma sugestão? Obrigado desde já!

  9. Olá pessoal, pessoas tem me procurado sobre este script
    fiz algumas alterações, o site da receita depois da consulta redireciona para uma página
    você precisa fazer o CURL seguir este redirecionamento com CURLOPT_FOLLOWLOCATION

    fiz uma versão simples do meu funcionando e coloquei em um zip com toda a estrutura de pastas
    quem quiser entre em http://www.leonardofilipe.me

  10. Beto disse:

    Caco, por acaso você não chegou a ver essa questão de consulta pelo cnpj? digo sobre minhas perguntas anteriores. abs..

    • cacovsky disse:

      ainda não, cara, mas prometo que vou olhar. tô um tantinho apertado!

      • Anderson cAko disse:

        iae pessoas! Estou nessa barca de incorporar num sistema interno um recurso para facilitar a consulta por CNPJ/CPF para validar mais as informações digitadas.

        Quanto à questão do CPF já foi dito pelo Leonardo Filipe.. a RF mudou denovo o mecanismo deles. E quanto ao CNPJ… ainda está funcionando basicamente nos mesmos moldes da consulta por CPF do Filipe com umas funções encontradas no que pode ser baixado do http://www.w4ti.com.br/cnpj.zip

      • Anderson cAko disse:

        epa… a referencia foi removida do texto, porém tem dentro do .php .. =]

  11. Edriel disse:

    Leonardo Filipe, baixei seu exemplo, e testei… bom a imagem do captcha aparece e troca tb se eu quiser, porém não faz a consulta ou não retorna a consulta, tem como vc dar uma olhada no código novamente? tem como fazer alguma correção?
    obrigado

  12. cacovsky disse:

    bom, galerinha, eu dei uma atualizada e consultei aqui localmente, tudo parece ter funcionado. utilizei a sugestão do felipe e tá tudo ok🙂

  13. Newerton disse:

    Para quem está tendo dificuldade de verificação, foi feita 2 alterações nas URL de verificação do CPF, do CNPJ ainda não verifiquei.

    Antes
    posturl: http://www.receita.fazenda.gov.br/Aplicacoes/ATCTA/cpf/ConsultaPublicaExibir.asp

    Depois
    posturl: http://www.receita.fazenda.gov.br/Aplicacoes/ATCTA/cpf/ConsultaPublica.asp

    Está é uma alteração!
    A outra é o nome do caminho.

    Observa que o /cpf/ está minusculo, e foi substituido para Maiusculo /CPF/

    http://www.receita.fazenda.gov.br/Aplicacoes/ATCTA/CPF/ConsultaPublica.asp

  14. Claudio disse:

    Parece que não funciona mais. Mesmo adicionando o curl_setopt($ch,CURLOPT_FOLLOWLOCATION, true); ,quando o curl redireciona, ele recebe a página inicial do formulário, e não mais a página de consulta.

    Alguma ideia?

  15. Newerton disse:

    Hoje parou de vez! Acho que conseguiram bloquear, todos os clientes que usam este tipo de validação já estão comunicando via suporte sobre não conseguir cadastrar cliente.

    • cacovsky disse:

      Newerton, fiz uma pequena atualização pra servidores windows, mas o código está funcionando adequadamente aqui. se eles conseguirem bloquear, sempre haverá uma forma de desbloquear.

      • Newerton disse:

        Que alterações você vez? Aqui ‘n’ clientes não está conseguindo, ja coloquei várias opções de curl_setopt() e nada.

      • cacovsky disse:

        a única opção de curl_setopt() que eu adicionei foi o CURLOPT_FOLLOWLOCATION para true.

        faz um passo a passo no seu sistema aí. o código disponível no site está funcionando.

  16. Newerton disse:

    Ta conseguindo gerar os cookies e mostrar a imagem?

  17. Antitribus disse:

    O site da receita é um lixo, sai do ar direto, num dá nem para debugar diretiro, quando você adquire o raciocinío ele cai

  18. Jarbas disse:

    Consegui apartir deste tutorial!

  19. ferreira disse:

    alguem consegui fazer funcionar com WampServer pois não mostra a imagem mas ela esta sendo gravada na pasta imagens como mo modelo (CUR5F7F.tmp) alguem pode me ajudar a corriguir esse problema

  20. Antitribus disse:

    Aew para quem quiser consultar a receita do exemplo que fiz é só acessar http://barros.orgfree.com/rec/ ,lá ta o form Chupa Cabra, mas o servidor da receita é muito instável.

    • cacovsky disse:

      excelente iniciativa, barros. mas essas informações são armazenadas (logging) em algum lugar? porque algumas pessoas má-intencionadas podem se aproveitar de CPFs válidos de outrem.

      • Antitribus disse:

        Nada é guardado, o cache está desabilitado, nem as imagens são armazenadas

      • cacovsky disse:

        barros, as imagens estão sendo armazenadas sim.

      • Antitribus disse:

        Você está certo, estava guardando sim, pois na minha classe havia desabilitado o parametro de apagar as imagens para debugar.
        Agora confere lá!
        Mas não entendo a sua ênfase para isto, sendo que as imagens são capturadas antes de qualquer emissão de dado confidencial (cpf)

      • cacovsky disse:

        em relação às imagens, de fato, é um problema menor. entretanto, se esses cpfs tiverem sendo armazenados em algum lugar, é um problema relevante. note que não tem como testar sua implementação se eu inserir cpfs inválidos.

      • Alonso Jr. disse:

        “note que não tem como testar sua implementação se eu inserir cpfs inválidos.”

        Lógico, é uma rotina para verificação da situação cadastral…

      • Antitribus disse:

        Verificar se um cpf é válido ou não, qualquer javascript encontrado no google faz isto.
        A proposta é conseguir fazer consultas próprias no site da receita federal.
        Eu não perdi tempo com este detalhe que poderia ser colocado por qualquer um.

      • cacovsky disse:

        Alonso, a questão é que uma pessoa má intencionada interceptando essas informações teria acesso a cpfs válidos pertencentes a pessoas. entendeu o problema?

    • Anderson cAko disse:

      Parabéns Antitribus, agora disponibiliza os fontes ae pra galera. =)

  21. Alonso Jr. disse:

    Eu e o Antitribus trabalhamos juntos. Desenvolvemos uma classe genérica para facilitar a consulta de qualquer serviço desse tipo (cpf, cnpj, portabilidade telefônica, cep, sedex, etc) com ou sem captcha em PHP. Muito legal…

  22. Antitribus disse:

    Bem, por enquanto estou finalizando algumas configurações no script.
    Estou melhorando ele para a utilização com AJAX veja em http://www.cgmautomacao.com.br/receita/
    Assim que terminar estaremos liberando para a comunidade PHP.
    Abcs!

  23. Sineir Marcos disse:

    Srs… ainda tem que acertar alguma coisa, pois o script no firefox funciona intermintente (pode ser SESSION)…..
    no IE nao funciona…
    http://www.sineir.com.br/xxml/cnpj2.php => rodando
    http://www.sineir.com.br/xxml/cnpj2.php.txt =>script

  24. marcos disse:

    cara tava precisando disto mais para outro site da receita, ele nao efetua é a consulta de NFE

    segue meu exemplo no endereco http://www.tomazini.org/nfe.rar

  25. leo disse:

    como faço um formulario validando o cef verdadeiro e cep

  26. Sineir disse:

    ia dar uma olhada… mas o arquivo nao tá mais la !

  27. Paulo Ogliano disse:

    Pessoal,

    achei este artigo muito útil. Porém, testei e funcionou com os navegadores Google Chrome, Safari e Internet Explorer. Infelizmente não funcionou no Firefox.

    O que ocorre, é que a imagem não aparece. Retornei as variáveis na página para ver o que acontece, e aparece sempre o caminho do servidor, seguido do nome temporário da imagem com uma barra invertida, desta forma:

    http://localhost/receita/images\CBFr.tmp

    Alguém sabe como solucionar isto?

    Obrigado.

  28. Paulo Ogliano disse:

    Olá pessoal.

    Nos navegadores Chrome, Safari e IE aparece normal o captcha. Porém, no Firefox não.

    Estou operando em localhost com o Vertrigo e usando Windows 7. Alguém teve esse mesmo problema?

    Paulo.

  29. Paulo disse:

    Não funcionou. Tirando o Firefox, os outros navegadores executaram muito bem a ação. No firefox, não aparece a imagem. Já revirei este blog para tentar corrigir o problema e não obtive sucesso. Dei um echo no $img_link pra ver o que retorna, e aparece isso:

    http://localhost/receita/images/\CUR3E00.tmp

    Essa maldita barra invertida antes do nome do arquivo é que impede que ele seja exibido no firefox. Não sei como funcionou aí com vocês no firefox, mas aqui, nada feito. =/

    Vocês chegaram testar no firefox? Deu certo? Houve alguma alteração? Por favor, se tiverem alguma dica, me ajudaria bastante… =)

    Obrigado.

    • cacovsky disse:

      Paulo, você pode configurar no seu código pra que o separador de diretório seja “/”, e não “\”. isso está numa variável, veja o código pra maiores detalhes. se ainda assim nao funcionar, é só falar.

  30. Paulo disse:

    Caco,

    É a variável $dir_sep no formulario.php, Certo? Lá tem isto aqui:

    $dir_sep = ‘/’;

    e isto:

    if (DIRECTORY_SEPARATOR == ‘\\’) $dir_sep = ‘\\’;

    Já inverti de tudo que é jeito, e nada, rsss. Eu até substitui a própria variável pela barra em si. Fiz a alteração nesta string:

    $img_link = $my_site.”images”.substr( $img_file_name, strrpos ($img_file_name , $dir_sep));

    E mudei pra isso:

    $img_link = $my_site.”images”.substr( $img_file_name, strrpos ($img_file_name , ‘/’));

    E, não funcionou. Até coloquei isso num servidor online pra ver se era algum problema pelo fato de rodar offline (localhost), mas deu na mesma no Firefox. Estou quase desistindo aqui haueheuhe não achei nada no Google. Acho que isso aí não funciona no Firefox não.. Tem alguma outra dica que possa resolver isso?

    Fico no aguardo.

    Obrigado!

    • cacovsky disse:

      você já tentou comentar essa parte?
      if (DIRECTORY_SEPARATOR == ‘\\’) $dir_sep = ‘\\’;

      • Paulo disse:

        Olá Caco,

        Já sim, e não deu certo.

        Vou deixar quieto. Se o usuário acessar o site com o Firefox, dá erro. Melhor deixar o campo aberto pra pessoa informar o CPF e o Nome manualmente mesmo.

        Obrigado pela ajuda.

        Abraço,
        Paulo.

      • Antitribus disse:

        Este trecho de código é um dos erros que podem ser evitados como:

        define(“DS” , DIRECTORY_SEPARATOR);

        // cria nome do cookie na pasta cookies
        $tempNamCookie = tempnam (dirname(__FILE__) . DS . “cookies” , “CURLCOOKIE”);

        Cacão, como faço pra lhe enviar um .rar com estes códigos melhorados, para que você disponibilize aqui, que atualmente é a maior fonte de procura para este assunto?

        Abcs!

  31. Antitribus disse:

    Este trecho de código é um dos erros que podem ser evitados como:

    define(“DS” , DIRECTORY_SEPARATOR);

    // cria nome do cookie na pasta cookies
    $tempNamCookie = tempnam (dirname(__FILE__) . DS . “cookies” , “CURLCOOKIE”);

    Cacão, como faço pra lhe enviar um .rar com estes códigos melhorados, para que você disponibilize aqui, que atualmente é a maior fonte de procura para este assunto?

    Abcs!

  32. junior disse:

    Warning: curl_setopt() [function.curl-setopt]: CURLOPT_FOLLOWLOCATION cannot be activated when in safe_mode or an open_basedir is set in
    Gostaria de dar um fim neste error que o servidor não me deixa trazer a consulta.
    obs. não posso mexer no open_basedir, sou apenas um misero estagiario.

  33. Antitribus disse:

    Passei um código corrigido funcionando para, que o Cacovsky liberasse para o pessoal, mas ele não o fez!.
    Por que será???

    • Cacovsky disse:

      tenha certeza, antitribus, não é má vontade. apenas estou muito ocupado.

      • Antitribus disse:

        Mas para responder você não está. e não durou nem 20 minutos, assim como nós sabemos que para alterar um zip não é tão demorado assim.
        Pessoas ainda acessam o script que está na minha hospedagem.
        É por isso que estou me disponibilizando a passar mesmo por email este código

      • Cacovsky disse:

        mas eu ainda não olhei seu código e não vou me comprometer com código dos outros quando eu ainda não analisei. além disso, particularmente, tenho outras prioridades. eu faço de boa vontade, mas faço quando eu quiser.

      • Antitribus disse:

        Acredite, este seu atualmente não está funcionando!

  34. Antitribus disse:

    Quem estiver com dúvidas, ou necessitar do código, mande email para antitribus@gmail.com, pois pelo visto por aqui não vai arrumar nada.
    Coloque assunto: PHP CPF.

    Editado pelo moderador: a discussão aqui daqui pra baixo é pouco relevante para resolução de potenciais problemas. se o código ainda estiver apresentando problemas, deixe um comentário ou utilize a sugestão do colega antitribus.

    • Cacovsky disse:

      eu me sinto triste quando vejo uma retribuição dessa forma.

      • Antitribus disse:

        Significado da palavra Retribuição:
        * Agradecimento, reconhecimento por um favor ou serviço recebido.
        Na realidade eu não recebi nada de você, você é que recebeu de mim, quem deveria ficar
        decepcionado aqui sou eu.
        A comunidade necessita do código, e o tempo que você perdeu comigo aqui respondendo estas questões
        , já tería disponibilizado o zip.

      • cacovsky disse:

        você recebeu sim. você quem pegou o código que eu fiz. se com alguma correção fez ele funcionar, suponho que tenha sido melhor que fazer o do zero. além disso, e principalmente, nas pesquisas que eu fiz a respeito, nenhuma utilizou essa abordagem que eu propus. eu tive a intenção maior de mostar que _é possível_ em qualquer linguagem ou ambiente com suporte a cookies e que é fácil implementar. basta ver o comentário do silvioprog, que implementou para lazarus. então, acho que merecia uma retribuição melhor sim.

        de qualquer forma, creio que agora resolvi o problema. seu código continha erros, achei melhor corrigir o meu mesmo.

      • Antitribus disse:

        Você fantasia muito!

        Eu usei o seu código para devolver ele corrigido, pois não sou louco de distribuir as minhas classes de consulta CPF, CNPJ e CEP, ainda mais para quem não confio.
        A minha classe foi feita em cima de um desenvolvimento OO criada pelo Alonso no Delphi, muito acima do seu código, cujas características não tem nada em comum.

        Depois de eu postar aqui que estaria resolvendo os problemas das pessoas por e-mail, o Paulo que estava com problema daquela lógica louca do seu código de verificação de diretório, me mandou um e-mail, e já está com o código corrigido.

        Pergunta para ele o que ele acha do código, se está certo ou errado!

      • Cacovsky disse:

        “Eu usei o seu código para devolver ele corrigido”
        não o fez.

        “pois não sou louco de distribuir as minhas classes de consulta CPF, CNPJ e CEP”
        aí é que tá… uma coisa é mostrar seu código de produção. uma outra coisa completamente diferente é mostrar como determinadas coisas podem ser feitas. este é o meu objetivo.

        ” cujas características não tem nada em comum.”
        estavam bem parecidos.

        “Pergunta para ele o que ele acha do código, se está certo ou errado!”
        o código está errado.

        “daquela lógica louca do seu código de verificação de diretório”
        um programador minimamente competente teria identificado facilmente o erro. era apenas o separador de diretório. tão somente isso.

      • Antitribus disse:

        Cara, você tá me curtindo!
        O código de Delphi do Alonso, foi o que eu usei para implementar a minha classe em PHP para as consultas de CPF, CNPJ e CEP, e que essas classes não tem nada em comum com o seu código.
        É óbvio que o código que lhe devolvi parece com o seu, pois ele É SEU, só que simplesmente corrigido e melhorado. Como eu disse não iria liberar minhas classes para você.
        Você disse que um programador minimamente competente tería identificado o erro do separador de diretórios. Eu digo que um programador minimamente básico não escrevería tal erro.
        Já que você é competente, porque postou com aquele erro?

      • Cacovsky disse:

        eu tinha considerado que, por sua classe, estava falando daquele código que você tinha me mandado por email. aquele código não funcionou.

        você quer que eu diga que meu código tá errado, ele tá errado. você quer que eu te agradeça, eu te agradeço.

        o código foi postado com “erro” porque eu não uso windows e não tenho acesso fácil a nenhuma instalação windows. então, havia me esquecido do problema com relação ao separador de diretórios. apesar de que, em um dos updates, eu deixei claro

        “update 3: o código não estava funcionando no windows, mas já foi corrigido. era um problema com o separador de diretório / no linux e \ no windows.”

        entretanto, o código continuou com erro.

        “Já que você é competente, porque postou com aquele erro?”
        porque sou incompetente.

        quem ler isso aqui procurando por outros problemas que possam acontecer vai dar de cara com uma discussão desnecessária e improdutiva.

      • Antitribus disse:

        1º O código que lhe devolvi tá longe de ser uma classe, se você notar não tem no mínimo uma declaração “class”.

        2º Não quero que você diga que seu código está errado, os fatos já dizem isto, e também muito menos quero que você agradeça.

        3º Problemas de diretório não foi corrigido, pois o Paulo estava com problemas de imagem com barra e na visualização da imagem em diferentes navegadores

        4º Se você se diz incompetente, não julgue a competêcia dos outros em “Um programador minimamente competente…”, respeite mais as pessoas

        5º Concordo plenamente contigo sobre a discussão desnecessária, só acho que você está retendo o código e impossibilitando as pessoas que entram aqui de trabalhar num código corrigido.

      • Cacovsky disse:

        concordo com os pontos 1, 2 e 3. tenho comentários sobre os pontos 4 e 5.
        “respeite mais as pessoas”
        “você está retendo o código e impossibilitando as pessoas que entram aqui de trabalhar num código corrigido.”
        minha intenção não foi desrespeitar nem impossibilitar outras pessoas de nada. contudo, não vou nem devo tecer maiores explicações. este será o último comentário desta subthread.

  35. betolimma disse:

    Pessoal bom dia e não quero me meter nesta discussão entre vocês, só acho que deu o que tinha que dar, bola pra frente e humildade sempre. Somo todos aprendizes nesta vida…
    Bom eu realmente gostaria de testar o código e quem puder me passar agradeço.
    betolima@gmail.com

    • Cacovsky disse:

      beto, o código deve estar funcionando agora. qualquer problema encontrado, por favor, relate.

      • Paulo disse:

        Olá pessoal!

        Ufa, essa conversa aí me tirou o fôlego.. hehehehe Galera, meu código que consegui com o Antitribus está funcionando!

        Se não fosse o André (cacovsky) ter essa ‘matéria’ aqui, com certeza não acharia pelo Google, então, agradeço à ele pela iniciativa da idéia, e entendo [e estava ciente] que havia uma observação quanto ao funcionando do código no Windows por causa do separador de diretório.

        Não vou dizer que sou expert em PHP, mas de várias formas até onde meu conhecimento me permite, tentei resolver o problema de diretório, sem sucesso.

        Com a ajuda do Antitribus, o problema foi resolvido e o código está bem fácil, onde podemos entender muito bem e de forma clara o funcionando do mesmo.

        Quero manifestar meus agradecimentos à todos, e dizer à vocês [dois principalmente] que estamos aqui para aprender cada vez mais, como disse o Beto. Com certeza o Antitribus queria ajudar realizando uma melhoria do código afim de eliminar o erro de diretório, e passou o código para o André (segundo entendi lendo msgs anteriores). Não conheço vocês, e não faço idéia onde moram e o que fazem da vida, portanto, pode ser que estejam no mesmo barco que eu, muitas coisa para fazer e o tempo está cada vez menor.. mas de qualquer forma, a iniciativa de ambos ajudou à todos.

        Certo de que essa discussão desnecessária terminou, digo que “uma mão lava a outra”. Se ninguém precisasse de ninguém, qual o sentido de nossas obrigações, compromissos, do mundo, da vida?

        Backspace nisso aí ok?!

        Abraço,
        Paulo.

  36. ferreira disse:

    estou com prolemas nao aparece a imagem
    uso o wampserver no windows 7
    a imagem é capturada mas acho que o erro esta na barra invertida /images\CUR1D40.tmp

    Not Found

    The requested URL /receita/images\CUR1D40.tmp was not found on this server.

    • ferreira disse:

      percebi que so acontece esse problema no firefox
      o is funciona perfeito
      alguem pode me ajudar com firefox

  37. betolimma disse:

    consegui.
    O problema era o seguinte:
    no meu apache não estava habilitado o curl, então procedi assim:
    aptitude install php5-curl
    depois restartei meu apache
    por fim dei chmod 777 na pasta images e cookies.

  38. Jeferson Costa disse:

    Bom, no meu caso não deu certo.

    Warning: curl_setopt() [function.curl-setopt]: CURLOPT_FOLLOWLOCATION cannot be activated when safe_mode is enabled or an open_basedir is set in /home/g2marketing/consultar.php on line 19
    erro na consulta

    Falei com o pessoal da kingHost, mas ees também não souberam ajudar.

    • cacovsky disse:

      isso tem toda a cara de problema de configuração no php.ini, mas não tenho certeza. analise o resultado de phpinfo() aí e veja como estão as configurações.

  39. sagamg disse:

    Otimo artigo ^^ . de muita utilida realmente muito bom

    tive um problema com a URL com as Barras pra Windows, fiz assim e funciona perfeito em todos navegadores.

    $new_url = str_replace(‘\\’,’/’,$img_link); // so pra windows

    • cacovsky disse:

      excelente, sagamg. eu atualizei o script pra ter essa modificação também, você pode verificar se está funcionando no windows sem modificações?

      valeu!

  40. will disse:

    Excelente artigo, gostei muito .
    Estou tentando adaptar seu script para fazer consulta no Detran , eles usam algo bem parecido com o da Receita Federal, porém as imagens são .bmp e não .gif o que dá um erro na execução: “imagecreatefromstring(): Data is not in a recognized format”
    Eu troquei a função imagegif por imagewbmp , mas o erro continua.
    Alguém poderia dar um help!!

    Abraços a todos

  41. olá… efetuei um teste e também sempre está retornando erro na consulta… só aparece esta mensagem na tela.. sem nenhum erro

  42. Jeferson disse:

    Alguém aí conseguiu fazer funcionar em alguma revenda como Locaweb/KingHost?

  43. Ajuda disse:

    Ola estou tentado usar alguns do exemplos acima mas não funciona. alguem pode me ajudar?

  44. Ola os exemplos acima não funciona alguem pode me ajudar?

  45. Antitribus disse:

    ai ai ai…

    • Ademir Tasca disse:

      Parcero, vc pode me disponibilizar os fontes???

    • Ademir Tasca disse:

      Esta perfeito, porém só func com CPF, estou tentando implementar pra cnpj e não estou tendo resultado, como dei uma olhadinha no fonte do seu ex. e pensei que vc já tem a solução…

    • Leandro disse:

      Não, o dizponibilizado aqui, não está aparecendo a imagem do captcha..poderia disponibilizar o fonte?

  46. MthLima disse:

    Alguem pode me ajudar com o CNPJ?
    Testei o exemplo do amigo Sineir, funciona 100%, gostaria de saber saber como implementar algo parecido.
    http://www.sineir.com.br/cnpj/cnpj2.php

    • Sineir disse:

      MthLima,
      Não está 100% , pelo menos aqui funciona uma vez sim outra não… talvez se usarmos a navegacao anonima até funcione… pois pode ter problemas de session ou cookies…

      sua pergunta está muito vaga, pois “aonde” vc quer implementar algo parecido, visto que os codigos aqui expostos estão em PHP+CURL e podem ser utilizados em um Host Linux ou ate mesmo no windows (xampp,wamp,easyphp)..

  47. MthLima disse:

    Hei Seneir, todas as vezes que eu testei deu certo me retornou os dados🙂
    Então a implementação seria em um cadastro de fornecedores onde a pessoa entre com o CNPJ dai eu recuperaria os dados e já alimentaria os devidos campos.
    A ideia é essa eu utilizo Flex e PHP.
    Meu Host é Linux, sua ideia de usar um proxy anonimo pode ser que dê certo.

    • Sineir disse:

      Não sou programador, sou remendador….
      antigamente eu fazia isso usando um iframe escondido, postava a pesquisa nele..e nele enderecava dados para os campos para o doc pai.
      Atualmente eu uso o ajax: e o mais indicado é retornar os dados em nodes de xml bem definidos… aí voce poderá encher os campos.
      Não tenho muito tempo.. mas se precisar de ajuda (se bem que não sou programador) dou uma mao para comecar…

      • mthlima disse:

        Isso ai brother, a ideia é montar um XML e recuperar os valores nos devidos campos.
        Estou analisando o exemplo do CPF para ver como funciona e então começar a escrever os códigos.
        Vou dar uma pesquisada a fundo neste assunto pois vou precisar muito disso.
        Obrigado

      • Alonso Jr. disse:

        A RF alterou as rotinas da consulta, seu exemplo não funciona mais. Valeu!

      • Sineir disse:

        Votamos ao comeco !!!!!!!

  48. MartinhoCampos disse:

    Galera, localmente funciona (Xampps); remota não, O capcha não aparece…😦
    Tem algum atributo necessário à pasta images?

    • MartinhoCampos disse:

      Apenas para constar, o host é em Linux, e suporte Curl ativo, (libcurl/7.21.0 OpenSSL/0.9.7a zlib/1.2.1.2 libidn/0.5.6 )

  49. Jhonatan souza disse:

    Ola galera eu imprimi as variaveis e vi o seguinte caso

    echo $img_file_name
    imprimiu:
    img_file_name = C:\wamp\www\tcc\images\CUR3326.tmp

    ——————————————————————————
    echo $img_link = $my_site.”images/”.substr( $img_file_name, strrpos ($img_file_name , ‘/’));
    imprimiu:
    img_link = http://localhost/tcc/images/C:\wamp\www\tcc\images\CUR1270.tmp

    —————————————————————————–
    esta dando erro na hora de busca a imagem
    substitua a variavel img_link por esse:

    $img_link = “images/”.substr($img_file_name,strlen($img_file_name) – 11);

    Explicando:

    “images” // eh o diretorio das imagens onde estao armazenadas
    substr($img_file_name,strlen($img_file_name) – 11); // pegara o nome da imagem, apartir do CUR1270.tmp

    Se tiverem alguma duvida eh so postar

  50. G9R3 disse:

    Correções:

    consultar.php:

    $cookie_file = $_SESSION[‘cookie_file’];

    Sugestão:

    substituir isso:

    curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
    $output = curl_exec ($ch); // the real thing
    $img_file_name = tempnam (“images/”, “CURLGIF_”);
    $img_data = imagecreatefromstring($output);
    imagegif($img_data, $img_file_name);
    $img_link = $my_site.”images/”.substr( $img_file_name, strrpos ($img_file_name , ‘/’));

    por isso:

    curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt ($ch, CURLOPT_HEADER, false);
    $output = curl_exec($ch);
    $img_data = base64_encode($output);
    $img_link = (‘data:image/gif;base64,’.$img_data);

    A cada acesso acumularia imagens no disco e isso não é uma boa prática.

  51. Agostinho disse:

    alguem teria o do CNPJ para disponibilizar por favor, poderia enviar para agostinhofb@hotmail.com

  52. A receita Federal mudou o captcha recentemente e este código não está mais servindo. Algém tem alguma outra solução?

  53. Marcelo disse:

    Receita Federal mudou forma de consulta…

  54. Marcelo disse:

    Mudaram o modo de consulta na Receita Federal

  55. Carlos disse:

    Amigão, primeiramente, parabéns pela iniciativa… parece que os códigos pararam de funcionar, tanto o de CPF quanto o de CNPJ… será que vocês poderiam conferir? Ví todos os comentários e os links de quem deixou disponível on-line os aplicativos… se algúem tiver o cógigo corrigido, gostaria muito que me enviassem… carlosedgi@hotmail.com obrigado!

  56. Carlos disse:

    Parece que a receita mudou o acesso novamente…

  57. Olá pessoas, tudo bem com vcs, alguém conseguiu fazer a consulta de CNPJ funcionar ? tive olhando por vários tópicos, com varias fontes, porém ainda não encontrei um funcionando, e tbm não conseguir fazer um funcionar.

    Segue alguns desses topicos

    http://www.bindideias.com.br/2012/08/17/atualizado-consultando-cnpj-na-receita-federal-via-php/

    http://mayk.brito.net.br/artigos/php-curl-e-captcha-como-eu-entendi-e-aprendi-trabalhar-com-isso

  58. silvioprog disse:

    Amigos,

    Estou bolando uma ideia em montar uma API online em RESTful/JSON para consulta de alguns tipos de documentos, dentre eles CPF e CNPJ (consulta direto no site da Receita Federal. Consultei com eles, não é ilegal).

    A API seria escrita sob o framework Brook:

    http://brookframework.org

    O preço seria super acessível. Se alguém tiver interesse eu posso agilizar na construção da API.

    Grande abraço,

    Silvio Clécio.

  59. sineir disse:

    achei um tópico com data recente….
    mas não consegui montar o quebra cabeça…
    http://tretasdanet.com/get/284c9ad300-coletando-informacoes-do-cnpj-direto-da-receita-federal-em-php

  60. sineir disse:

    Senhores… A Paz de Cristo… apresento-lhes meus testes: http://www.sineir.com.br/cnpj
    não sou programador.


Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s