Очистка данных с веб-сайта с помощью vba
Я пытаюсь соскрести данные с сайта: http://uk.investing.com/rates-bonds/financial-futures с помощью VBA, как и в режиме реального времени цены, т. е. немецкий 5 год бобло, нам 30-летние казначейские облигации, я пробовал в Excel веб-запрос, но это только царапины весь сайт, но я хотел бы, чтобы очистить уровень только, есть ли способ сделать это?
5 ответов:
Существует несколько способов сделать это. Это ответ, который я пишу, надеясь, что все основы автоматизации Internet Explorer будут найдены при просмотре ключевых слов "очистка данных с веб-сайта", но помните, что ничто не стоит вашего собственного исследования (если вы не хотите придерживаться заранее написанных кодов, которые вы не можете настроить).
Обратите внимание, что это один из способов , который я не предпочитаю с точки зрения производительности (так как это зависит от скорости браузера), но это хорошо, чтобы понять обоснование автоматизации Интернета.
1) Если мне нужно просматривать веб-страницы, мне нужен браузер! Поэтому я создаю браузер Internet Explorer:2) я прошу браузер просмотреть целевую веб-страницу. Через пользование имуществом".Видимый", я решаю, хочу ли я видеть, что браузер делает свою работу или нет. При построении кода приятно иметьDim appIE As Object Set appIE = CreateObject("internetexplorer.application")Visible = True, но когда код работает на выскабливание данных приятно не видеть его каждый раз такVisible = False.3) веб-странице потребуется некоторое время для загрузки. Так что я подожду, пока он будет занят...With appIE .Navigate "http://uk.investing.com/rates-bonds/financial-futures" .Visible = True End With4) Ну вот, теперь страница загружена. Скажем, что я хочу наскрести изменение US30Y T-Bond: Я просто нажму F12 в Internet Explorer, чтобы увидеть код веб-страницы, и, следовательно, с помощью указателя (в красном круге) я нажму на элемент, который я хочу очистить, чтобы увидеть, как я могу достичь своей цели.Do While appIE.Busy DoEvents Loop5) то, что я должен сделать, это прямой вперед. Прежде всего, я получу по свойству ID элемент
tr, содержащий значение:Set allRowOfData = appIE.document.getElementById("pair_8907")Здесь я получу набор
tdэлементов (в частности,tr- это строка данных, аtd- ее ячейки. Мы ищем 8-го, поэтому я напишу:Почему я написал 7 вместо 8? Поскольку набор ячеек начинается с 0, то индекс 8-го элемента равен 7 (8-1). Вкратце анализируя эту линию код:Dim myValue As String: myValue = allRowOfData.Cells(7).innerHTML
.Cells()дает мне доступ к элементамtd;innerHTML- это свойство ячейки, содержащей искомое значение.Как только мы получим наше значение, которое теперь хранится в переменной
myValue, мы можем просто закрыть браузер IE и освободить память, установив его в ничто:Теперь у вас есть ваша ценность, и вы можете делать с ней все, что хотите: поместить ее в ячейку (appIE.Quit Set appIE = NothingRange("A1").Value = myValue) или в ярлык формы (Me.label1.Text = myValue). Я просто хотел бы указать вам, что это не так, как работает StackOverflow: здесь вы публикуете вопросы о конкретных проблемах с кодированием, но сначала вы должны сделать свой собственный поиск. Причина, по которой я отвечаю на вопрос, который не показывает слишком много исследовательских усилий, заключается в том, что я вижу, что его задавали несколько раз, и, возвращаясь к тому времени, когда я научился это делать, я помню, что мне хотелось бы иметь более качественную поддержку для начала. Поэтому я надеюсь, что этот ответ, который является просто "ввод исследования" и вовсе не самое лучшее/самое полное решение, может быть поддержкой для следующего пользователя, имеющего ту же самую проблему. Потому что я научился программировать благодаря этому сообществу, и мне нравится думать, что вы и другие новички могли бы использовать мой вклад, чтобы открыть для себя прекрасный мир программирования.Наслаждайтесь своей практикой ;)
Были упомянуты и другие методы, поэтому давайте, пожалуйста, признаем, что на момент написания этой книги мы находимся в 21 веке. Давайте припаркуемлокальный автобус открытие браузера, и fly с XMLHTTP GET запрос (XHR GET для краткости).
XHR-это API в виде объекта, методы которого передают данные между веб-браузером и веб-сервером. Объект предоставляется компанией JavaScript браузера окружающая среда
Это быстрый метод извлечения данных, который не требует открытия браузера. Ответ сервера может быть прочитан в HTMLDocument, и процесс захвата таблицы продолжается оттуда.
В приведенном ниже коде таблица захватывается ее идентификатором
cr1.В вспомогательном подразделе
WriteTableмы циклически перебираем столбцы (тегиtd), а затем строки таблицы (тегиtr) и, наконец, проходим через длину каждой строки таблицы, ячейки таблицы по ячейка таблицы. Поскольку нам нужны только данные из столбцов 1 и 8, используется операторSelect Case, указывающий, что записывается на лист.
Пример просмотра веб-страницы:
Пример вывода кода:
VBA:
Option Explicit Public Sub GetRates() Dim sResponse As String, html As New HTMLDocument '<== Tools > References > HTML Object Library Dim hTable As HTMLTable Application.ScreenUpdating = False With CreateObject("MSXML2.XMLHTTP") .Open "GET", "https://uk.investing.com/rates-bonds/financial-futures", False .setRequestHeader "If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT" .send sResponse = StrConv(.responseBody, vbUnicode) End With sResponse = Mid$(sResponse, InStr(1, sResponse, "<!DOCTYPE ")) With html .body.innerHTML = sResponse Set hTable = .getElementById("cr1") WriteTable hTable, 1, ThisWorkbook.Worksheets("Sheet1") End With Application.ScreenUpdating = True End Sub Public Sub WriteTable(ByVal hTable As HTMLTable, Optional ByVal startRow As Long = 1, Optional ByVal ws As Worksheet) Dim tSection As Object, tRow As Object, tCell As Object, tr As Object, td As Object, r As Long, C As Long, tBody As Object r = startRow: If ws Is Nothing Then Set ws = ActiveSheet With ws Dim headers As Object, header As Object, columnCounter As Long Set headers = hTable.getElementsByTagName("th") For Each header In headers columnCounter = columnCounter + 1 Select Case columnCounter Case 2 .Cells(startRow, 1) = header.innerText Case 8 .Cells(startRow, 2) = header.innerText End Select Next header startRow = startRow + 1 Set tBody = hTable.getElementsByTagName("tbody") For Each tSection In tBody Set tRow = tSection.getElementsByTagName("tr") For Each tr In tRow r = r + 1 Set tCell = tr.getElementsByTagName("td") C = 1 For Each td In tCell Select Case C Case 2 .Cells(r, 1).Value = td.innerText Case 8 .Cells(r, 2).Value = td.innerText End Select C = C + 1 Next td Next tr Next tSection End With End Sub
Вы можете использовать объект winhttprequest вместо internet explorer, так как он хорош для загрузки данных, исключая картинки N реклама вместо загрузки полной веб-страницы, включая рекламу n картинки, которые делают объект internet explorer тяжелым по сравнению с объектом winhttpRequest.
Этот вопрос задали задолго до этого. Но я подумал, что следующая информация будет полезна для новичков. На самом деле вы можете легко получить значения из имени класса, как это.
Sub ExtractLastValue() Set objIE = CreateObject("InternetExplorer.Application") objIE.Top = 0 objIE.Left = 0 objIE.Width = 800 objIE.Height = 600 objIE.Visible = True objIE.Navigate ("https://uk.investing.com/rates-bonds/financial-futures/") Do DoEvents Loop Until objIE.readystate = 4 MsgBox objIE.document.getElementsByClassName("pid-8907-last")(0).innerText End SubИ если вы новичок в веб-выскабливание читайте в нашем блоге.
А также существуют различные методы извлечения данных из веб-страниц. В этой статье мы рассмотрим лишь некоторые из них на примерах.
Я изменил некоторые вещи, которые были всплывающие ошибки для меня и в конечном итоге с этим, который работал отлично, чтобы извлечь данные, как мне нужно:
Sub get_data_web() Dim appIE As Object Set appIE = CreateObject("internetexplorer.application") With appIE .navigate "https://finance.yahoo.com/quote/NQ%3DF/futures?p=NQ%3DF" .Visible = True End With Do While appIE.Busy DoEvents Loop Set allRowofData = appIE.document.getElementsByClassName("Ta(end) BdT Bdc($c-fuji-grey-c) H(36px)") Dim i As Long Dim myValue As String Count = 1 For Each itm In allRowofData For i = 0 To 4 myValue = itm.Cells(i).innerText ActiveSheet.Cells(Count, i + 1).Value = myValue Next Count = Count + 1 Next appIE.Quit Set appIE = Nothing End Sub




Comments