2016-03-10 3 views
1

первый раз проводкиВойти на сайт, используя Msxml2.XMLHTTP вместо InternetExplorer.Application с VBA

Я пытаюсь получить идентификатор «dadosDoUsuario» со страницы веб-сайта, я должен быть зарегистрирован. Я получил его работая с использованием объекта «InternetExplorer.Application», но не может получить значение ID при использовании объекта «MSXML2.XMLHTTP». Кажется, он не пройдет мимо страницы входа, так как я могу получить другие идентификаторы с этой страницы (пример: «tituloPagina»). Может ли кто-нибудь дать подсказку о том, как я получаю данные со страницы после входа в систему? Благодаря!

код InternetExplorer.Application (это работает):

Sub testIE() 
Dim texto As String 

Set ie = CreateObject("InternetExplorer.Application") 
my_url = "https://www.nfp.fazenda.sp.gov.br/login.aspx" 
With ie 
    .Visible = False 
    .Navigate my_url 

Do Until Not ie.Busy And ie.readyState = 4 
    DoEvents 
Loop 

End With 

ie.Document.getelementbyid("userName").Value = "MYUSERNAME" 
ie.Document.getelementbyid("Password").Value = "MYPASSWORD" 
ie.Document.getelementbyid("Login").Click 

Do Until Not ie.Busy And ie.readyState = 4 
    DoEvents 
Loop 

ie.Document.getelementbyid("btnConsultarNFSemestre").Click 

Do Until Not ie.Busy And ie.readyState = 4 
    DoEvents 
Loop 

texto = ie.Document.getelementbyid("dadosDoUsuario").innerText 
MsgBox texto 

ie.Quit 

End Sub 

Msxml2.XMLHTTP код (это один не работает):

Sub testXMLHTTP() 
Dim xml As Object 
Dim html As Object 
Dim dados As Object 
Dim text As Object 

Set xml = CreateObject("MSXML2.XMLHTTP") 

Set html = CreateObject("htmlFile") 

With xml 
    .Open "POST", "https://www.nfp.fazenda.sp.gov.br/Login.aspx", False 
    .setRequestHeader "Content-Type", "text/xml" 
    .send "userName=MYUSERNAME&password=MYPASSWORD" 
    .Open "GET", "https://www.nfp.fazenda.sp.gov.br/Inicio.aspx", False 
    .setRequestHeader "Content-Type", "text/xml" 
    .send 
End With 

html.body.innerhtml = xml.responseText 

Set objResult = html.GetElementById("dadosDoUsuario") 
GetElementById = objResult.innertext 

MsgBox GetElementById 

End Sub 

EDIT: Я последовал шаги, предложенные @ Florent B., и добавил scripcontrol для получения закодированных значений для __VIEWSTATE, __VIEWSTATEGENERATOR и __EVENTVALIDATION. Сработало!

Sub testXMLHTTP() 
Dim xml As Object 
Dim html As HTMLDocument 
Dim dados As Object 
Dim text As Object 
Dim html2 As HTMLDocument 
Dim xml2 As Object 

Set xml = CreateObject("Msxml2.ServerXMLHTTP.6.0") 
Set html = CreateObject("htmlFile") 


With xml 
    .Open "GET", "https://www.nfp.fazenda.sp.gov.br/Login.aspx", False 
    .send 
End With 

strCookie = xml.getResponseHeader("Set-Cookie") 

html.body.innerhtml = xml.responseText 

Set objvstate = html.GetElementById("__VIEWSTATE") 
Set objvstategen = html.GetElementById("__VIEWSTATEGENERATOR") 
Set objeventval = html.GetElementById("__EVENTVALIDATION") 

vstate = objvstate.Value 
vstategen = objvstategen.Value 
eventval = objeventval.Value 

'URL Encode ViewState 
    Dim ScriptEngine As ScriptControl 
    Set ScriptEngine = New ScriptControl 
    ScriptEngine.Language = "JScript" 
    ScriptEngine.AddCode "function encode(vstate) {return encodeURIComponent(vstate);}" 
    Dim encoded As String 
    encoded = ScriptEngine.Run("encode", vstate) 
    vstate = encoded 
'URL Encode Event Validation 
    ScriptEngine.AddCode "function encode(eventval) {return encodeURIComponent(eventval);}" 
    encoded = ScriptEngine.Run("encode", eventval) 
    eventval = encoded 
'URL Encode ViewState Generator 
    ScriptEngine.AddCode "function encode(vstategen) {return encodeURIComponent(vstategen);}" 
    encoded = ScriptEngine.Run("encode", vstategen) 
    vstategen = encoded 

Postdata = "__EVENTTARGET=" & "&__EVENTARGUMENT=" & "&__VIEWSTATE=" & vstate & "&__VIEWSTATEGENERATOR=" & vstategen & "&__EVENTVALIDATION=" & eventval & "&ctl00$ddlTipoUsuario=#rdBtnNaoContribuinte" & "&ctl00$UserNameAcessivel=Digite+o+Usuário" & "&ctl00$PasswordAcessivel=x" & "&ctl00$ConteudoPagina$Login1$rblTipo=rdBtnNaoContribuinte" & "&ctl00$ConteudoPagina$Login1$UserName=MYUSERNAME" & "&ctl00$ConteudoPagina$Login1$Password=MYPASSWORD" & "&ctl00$ConteudoPagina$Login1$Login=Acessar" & "&ctl00$ConteudoPagina$Login1$txtCpfCnpj=Digite+o+Usuário" 

Set xml2 = CreateObject("Msxml2.ServerXMLHTTP.6.0") 
Set html2 = CreateObject("htmlFile") 

With xml2 
    .Open "POST", "https://www.nfp.fazenda.sp.gov.br/Login.aspx", False 
    .setRequestHeader "Cookie", strCookie 
    .setRequestHeader "Content-Type", "application/x-www-form-urlencoded" 
    .setRequestHeader "Content-Lenght", Len(Postdata) 
    .send (Postdata) 
End With 

html2.body.innerhtml = xml2.responseText 

Set objResult = html2.GetElementById("dadosDoUsuario") 
GetElementById = objResult.innertext 

MsgBox GetElementById 


End Sub 

ответ

2

Возможно, но это не так просто.

Сначала вам нужно использовать CreateObject («Msxml2.ServerXMLHTTP.6.0»), а не CreateObject («MSXML2.XMLHTTP»).

Затем выполните следующие действия:

  1. Открыть и послать GET к https://www.nfp.fazenda.sp.gov.br/login.aspx
  2. синтаксический анализ и сохранять файлы из заголовка ответа "Set-Cookie"
  3. Анализировать и хранить __VIEWSTATE, __VIEWSTATEGENERATOR, __EVENTVALIDATION из ответа HTML
  4. Создайте данные для следующего запроса с ранее проанализированными значениями и с вашим именем пользователя/паролем:

    __EVENTTARGET:"" 
    __EVENTARGUMENT:"" 
    __VIEWSTATE:"..." 
    __VIEWSTATEGENERATOR:"..." 
    __EVENTVALIDATION:"..." 
    ctl00$ddlTipoUsuario:"#rdBtnNaoContribuinte" 
    ctl00$UserNameAcessivel:"Digite+o+Usuário" 
    ctl00$PasswordAcessivel:"x" 
    ctl00$ConteudoPagina$Login1$rblTipo:"rdBtnNaoContribuinte" 
    ctl00$ConteudoPagina$Login1$UserName:"..." 
    ctl00$ConteudoPagina$Login1$Password:"..." 
    ctl00$ConteudoPagina$Login1$Login:"Acessar" 
    ctl00$ConteudoPagina$Login1$txtCpfCnpj:"Digite+o+Usuário" 
    
  5. Открыть ПОСТ к https://www.nfp.fazenda.sp.gov.br/login.aspx

  6. Установите заголовок "Cookie" с куками разобранных на шаге 2
  7. Установите заголовок Content-Type: "применение/х-WWW-форм-urlencoded"
  8. указан заголовок Content-Length с длиной данных
  9. Отправьте POST с данными, начиная с шага 4
+2

это хороший план действий. Я хочу отметить, что использование 'ServerXMLHTTP' не является обязательным в общем случае. 'XMLHTTP' имеет то преимущество, что вам не нужно беспокоиться о файлах cookie - он управляет ими изначально: получает, сохраняет и отправляет вам необходимый файл cookie, поскольку он основан на IE. Хотя у него нет возможности перенаправления и игнорирования ошибок сертификата, поэтому для этих случаев «ServerXMLHTTP» является единственным способом. Также 'ServerXMLHTTP' полезен, когда вам нужно отправить несколько одновременных запросов с разными куки-файлами. – omegastripes

+0

Helo @Florent B., спасибо за ответ, и извините за то, что я долго возвращался, я решил немного изучить, чтобы лучше понять, что вы предложили. Я отредактировал исходный пост с новым кодом, выполнив шаги, которые вы предложили. Я все еще не получаю ответ со страницы после входа в систему. Что может быть неправильным? –

+0

Вы должны проверить и сравнить пакеты, чтобы определить, что не соответствует вашему запросу (https://www.wireshark.org). –

Смежные вопросы