 |
ActiveDelphi .: O site do programador Delphi! :.
|
Exibir mensagem anterior :: Exibir próxima mensagem |
Autor |
Mensagem |
tiago.prs Aprendiz


Registrado: Sábado, 9 de Mai de 2009 Mensagens: 193
|
Enviada: Seg Ago 12, 2013 11:32 am Assunto: IdHTTP e consulta web de NFe [Resolvido] |
|
|
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 |
|
 |
tiago.prs Aprendiz


Registrado: Sábado, 9 de Mai de 2009 Mensagens: 193
|
Enviada: Qua Ago 14, 2013 2:13 pm Assunto: |
|
|
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 |
|
 |
scbrianti Novato

Registrado: Domingo, 3 de Agosto de 2014 Mensagens: 1
|
Enviada: Dom Ago 03, 2014 11:20 am Assunto: Baixar pagina Nfe |
|
|
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 |
|
 |
tiago.prs Aprendiz


Registrado: Sábado, 9 de Mai de 2009 Mensagens: 193
|
Enviada: Dom Ago 03, 2014 12:30 pm Assunto: |
|
|
Eu nem tenho mais esses fontes.
Não me lembro de nenhum segredo.
Tentei até reproduzir aqui, mas estou tendo logo erro de conexão socket.
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 |
|
 |
johnny-walker Moderador


Registrado: Sábado, 4 de Outubro de 2003 Mensagens: 10653 Localização: Contagem/MG - BRAZIL
|
Enviada: Seg Ago 04, 2014 8:46 pm Assunto: |
|
|
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 |
|
 |
tiago.prs Aprendiz


Registrado: Sábado, 9 de Mai de 2009 Mensagens: 193
|
Enviada: Seg Ago 04, 2014 11:53 pm Assunto: |
|
|
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 |
|
 |
johnny-walker Moderador


Registrado: Sábado, 4 de Outubro de 2003 Mensagens: 10653 Localização: Contagem/MG - BRAZIL
|
Enviada: Ter Ago 05, 2014 11:54 am Assunto: |
|
|
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 |
|
 |
claudio.ferreira Profissional


Registrado: Quarta-Feira, 18 de Setembro de 2013 Mensagens: 667
|
|
Voltar ao Topo |
|
 |
tiago.prs Aprendiz


Registrado: Sábado, 9 de Mai de 2009 Mensagens: 193
|
Enviada: Ter Ago 05, 2014 10:38 pm Assunto: |
|
|
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.
Abraços! |
|
Voltar ao Topo |
|
 |
claudio.ferreira Profissional


Registrado: Quarta-Feira, 18 de Setembro de 2013 Mensagens: 667
|
|
Voltar ao Topo |
|
 |
tiago.prs Aprendiz


Registrado: Sábado, 9 de Mai de 2009 Mensagens: 193
|
Enviada: Qua Ago 06, 2014 10:05 pm Assunto: |
|
|
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 |
|
 |
claudio.ferreira Profissional


Registrado: Quarta-Feira, 18 de Setembro de 2013 Mensagens: 667
|
Enviada: Qui Ago 07, 2014 9:57 am Assunto: |
|
|
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 |
|
 |
tiago.prs Aprendiz


Registrado: Sábado, 9 de Mai de 2009 Mensagens: 193
|
Enviada: Sáb Ago 09, 2014 10:05 am Assunto: |
|
|
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.
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 |
|
 |
claudio.ferreira Profissional


Registrado: Quarta-Feira, 18 de Setembro de 2013 Mensagens: 667
|
|
Voltar ao Topo |
|
 |
tiago.prs Aprendiz


Registrado: Sábado, 9 de Mai de 2009 Mensagens: 193
|
Enviada: Sáb Ago 09, 2014 10:41 am Assunto: |
|
|
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.
Mas o trabalho não acabou, só o que fiz foi pegar o HTML, ainda tem trabalho pela frente, ainda precisam pegar os dados!
[]´s |
|
Voltar ao Topo |
|
 |
|
|
Enviar Mensagens Novas: Proibido. Responder Tópicos Proibido Editar Mensagens: Proibido. Excluir Mensagens: Proibido. Votar em Enquetes: Proibido.
|
|