использование MS Excel VBA для извлечения данных из сложных HTML / JS - PullRequest
0 голосов
/ 14 ноября 2018

Краткое введение, я считаю себя средним VBA-кодером без какого-либо значительного опыта работы с HTML.Я хотел бы извлечь данные из веб-страницы HTML / JS, используя MS Excel VBA.Я потратил пару часов на тестирование своего кода на различных страницах, а также на поиск учебных материалов и различных форумов и страниц вопросов и ответов.

Я отчаянно прошу вас о помощи.(Office 2013, IE 11.0.96)

Цель состоит в том, чтобы получить курс обмена валют определенной веб-страницы Bloomberg.Долгосрочная цель состоит в том, чтобы запускать макрос по различным обменным курсам и выводить дневной курс из системы в таблицу Excel за рабочий день, но я справлюсь с этой частью.

Я был бы доволен либо

(1) текущий курс (класс span = "priceText__1853e8a5") или

(2) предыдущее закрытие (раздел class = "dataBox opreviousclosingpriceonetradingdayago numeric") или

(3) скорость открытия (раздел class = "dataBox openprice numeric").

Моя проблема в том, что я не могу получить ту часть HTML-кода, где находится скорость.

Dim IE As Object
Dim div As Object, holdingsClass As Object, botoes As Object
Dim html As HTMLDocument
Set IE = CreateObject("InternetExplorer.Application")
    With IE
        .Visible = False
        .Navigate "https://www.bloomberg.com/quote/EURHKD:CUR"
        Do Until .ReadyState = 4: DoEvents: Loop
    End With

Set html = IE.document
Set div = IE.document.getElementById("leaderboard") 'works just fine, populates the objects
Set holdingsClass = IE.document.getElementsByclass("dataBox opreviousclosingpriceonetradingdayago numeric") 'i am not sure is it a class element at all
Set botoes = IE.document.getElementsByTagName("dataBox openprice numeric") 'i am not sure is it a tag name at all

    Range("a1").Value = div.textContent 'example how i would place it by using .textContent 
    Range("A2").Value = holdingsClass.textContent
    Range("A3").Value = botoes.textContent

Очень ценю вашу помощь!

Ответы [ 3 ]

0 голосов
/ 14 ноября 2018

Чтобы ответить на ваши вопросы в целом, см. Ниже.

(1) текущий курс (класс span = "priceText__1853e8a5")

Это можно записать как селектор запросов CSS:

span.priceText__1853e8a5

(2) предыдущее закрытие (section class = "dataBox "прежде всего, цена закрыта", "число 101" *

Это можно записать как селектор запросов CSS:

.dataBox.opreviousclosingpriceonetradingdayago.numeric

(3) скорость открытия (section class = "dataBox openprice numeric")

Это можно записать как селектор запросов CSS:

.dataBox.openprice.numeric

Они применяются с querySelector или querySelectorAll (если требуется более одного совпадения и более позднее совпадение, чем первое) из HTMLDocument.

например.

Debug.Print IE.document.querySelector("span.priceText__1853e8a5").innerText

Если больше использовать querySelectorAll

IE.document.querySelectorAll("span.priceText__1853e8a5")(0).innerText

В приведенном выше примере вы заменяете 0 на соответствующий индекс, в котором находится целевой элемент.


Наблюдая за страницей, фактические селекторы выглядят следующим образом, но я думаю, что этот веб-сайт, вероятно, использует синтаксис ecmascript, который не поддерживается в устаревших браузерах, то есть Internet Explorer, или пытается заблокировать междоменные запросы.

Option Explicit

Public Sub GetInfo()
    Dim IE As New InternetExplorer
    With IE
        .Visible = True
        .navigate "https://www.bloomberg.com/quote/EURHKD:CUR"

        While .Busy Or .readyState < 4: DoEvents: Wend
        With .document
            Debug.Print "Current: " & .querySelector(".priceText__1853e8a5").innerText
            Debug.Print "Prev close: " & .querySelector(".value__b93f12ea").innerText
            Debug.Print "Open: " & .querySelector(".value__b93f12ea").innerText
        End With

        .Quit
    End With
End Sub

При использовании Selenium Basic и Chrome страница отображается нормально:

Option Explicit
Public Sub GetInfo()
    Dim d As WebDriver
    Set d = New ChromeDriver
    Const URL = "https://www.bloomberg.com/quote/EURHKD:CUR"
    With d
        .Start "Chrome"
        .get URL
        Debug.Print "Current: " & .FindElementByCss(".priceText__1853e8a5").Text
        Debug.Print "Prev close: " & .FindElementByCss(".value__b93f12ea").Text
        Debug.Print "Open: " & .FindElementByCss(".value__b93f12ea").Text
        .Quit
    End With
End Sub
0 голосов
/ 14 ноября 2018

Вместо того, чтобы копаться в html, почему бы не использовать Bloomberg API для запроса определенной ставки?

Вероятно, будет быстрее и сэкономит вам много времени в будущем, делая то же самое.

Пожалуйста, посмотрите мой похожий проект, в котором я создаю макрос для извлечения исторических курсов валют из Европейского центрального банка. https://github.com/dmegaffi/VBA-GET-Requests/blob/master/FX%20-%20GET.xlsm

0 голосов
/ 14 ноября 2018

Если щелкнуть правой кнопкой мыши нужный элемент веб-страницы в Chrome и выбрать «осмотреть», отобразятся подробности этого элемента. Вы также можете нажать клавишу F12, чтобы открыть HTML-код любой страницы. Это также работает в других браузерах.

Это элемент, который вы ищете? снимок экрана упомянутой веб-страницы

Исходя из кода выше, вы можете ссылаться на этот элемент с помощью IE.document.getElementsByclass ("priceText__1853e8a5"). Элементы в HTML могут совместно использовать классы, но не могут совместно использовать идентификаторы, поэтому, если есть другой элемент с классом priceText__1853e8a5, он не будет работать, поскольку он не выберет ни одного элемента. Затем, конечно, вы должны выделить текст внутри элемента, так как в этот момент у вас просто будет текст, и вам понадобится текст внутри него. Надеюсь это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...