2015-08-22 3 views
0

Я пытаюсь автоматизировать регистрацию и загрузку данных для веб-сайта (https://indexes.nasdaqomx.com/). Мой код стенает authenticiation, где проблема, моя верхняя часть WinHttpReq.responseText говорит, как показано ниже:веб-сайт Ошибка входа в систему с помощью WinHTTPrequest.5.1/Microsoft.XMLHTTP в VBA

</header> 
    <div class="container"> 
     <div class="row-fluid spacer"> 
    <div class="span12"> 
     <p class="textCenter"> 
      We're sorry your request could not be fulfilled. Rest assured we have been notifed and will resolve this issue shortly. 
     </p> 
    </div> 
</div> 

Мой код VBA, как показано ниже:

Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) 

Sub DownloadFile() 

Dim myuser As String 
Dim MyPass As String 
Dim sHTML As String 
myuser = "xxxxxx" 
MyPass = "xxxxxx" 

Dim WinHttpReq As Object 
Set WinHttpReq = CreateObject("Microsoft.XMLHTTP") 

WinHttpReq.Open "POST", "https://indexes.nasdaqomx.com/Account/LogOn", True 

WinHttpReq.SetRequestHeader "Content-type", "application/x-www-form-urlencoded" 
WinHttpReq.SetRequestHeader "Connection", "keep-alive" 
WinHttpReq.send "UserName=xxxxxx&Password=xxxxxxx" 
Sleep (6000) 
Debug.Print WinHttpReq.readyState 
If WinHttpReq.readyState = 4 Then 
sHTML = WinHttpReq.responseText 
'this below line result shows We're sorry your request could not be fulfilled 
Debug.Print sHTML 
End If 
Sleep (5000) ' delay 4 second 

WinHttpReq.Open "GET", "https://indexes.nasdaqomx.com/Index/ExportWeightings/NDX?tradeDate=2015-08-19T00:00:00.000&timeOfDay=SOD", True 
Debug.Print WinHttpReq.readyState 
WinHttpReq.SetRequestHeader "Connection", "keep-alive" 
WinHttpReq.send 
Sleep (5000) ' delay 4 second 
Debug.Print WinHttpReq.readyState 

MyURL = WinHttpReq.responseBody 
If WinHttpReq.Status = 200 Then 
    Set oStream = CreateObject("ADODB.Stream") 
    oStream.Open 
    oStream.Type = 1 
    oStream.Write WinHttpReq.responseBody 
    ' 1 = no overwrite, 2 = overwrite 
    oStream.SaveToFile "D:\Visual Basic Programming\Macro\nasdaqomx\SODWeightings_20150819_NDX.xlsx", 2 
    oStream.Close 
End If 

End Sub 

Итак, где проблема? У меня есть действительные учетные данные для этого, так как ручной вход работает нормально. Ниже приведен снимок экрана html-кода этой страницы. Он показывает какой-то код проверки запроса, но каждый раз, когда я это заметил, он отличается. Может ли кто-нибудь сказать мне, как делать логин программным образом на веб-странице?

login page html screenshot

+0

Вы не читаете скрытый элемент ввода для токена и передаете его обратно в строке отправки. Иногда вам нужно возвращать, казалось бы, безобидные элементы ввода, такие как submit. Лучше всего использовать такой инструмент, как [Fiddler] (http://www.telerik.com/fiddler), чтобы проверить, какая строка POST передана, и где во время ручного входа. – Jeeped

+0

Я подозревал это .... мог у PLZ опубликовать код, как читать скрытый элемент ввода для токена и отправить его обратно – pmr

ответ

1

Я не могу отправить «код», но я могу опубликовать некоторые рамки. Если у вас возникли проблемы с получением этой работы, используйте Fiddler для проверки скрытой строки POST при успешном входе в систему и ее дублировании.

Метод заключается в том, чтобы сначала ПОЛУЧИТЬ страницу и прочитать токен. Добавьте токен и любые другие случайные цифры < > введите элементы в свою строку отправки и отправьте ее обратно.

Я сделал несколько публичных открыток, поскольку они могут использоваться в других процедурах. Убедитесь, что у вас нет двух объявлений Option Explicit в верхней части листа вашего модуля.

Option Explicit 

Public pUSR As String 
Public pPWD As String 
'you might need this elsewhere; make it a public string 
Public pTOKENID As String 
'you might need one of these too 
Public pJSESSIONID As String 
'you want to go here 
Public Const csLOGINpg = "https://indexes.nasdaqomx.com/Account/LogOn" 
Public Const csTOKENnm = "__RequestVerificationToken" 

Sub mcr_XML_LogIn() 
    Dim htmlBDY As New MSHTML.HTMLDocument, xmlHTTP As New MSXML2.ServerXMLHTTP60 

    Dim iEL As Long, xmlSend As String 

    On Error GoTo bm_Err_Report 

    pJSESSIONID = vbNullString 
    pTOKENID = vbNullString 
    pUSR = "xxxxxx" 
    pPWD = "xxxxxxx" 

    With xmlHTTP 
     .Open "GET", csLOGINpg, False 
     .SetRequestHeader "Content-Type", "text/html;charset=UTF-8" 
     .SetRequestHeader "Connection", "keep-alive" 
     .send 

     htmlBDY.body.innerHTML = .responseText 

     If CBool(htmlBDY.getElementsByTagName("form").Length) Then 
      With htmlBDY.getElementsByTagName("form")(0) 
       For iEL = 0 To (.getElementsByTagName("input").Length - 1) 
        If htmlBDY.getElementsByTagName("input")(iEL).Name = csTOKENnm Then 
         pTOKENID = htmlBDY.getElementsByTagName("input")(iEL).Value 
         Exit For 
        End If 
       Next iEL 
      End With 
     End If 

     .Open "POST", csLOGINpg, False 
     .SetRequestHeader "Content-type", "application/x-www-form-urlencoded" 
     .SetRequestHeader "Connection", "keep-alive" 
     'you may need to send a JSESSIONID cookie; Fiddler will tell you this and other stuff 
     '.SetRequestHeader "Cookie", "JSESSIONID=" & pJSESSIONID 
     xmlSend = csTOKENnm & Chr(61) & pTOKENID & "&RememberMe=false&UserName=" & pUSR & "&Password=" & pPWD 
     Debug.Print xmlSend 

     .send xmlSend 
     htmlBDY.body.innerHTML = .responseText 
    End With 'done with the xmlHTTP object for now 

    'do something with what you received here (maybe check for a successful log-in) 
    Debug.Print Left(htmlBDY.body.innerHTML, 1024) 

    GoTo bm_Safe_Exit 

bm_Err_Report: 
    Debug.Print Err.Number & " - " & Err.Description 

bm_Safe_Exit: 
    Set htmlBDY = Nothing 
    Set xmlHTTP = Nothing 
End Sub 

Да, это основано на объекте MSXML2.ServerXMLHTTP60, но это один, который кладя IO, вокруг которого можно было бы легко отредактирована для публичного распространения.

Если вы используете этот код, не меняя его на WinHTTP, вам понадобятся справочные библиотеки microsoft XML v6.0 и Microsoft Internet Controls, добавленные в Инструменты VBE ► Ссылки.

Я пропустил это, чтобы убедиться, что я связался с правой страницей. Строка xmlSend была:

__RequestVerificationToken=RHr1FDomqqHEZQJPmMVqdwoFKVsK43uE3j1g+IWRF3nHqmxZGDyAxpUWqes2XCKgHVhHPnpLCcn3EOIKHJ30EoQbBOhV16IkS7oqPQm+3x5cex0GAWzfUYuzOGGYM35/Xa6jsXF7YsN78b3TzadIwS/8EENNdA6jSqtXgH7cDU/FNIRuMJQbO9dplwtglcg8&RememberMe=false&UserName=xxxxxx&Password=xxxxxxx 

... так что он извлекал токен. Первые 1024 символа .innerHTML:

<HEADER id=headerContent class=spacer> 
<DIV id=logoRow class=row-fluid> 
<DIV class=container> 
<DIV class=row-fluid> 
<DIV class=span6><A class=noLinkExternal href="http://nasdaqomx.com/"><IMG id=Nasdaqlogo style="MARGIN-RIGHT: -3px" alt="Nasdaq logo" src="about:/Content/Images/nasdaq_logo.png"></A> <A href="about:/"><IMG id=logo alt="Nasdaq Global Indexes" src="about:/Content/Images/global_indexes.png"></A> </DIV> 
<DIV class=span6> 
<DIV class=floatRight> 
<UL id=loginList class=hideListStyle> 
<LI class=hidden-phone><A id=LoginLink class=noLinkExternal>Log In</A></LI> 
<LI class=visible-phone><A href="about:/Account/LogOn">Log In</A></LI> 
<LI><A href="about:/Home/IndexData">Register</A></LI></UL><INPUT id=siteSearch class=ui-autocomplete-input value=Search> </DIV></DIV></DIV></DIV></DIV> 
<DIV id=menuContainer> 
<DIV class=container> 
<DIV class=row-fluid> 
<DIV class=span12> 
<DIV id=LoginPanel class=inputForm> 
<FORM method=post action=/Account/LogOn><INPUT type=hidden value=EpSOScbAMNDv1lIjBnm8Xew4Rn 

Надеюсь, что это поможет. Используйте Fiddler для решения любых проблем. Извините, но я не могу сделать ничего другого без действительных учетных данных.

+0

Это отличная помощь! – pmr

+0

может рекомендовать любую прикладную книгу, чтобы изучить веб-сайт. Механизм входа в систему java технический материал – pmr

+0

Рад, что это было полезно. Извините, но у меня нет рекомендаций по использованию, но форум [xmlHTTP] (http://stackoverflow.com/questions/new/xmlhttp?show=all&sort=newest) здесь хорош, и я вношу свой вклад, когда я Можно. – Jeeped