ActiveDelphi - Índice do Fórum ActiveDelphi
.: O site do programador Delphi! :.
 
 FAQFAQ   PesquisarPesquisar   MembrosMembros   GruposGrupos   RegistrarRegistrar 
 PerfilPerfil   Entrar e ver Mensagens ParticularesEntrar e ver Mensagens Particulares   EntrarEntrar 

IdHTTP e consulta web de NFe [Resolvido]
Ir à página 1, 2, 3  Próximo
 
Novo Tópico   Responder Mensagem    ActiveDelphi - Índice do Fórum -> Delphi
Exibir mensagem anterior :: Exibir próxima mensagem  
Autor Mensagem
tiago.prs
Aprendiz
Aprendiz


Registrado: Sábado, 9 de Mai de 2009
Mensagens: 193

MensagemEnviada: Seg Ago 12, 2013 11:32 am    Assunto: IdHTTP e consulta web de NFe [Resolvido] Responder com Citação

Caros, saudações!

Venho novamente até você para pedir ajuda. Ficaria grato se puderem me ajudar.
Estou precisando melhorar o desempenho da minha consulta on-line de NFe que atualmente uso TWebBrowser, onde carrego os dados filtrando o html e mostrando em um form.

A rotina realiza o processo já bem conhecido, que é de obter o captcha e colocá-lo em um TImage para o usuário digitar a chave e o texto do captcha para então realizar a consulta.

Estou tentando agora mudar para o componente indy TIdHTTP, mas estou tendo dificuldades em realizar o processo.
Segue o que estou fazendo:
Código:
unit Forms.MainForm;

interface

uses
  Winapi.Windows, Winapi.Messages,
  System.SysUtils, System.Variants, System.Classes,
  Vcl.Forms, Vcl.Graphics, Vcl.Dialogs, Vcl.Controls, Vcl.ExtCtrls,
  Vcl.StdCtrls,
  IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdHTTP,
  IdIOHandler, IdIOHandlerSocket, IdIOHandlerStack, IdSSL, IdSSLOpenSSL,
  IdCookieManager, IdCookie, IdURI,
  GIFImg;

type
  TMainForm = class(TForm)
    mem: TMemo;
    IdHttp: TIdHTTP;
    IdSSLHandlerSocket: TIdSSLIOHandlerSocketOpenSSL;
    IdCookieManager: TIdCookieManager;
    panBottom: TPanel;
    btnGo: TButton;
    imgCaptcha: TImage;
    edtCode: TEdit;
    edtChave: TEdit;
    procedure btnGoClick(Sender: TObject);
    procedure FormShow(Sender: TObject);
  private
    Cookies: TIdCookieList;
    procedure p_Execute;
  end;

var
  MainForm: TMainForm;

const
  URL = 'http://www.nfe.fazenda.gov.br/portal/consulta.aspx?tipoConsulta=completa&tipoConteudo=XbSeqxE8pl8=';
  URLIMG = 'http://www.nfe.fazenda.gov.br/scripts/srf/intercepta/captcha.aspx?opt=image';

implementation

{$R *.dfm}

procedure TMainForm.btnGoClick(Sender: TObject);
begin
  p_Execute;
end;

procedure TMainForm.FormShow(Sender: TObject);
var
  response: TMemoryStream;
  gif: TGIFImage;
begin
  response := TMemoryStream.Create;
  gif := TGIFImage.Create;
  try
    IdHttp.Get(URL);
    IdHttp.Get(URLIMG, response);
    response.Position := 0;
    gif.LoadFromStream(response);
    imgCaptcha.Picture.Assign(gif);
    Cookies := IdCookieManager.CookieCollection.LockCookieList(caRead);
    try
    finally
      IdCookieManager.CookieCollection.UnlockCookieList(caRead);
    end;
  finally
    gif.Free;
    response.Free;
  end;
end;

procedure TMainForm.p_Execute;
var
  params: TStringList;
  response: TMemoryStream;
  Uri: TIdURI;
  nI: Integer;
begin
  params := TStringList.Create;
  response := TMemoryStream.Create;
  try
    Uri := TIdURI.Create(URL);
    try
      for nI := 0 to Cookies.Count-1 do
        IdCookieManager.AddServerCookie(Cookies[nI].ClientCookie, Uri);

      //params.Add('__EVENTTARGET=ctl00%24ContentPlaceHolder1%24btnConsultar=Continuar');
      //params.Add('__EVENTTARGET=');
      //params.Add('__EVENTARGUMENT=');
      params.Add('ctl00%24ContentPlaceHolder1%24txtChaveAcessoCompleta=' + txtChave.Text);
      params.Add('ctl00%24ContentPlaceHolder1%24txtCaptcha=' + edtCode.Text);

      params.Add('ctl00$ContentPlaceHolder1$txtChaveAcessoCompleta=' + txtChave.Text);
      params.Add('ctl00$ContentPlaceHolder1$txtCaptcha=' + edtCode.Text);

      params.Add('ContentPlaceHolder1_txtChaveAcessoCompleta=' + txtChave.Text);
      params.Add('ContentPlaceHolder1_txtCaptcha=' + edtCode.Text);

      params.Add('ctl00%24ContentPlaceHolder1%24btnConsultar=Continuar');
      params.Add('ctl00$ContentPlaceHolder1$btnConsultar=Continuar');
      params.Add('ContentPlaceHolder1_btnConsultar=Continuar');

      params.Add('hiddenInputToUpdateATBuffer_CommonToolkitScripts=1');

      IdHttp.Post(URL, params, response);
      response.Position := 0;
      mem.Clear;
      mem.Lines.LoadFromStream(response);
    finally
      Uri.Free;
    end;
  finally
    params.Free;
    response.Free;
  end;
end;

end.


Os cookies ASP.NET_SessionId e cookieCaptcha são capturados e adicionados no componente IdCookieManager.

Não há exceção ocorrendo, mas o retorno do post não é o html da nota, e sim o da página inicial ainda.

Alguém saberia/poderia/gostaria de me ajudar com isso?

Desde já, agradeço a atenção e paciência de vocês!
Grato!


Editado pela última vez por tiago.prs em Qua Ago 14, 2013 2:15 pm, num total de 1 vez
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
tiago.prs
Aprendiz
Aprendiz


Registrado: Sábado, 9 de Mai de 2009
Mensagens: 193

MensagemEnviada: Qua Ago 14, 2013 2:13 pm    Assunto: Responder com Citação

com uma ajudinha do Remy Lebeau, na stackoverflow.com, aprendi umas dicas e realizei o processo que queria.

http://stackoverflow.com/questions/18216503/idhttp-idcookiemanager-asp-net-webform-page-close

Ai está o exemplo se mais alguém se interessar.

Abraços!

Código:

unit Forms.MainForm;

interface

uses
  Winapi.Windows, Winapi.Messages,
  System.SysUtils, System.Variants, System.Classes,
  Vcl.Forms, Vcl.Graphics, Vcl.Dialogs, Vcl.Controls, Vcl.ExtCtrls,
  Vcl.StdCtrls,
  IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdHTTP,
  IdIOHandler, IdIOHandlerSocket, IdIOHandlerStack, IdSSL, IdSSLOpenSSL,
  IdCookieManager, IdCookie, IdURI,
  GIFImg;

type
  TMainForm = class(TForm)
    mem: TMemo;
    IdHttp: TIdHTTP;
    IdSSLHandlerSocket: TIdSSLIOHandlerSocketOpenSSL;
    panBottom: TPanel;
    btnGo: TButton;
    imgCaptcha: TImage;
    edtKey: TEdit;
    edtCode: TEdit;
    lblInit: TLabel;
    procedure FormShow(Sender: TObject);
    procedure lblInitClick(Sender: TObject);
    procedure btnGoClick(Sender: TObject);
  private
    viewState, eventValidate: string;
    procedure GetHiddenFieldValues(html: string);
    procedure p_Execute;
  end;

var
  MainForm: TMainForm;

const
  HOST         = 'http://www.nfe.fazenda.gov.br';
  URLIMG       = HOST + '/scripts/srf/intercepta/captcha.aspx?opt=image';
  URLGET       = HOST + '/portal/consulta.aspx?tipoConsulta=completa&tipoConteudo=XbSeqxE8pl8=';
  URLPOST      = HOST + '/portal/consulta.aspx?tipoConsulta=completa&tipoConteudo=XbSeqxE8pl8%3d';
  URLGETRESULT = HOST + '/portal/consultaCompleta.aspx?tipoConteudo=XbSeqxE8pl8=';
  CONTENT_TYPE = 'application/x-www-form-urlencoded';

implementation

{$R *.dfm}

procedure TMainForm.FormShow(Sender: TObject);
begin
  lblInitClick(Sender);
end;

procedure TMainForm.lblInitClick(Sender: TObject);
var
  response: TMemoryStream;
  gif: TGIFImage;
  html: string;
begin
  html := IdHttp.Get(URLGET);
  mem.Text := html;
  GetHiddenFieldValues(html);

  response := TMemoryStream.Create;
  gif := TGIFImage.Create;
  try
    IdHttp.Get(URLIMG, response);
    response.Position := 0;
    gif.LoadFromStream(response);
    imgCaptcha.Picture.Assign(gif);
  finally
    gif.Free;
    response.Free;
  end;
end;

procedure TMainForm.btnGoClick(Sender: TObject);
begin
  p_Execute;
end;

procedure TMainForm.GetHiddenFieldValues(html: string);
var
  nIni, nLen: integer;
  cVal: string;
begin
  ...
end;

procedure TMainForm.p_Execute;
var
  params: TStringList;
begin
  params := TStringList.Create;
  try
    params.Add('__VIEWSTATE=' + viewState);
    params.Add('__EVENTVALIDATION=' + eventValidate);

    params.Add('__EVENTTARGET=');
    params.Add('__EVENTARGUMENT=');

    params.Add('ctl00$txtPalavraChave=');

    params.Add('ctl00$ContentPlaceHolder1$txtChaveAcessoCompleta=' + Trim(edtKey.Text));

    params.Add('ctl00$ContentPlaceHolder1$txtCaptcha=' + Trim(edtCode.Text));

    params.Add('ctl00$ContentPlaceHolder1$btnConsultar=Continuar');
    params.Add('hiddenInputToUpdateATBuffer_CommonToolkitScripts=1');

    mem.Text := IdHttp.Post(URLPOST, params);

    mem.Text := IdHttp.Get(URLGETRESULT);
  finally
    params.Free;
  end;
end;

end.
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
scbrianti
Novato
Novato


Registrado: Domingo, 3 de Agosto de 2014
Mensagens: 1

MensagemEnviada: Dom Ago 03, 2014 11:20 am    Assunto: Baixar pagina Nfe Responder com Citação

Bom dia Amigo

Estou tentando fazer executar seu código em e sempre dá Sessão expirou!!

Já tentei de tudo.

Onde está o pulo do gato ai?

Sidnei
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
tiago.prs
Aprendiz
Aprendiz


Registrado: Sábado, 9 de Mai de 2009
Mensagens: 193

MensagemEnviada: Dom Ago 03, 2014 12:30 pm    Assunto: Responder com Citação

Eu nem tenho mais esses fontes. Embarassed
Não me lembro de nenhum segredo.

Tentei até reproduzir aqui, mas estou tendo logo erro de conexão socket. Laughing

Bom, está usando o IdCookieManager?
Apontou o IdCookieManager no IdHTTP?
E o IdSSLIOHandlerSocketOpenSSL (se não me engano tem umas dll´s necessárias para se trabalhar com ele), está usando?
Ligou ele no IdHTTP também?
E quanto aos valores dos elementos ASP.NET, verificou se estão sendo carregados corretamente?

Em que momento está tendo a falha na sessão?

[]´s
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
johnny-walker
Moderador
Moderador


Registrado: Sábado, 4 de Outubro de 2003
Mensagens: 10653
Localização: Contagem/MG - BRAZIL

MensagemEnviada: Seg Ago 04, 2014 8:46 pm    Assunto: Responder com Citação

Isto pode acontecer com a nova indie, este código não é compatível com a indy atual, neste caso tem-se de utilizar stringstream em vez de stringlist.


bye
_________________
P.O.W.E.R B.Y D.E.L.P.H.I
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular MSN Messenger
tiago.prs
Aprendiz
Aprendiz


Registrado: Sábado, 9 de Mai de 2009
Mensagens: 193

MensagemEnviada: Seg Ago 04, 2014 11:53 pm    Assunto: Responder com Citação

Oi johnny,

Mas até que eu fiz isso no XE3.
A não ser que o amigo Sidnei esteja fazendo no XE6, por exemplo, e ja tenha diferenças no pacote Indy.

Eu cheguei a testar o exemplo mas já tive logo de cara um erro host inválido (não lembro a mensagen de erro corretmente, depois posto). Não me lembro o que pode ser, apesar de estsr com cara de ser algo bem básico.

O tempo ta curto e por isso não tentei novamente.
Quem sabe logo eu posto um exemplo funcionando e com o código mais completo.

[]´s
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
johnny-walker
Moderador
Moderador


Registrado: Sábado, 4 de Outubro de 2003
Mensagens: 10653
Localização: Contagem/MG - BRAZIL

MensagemEnviada: Ter Ago 05, 2014 11:54 am    Assunto: Responder com Citação

Cara conversei com o Remi algumas vezes, muito bom o cara, aliás foi ele e uma outra pessoa que é responsável pela indy, também respondem em fóruns.
Para quem se interessa em fazer este tipo de programa eu recomendo o fiddler, pois com ele se torna bem mais fácil saber o que está acontecendo por detrás das páginas.

tiago.pr também fiz desta forma uma vez no delphi 7, mas estava me dando dores de cabeça, acho que o tipo tstringlist é diferente nestas versões mais novas do delphi.

Na antiga indy tinha muitos problemas com cookies, pois utilizada o gerenciado do antigo netscape, mas com o novo gerenciador de cookies a indy melhorou muito e você não tem bem dizer reconstruir os cookies na mão.
Nesta parte a indy é que você vê a diferença, pois na antiga tinha que fazer verdadeiros malabarismos pra fazer funcionar os cookies.



bye
bye
_________________
P.O.W.E.R B.Y D.E.L.P.H.I
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular MSN Messenger
claudio.ferreira
Profissional
Profissional


Registrado: Quarta-Feira, 18 de Setembro de 2013
Mensagens: 667

MensagemEnviada: Ter Ago 05, 2014 5:54 pm    Assunto: Responder com Citação

O Remi Labeau sabe muito Cool
_________________
Sistema SNGPC para farmácias
http://www.cmasistemas.com.br
Rastreabilidade de Medicamentos
https://www.sncm.com.br
Soluções em Delphi
https://delphisolutions.wordpress.com/
.
"E não sabendo que era impossível, foi lá e fez"
Mark Twain
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Visitar a homepage do Usuário
tiago.prs
Aprendiz
Aprendiz


Registrado: Sábado, 9 de Mai de 2009
Mensagens: 193

MensagemEnviada: Ter Ago 05, 2014 10:38 pm    Assunto: Responder com Citação

Então pessoal, eu estava com problemas para usar esse código por conta do antivírus.

Resolvendo o problema eu já consegui realizar o acesso e obter o html com o conteúdo da NFe. Wink

Abraços!
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
claudio.ferreira
Profissional
Profissional


Registrado: Quarta-Feira, 18 de Setembro de 2013
Mensagens: 667

MensagemEnviada: Qua Ago 06, 2014 9:54 am    Assunto: Responder com Citação

Prezado Tiago, eu ia desenvolver algo assim para buscar o NFe do site da fazenda. Voce poderia dizer se esse codigo está funcionando ?

Grato.
_________________
Sistema SNGPC para farmácias
http://www.cmasistemas.com.br
Rastreabilidade de Medicamentos
https://www.sncm.com.br
Soluções em Delphi
https://delphisolutions.wordpress.com/
.
"E não sabendo que era impossível, foi lá e fez"
Mark Twain
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Visitar a homepage do Usuário
tiago.prs
Aprendiz
Aprendiz


Registrado: Sábado, 9 de Mai de 2009
Mensagens: 193

MensagemEnviada: Qua Ago 06, 2014 10:05 pm    Assunto: Responder com Citação

Olá claudio.ferreira!

claudio.ferreira escreveu:
Prezado Tiago, eu ia desenvolver algo assim para buscar o NFe do site da fazenda. Voce poderia dizer se esse codigo está funcionando ?
Grato.


Sim, funciona.
Eu fiz no Delphi XE3.
Sidnei, você fez com o Delphi XE3 também?

O amigo Sidnei me mandou um e-mail, com um exemplo que trocamos funcionando, e exatamente hoje a receita mudou o site de consulta de NFe (mais uma vez - ela está constantemente mudando), a princípio ele me disse que conseguiu resolver a imagem do captcha, que está em base 64.

Decodificaram a imagem do captcha em uma string na base 64.
Ele me mandou um e-mail dizendo que resolveu isso. Provavelmente terá que resolver o código fonte da página que mudou também.

Bom, está ciente que a importação de uma NFe pela web, sem acesso com certificado digital, consiste em filtrar o HTML da página e pegar os valores, certo?
Com Indy isso fica mais rápido só por não ter que esperar renderizar (os exemplos encontrados por ai usam o TWebBrowser e isso já é um custo no desempenho por conta da renderização).

Muito de plugins, imagens entre outros não são baixados também.
Enfim, desempenho maior.

Mas então, sim, funciona!
Vou ver se posto um exemplo obtendo o HTML com os valores.
Quem sabe mais tarde continuo o exemplo filtrando os dados.

Desculpe a demora para responder, estive tendo problemas para acessar o fórum do ActiveDelphi.

É isso ai então pessoal, abraços!
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
claudio.ferreira
Profissional
Profissional


Registrado: Quarta-Feira, 18 de Setembro de 2013
Mensagens: 667

MensagemEnviada: Qui Ago 07, 2014 9:57 am    Assunto: Responder com Citação

Olá Tiago,

Sempre preferi usar o IdHttp à TWebBrowser, acho que dá maior controle. Esse codigo é muito útil e muita gente precisa.

Se puder no futuro disponibilizar o codigo com as novas alterações agradeço e a comunidade também.

Grato.
_________________
Sistema SNGPC para farmácias
http://www.cmasistemas.com.br
Rastreabilidade de Medicamentos
https://www.sncm.com.br
Soluções em Delphi
https://delphisolutions.wordpress.com/
.
"E não sabendo que era impossível, foi lá e fez"
Mark Twain
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Visitar a homepage do Usuário
tiago.prs
Aprendiz
Aprendiz


Registrado: Sábado, 9 de Mai de 2009
Mensagens: 193

MensagemEnviada: Sáb Ago 09, 2014 10:05 am    Assunto: Responder com Citação

Caros, saudações!

Segue link com exemplo para do processo de obteção do html com os dados da NFe. No caso, o processo para logar por Indy.

https://github.com/tiagoprs/DonwloadNFeWeb

Demorei porque tenho andado bem ocupado.

Quanto ao git, paciência comigo pois não mexi nada nessa ferramenta ainda. Trabalho com SVN. Embarassed Laughing

O exemplo é bem simples, e paro no momento em que obtenho o html com os dados da NFe, ficando por responsabilidade de vocês agora filtrar os dados.

faço uso de um WebBrowser para facilitar o trabalho com o novo formato de captcha.
Se observarem também faço uso de Ole para facilitar a manipulação do html, o que trará um pouco de trabalho para migrar para Lazarus e deixá-lo cross-platform, por exemplo, no caso, Linux.

Espero que seja de bom uso.
[]´s
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
claudio.ferreira
Profissional
Profissional


Registrado: Quarta-Feira, 18 de Setembro de 2013
Mensagens: 667

MensagemEnviada: Sáb Ago 09, 2014 10:32 am    Assunto: Responder com Citação

Tiago, Obrigado !

Saiba que voce vai fazer muitos usuários felizes que agora não terâo que digitar as notas em seus sistemas.
_________________
Sistema SNGPC para farmácias
http://www.cmasistemas.com.br
Rastreabilidade de Medicamentos
https://www.sncm.com.br
Soluções em Delphi
https://delphisolutions.wordpress.com/
.
"E não sabendo que era impossível, foi lá e fez"
Mark Twain
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Visitar a homepage do Usuário
tiago.prs
Aprendiz
Aprendiz


Registrado: Sábado, 9 de Mai de 2009
Mensagens: 193

MensagemEnviada: Sáb Ago 09, 2014 10:41 am    Assunto: Responder com Citação

claudio.ferreira,

Que bom, eu torço para que ajude mesmo pois é sempre gratificante saber que dá para contribuir e então fazê-lo.

Não ajudar somente aos usuários, que são a grande maioria, mas também aos programadores individuais que estão sofrendo pressão de seus clientes, e os programadores contratados que estão sofrendo pressão de seus patrões. Laughing
Mr. Green

Mas o trabalho não acabou, só o que fiz foi pegar o HTML, ainda tem trabalho pela frente, ainda precisam pegar os dados! Wink
[]´s
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
Mostrar os tópicos anteriores:   
Novo Tópico   Responder Mensagem    ActiveDelphi - Índice do Fórum -> Delphi Todos os horários são GMT - 3 Horas
Ir à página 1, 2, 3  Próximo
Página 1 de 3

 
Ir para:  
Enviar Mensagens Novas: Proibido.
Responder Tópicos Proibido
Editar Mensagens: Proibido.
Excluir Mensagens: Proibido.
Votar em Enquetes: Proibido.


Powered by phpBB © 2001, 2005 phpBB Group
Traduzido por: Suporte phpBB