VBA - веб-очистка не может найти правильный запрос GET - PullRequest
0 голосов
/ 27 августа 2018

Мой вопрос связан с другим вопросом VBA - веб-очистка не может получить HTMLElement innerText . У меня похожая проблема

URL сайта - https://www.hnb.hr/en/core-functions/monetary-policy/exchange-rate-list/exchange-rate-list

Мне нужно получить дату обращения к валюте и выбранные значения. Проблема в том, что я не могу найти правильный запрос GET, где эти значения наконец генерируются. Я обнаружил, что это связано с запросом POST:

POST / а / ядро-функция / кредитно-денежная политика / обменного курс-лист / обменный курс-лист? P_p_id = tecajnalistacontroller_WAR_hnbtecajnalistaportlet & p_p_lifecycle = 2 & p_p_state = нормальное и p_p_mode = вид и p_p_resource_id = getTecajnaAjaxDataURL & p_p_cacheability = cacheLevelPage & p_p_col_id = колонок 2 & p_p_col_count = 2 HTTP / 1,1

Я хотел бы использовать метод с получением по идентификатору, классу или тегу - что угодно, но только при условии, что GET URL-запрос слишком быстр для получения необходимой информации

1 Ответ

0 голосов
/ 27 августа 2018

XMLHTTP-запрос и API:

Я бы использовал их API , как показано ниже. У меня есть некоторые вспомогательные функции, чтобы помочь с анализом ответа. В функции GetDict вы можете установить интересующие вас валюты. В функции GetRate вы можете указать интересующий вас курс. Если вы не укажете, по умолчанию будет "median_rate".

Вызов API:

Чтобы узнать тарифы на определенную дату, сделайте [n] HTTP-вызов следующий URL:

http://hnbex.eu/api/v1/rates/daily/?date=YYYY-MM-DD

Параметр даты является необязательным. Если не установлено, текущая дата (сегодня) используется.

Вы можете проанализировать ответ JSON с помощью JSON parser, но я обнаружил, что проще использовать Split для получения необходимой информации из строки JSON. Если вы знакомы с JSON, я с удовольствием обновлю пример JSON-разбора.

Option Explicit

Public Sub GetInfo()
    'http://hnbex.eu/api/v1/
    Dim strJSON As String, http As Object, json As Object
    Const URL As String = "http://hnbex.eu/api/v1/rates/daily/"

    Set http = CreateObject("MSXML2.XMLHTTP")
    With http
        .Open "GET", URL, False
        .send
        strJSON = .responseText
    End With
    'Set json = JsonConverter.ParseJson(strJSON) '<== You could parse the JSON using a JSON parse such as [JSONConverter][1]

    Dim currencyDict As Object
    Set currencyDict = GetDict

    Dim key As Variant, dictKeys As Variant, result As Variant
    For Each key In currencyDict.keys
        result = GetRate(strJSON, key)
        If Not IsError(result) Then currencyDict(key) = result
        result = vbNullString
    Next key

    PrintDictionary currencyDict

End Sub

Public Function GetDict() As Object '<== You could adapt to pass currencies as string arguments to the function. Or even a string array.
    Dim dict As Object
    Set dict = CreateObject("Scripting.Dictionary")
    dict.Add "EUR", vbNullString
    dict.Add "CZK", vbNullString
    dict.Add "HRK", vbNullString
    dict.Add "HUF", vbNullString
    dict.Add "PLN", vbNullString
    dict.Add "RON", vbNullString
    dict.Add "RSD", vbNullString
    Set GetDict = dict
End Function

Public Function GetRate(ByVal json As String, ByVal key As Variant, Optional ByVal rate As String = "median_rate") As Variant
    Dim arr() As String, tempString As String
    On Error GoTo Errhand
    arr = Split(json, """currency_code"": " & Chr$(34) & key & Chr$(34))
    tempString = arr(1)
    tempString = Split(arr(1), Chr$(34) & rate & Chr$(34) & ":")(1)
    tempString = Split(tempString, ",")(0)
    GetRate = tempString
    Exit Function
Errhand:
    GetRate = CVErr(xlErrNA)
End Function

Public Sub PrintDictionary(ByVal dict As Object)
    Dim key As Variant
    For Each key In dict.keys
        Debug.Print key & " : " & dict(key)
    Next
End Sub

Internet Explorer:

Вы можете использовать цикл с явным ожиданием появления элемента на странице (или заполнения)

Option Explicit
Public Sub GetInfo()
    Dim IE As New InternetExplorer, t As Date, hTable As HTMLTable, clipboard As Object
    Const WAIT_TIME_SECS As Long = 5
    t = Timer

    With IE
        .Visible = True
        .navigate "https://www.hnb.hr/en/core-functions/monetary-policy/exchange-rate-list/exchange-rate-list"

        While .Busy Or .readyState < 4: DoEvents: Wend

        Do
            DoEvents
            On Error Resume Next
            Set hTable = .document.getElementById("records_table")
            On Error GoTo 0
            If Timer - t > WAIT_TIME_SECS Then Exit Do
        Loop While hTable Is Nothing

        If hTable Is Nothing Then
            .Quit
            Exit Sub
        End If
        Set clipboard = GetObject("New:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
        clipboard.SetText hTable.outerHTML
        clipboard.PutInClipboard
        ThisWorkbook.Worksheets("Sheet1").Cells(1, 1).PasteSpecial
        .Quit                                    '<== Remember to quit application
    End With
End Sub
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...