#html #excel #vba #web-scraping
#HTML #excel #vba #очистка веб-страниц
Вопрос:
Я пытаюсь извлечь некоторые данные из таблицы HTML, однако я продолжаю получать сообщение об ошибке 13 «Несоответствие типов». Возможно, это связано с тем, что я использую неправильный HTML-тег. Я боролся с этим уже несколько дней, так как не могу выработать правильный процесс.
Это HTML, который я использую
Код
Dim htmlTable As Object
Dim collTD As Collection
Dim oNode As Object
Dim IE As Object
Set IE = CreateObject("InternetExplorer.application")
With IE
.Visible = True
.navigate "https://ukonlinestores.co.uk/amazon-uk-sellers/"
' Wait for the page to fully load; you can't do anything if the page is not fully loaded
Do While .Busy Or _
.readyState <> 4
DoEvents
Loop
Set htmlTable = IE.document.getElementById("table_1")
Set collTD = htmlTable.getElementsByTagName("td")
For Each oNode In collTD
.Range("A" amp; RowCount) = oNode.innerHTML
RowCount = RowCount 1
Next oNode
End With
ОБНОВЛЕНИЕ ПО СОСТОЯНИЮ НА СЕГОДНЯ ПН, 12 ОКТЯБРЯ 2020 Г.
Я внес несколько изменений в код, поскольку я хочу перемещаться по таблице разбивки на страницы и извлекать данные с каждой страницы. Я знаю, что добавленный мной код разбивки на страницы работает, поскольку в настоящее время я использую его в другом коде, моя проблема в том, что он не перемещается по страницам, возможно, из-за неправильного класса или идентификатора.
HTML для СЛЕДУЮЩЕЙ страницы
Новый код, обновленный
Dim htmlTable As Object
Dim collTD As Object
Dim oNode As Object
Dim IE As Object
Dim RowCount As Long
Dim currentColumn As Long
''''' NEW '''''''
Dim HTMLdoc As Object
Dim nextPageElements As Object
Dim pageNumber As Long
'''' START ROW 5 ''''''
RowCount = 5
currentColumn = 1
Set IE = CreateObject("InternetExplorer.application")
With IE
.Visible = True
.navigate "https://ukonlinestores.co.uk/amazon-uk-sellers/"
' Wait for the page to fully load; you can't do anything if the page is not fully loaded
Do While .readyState <> 4: DoEvents: Loop
Application.Wait (Now TimeSerial(0, 0, 2))
StartForLoop_Restart:
Set htmlTable = .document.getElementById("table_1")
Set collTD = htmlTable.getElementsByTagName("td")
For Each oNode In collTD
If currentColumn Mod 11 = 0 Then
RowCount = RowCount 1
currentColumn = 1
End If
Cells(RowCount, currentColumn) = oNode.innerHTML 'Change to inner HTML to pull of url
currentColumn = currentColumn 1
Next oNode
''''' ######### NEXT PAGE AND DELAYS ###### added by me
Do
DoEvents
''''' Searches Number of Pages entered in Sheet3 A2
If pageNumber >= Replace(Worksheets("Sheet3").Range("A2").Value, " ", " ") Then Exit Do
On Error Resume Next
''' ################### CHANGE THE CLASS OF THE NEXT PAGE ########################## ERROR IS HERE ####
Set nextPageElements = HTMLdoc.getElementsByClassName("paginate_button next")(0)
'Set nextPageElements = HTMLdoc.getElementsID("table_1_next ")(0)
If nextPageElements Is Nothing Then Exit Do
''' ################### CHANGE THE CLASS OF THE NEXT PAGE ########################## ERROR IS ABOVE ####
''''' Scrolls Down the Browser
IE.document.parentWindow.Scroll 0amp;, 99999
'''''Random delay from Max number entered in
Application.Wait Now TimeSerial(0, 0, Application.RandBetween(1, Worksheets("Sheet3").Range("B2").Value))
nextPageElements.Click 'next web page
Do While IE.Busy Or IE.readyState <> 4
DoEvents
Loop
''''Second Random delay from Max number entered
Application.Wait Now TimeSerial(0, 0, Application.RandBetween(1, Worksheets("Sheet3").Range("C2").Value))
Set HTMLdoc = IE.document
pageNumber = pageNumber 1
GoTo StartForLoop_Restart
Loop
End With
IE.Quit
Set IE = Nothing
Set HTMLdoc = Nothing
Set nextPageElements = Nothing
MsgBox "All Done"
Также необходимо
В настоящее время я не думаю, что результаты следующей страницы копируются и вставляются под результатами предыдущей страницы. Это должно быть что-то вроде этого. Цвет используется только для вашего reff.
- Зеленый = Страница 1 результатов
- Красный = Страница 2 результатов
- Синий = Результаты Page3 и так далее, как показано ниже.
Комментарии:
1. Вы пробовали
Dim collTD As Object
?2. Нет, однако я только что проверил вашу рекомендацию и получил сообщение об ошибке в этой строке кода
.Range("A" amp; RowCount) = oNode.innerHTML
ОБЪЕКТ НЕ ПОДДЕРЖИВАЕТ ЭТО СВОЙСТВО ИЛИ МЕТОД
Ответ №1:
Вы должны правильно объявлять свои объекты как элементы IHTML, чтобы манипулировать ими и использовать их методы.
Сначала добавьте ссылку на библиотеку объектов Microsoft HTML
Ваш код становится
Sub test()
Dim htmlTable As IHTMLElement
Dim collTD As IHTMLElementCollection
Dim oNode As IHTMLElement
Dim IE As Object
Dim RowCount As Integer
Set IE = CreateObject("InternetExplorer.application")
With IE
.Visible = True
.navigate "https://ukonlinestores.co.uk/amazon-uk-sellers/"
' Wait for the page to fully load; you can't do anything if the page is not fully loaded
Do While .Busy Or _
.readyState <> 4
DoEvents
Loop
Set htmlTable = IE.document.getElementById("table_1")
Set collTD = htmlTable.getElementsByTagName("td")
RowCount = 1
For Each oNode In collTD
ThisWorkbook.Worksheets(1).Range("A" amp; RowCount) = oNode.innerHTML
RowCount = RowCount 1
Next oNode
End With
End Sub
Комментарии:
1. Thomas G У меня уже есть библиотека объектов HTML и элементы управления Интернетом в моем проекте. Вы утверждаете, что мне нужна другая ссылка, если да, то какая, поскольку я не смог заставить ваш код что-либо сделать. Я что-то упускаю?
Ответ №2:
При поздней привязке вам не нужна ссылка.
Sub Test()
Dim htmlTable As Object
Dim collTD As Object
Dim oNode As Object
Dim IE As Object
Dim RowCount As Long
Dim currentColumn As Long
RowCount = 1
currentColumn = 1
Set IE = CreateObject("InternetExplorer.application")
With IE
.Visible = True
.navigate "https://ukonlinestores.co.uk/amazon-uk-sellers/"
' Wait for the page to fully load; you can't do anything if the page is not fully loaded
Do While .readyState <> 4: DoEvents: Loop
Application.Wait (Now TimeSerial(0, 0, 2))
Set htmlTable = .document.getElementById("table_1")
Set collTD = htmlTable.getElementsByTagName("td")
For Each oNode In collTD
If currentColumn Mod 11 = 0 Then
RowCount = RowCount 1
currentColumn = 1
End If
Cells(RowCount, currentColumn) = oNode.innertext
currentColumn = currentColumn 1
Next oNode
End With
End Sub
Комментарии:
1.Zwenn, спасибо за вашу помощь, ваш код работает, однако он помещает все в столбец A, я предположил, что он будет начинаться с A и проходить так, как показано на веб-странице. Я также добавил это к For Each oNode в CollTD
ThisWorkbook.Worksheets(3).Range("A" amp; RowCount) = oNode.innerHTML RowCount = RowCount 1
, поскольку ваш код извлекал столбец 3 таблицы веб-страниц как слово «STORE», а не href. Мое небольшое изменение извлекает ссылку href. Не могли бы вы помочь распределить данные по столбцам, а НЕ только по столбцу A. Спасибо2. Цвенн, я добавил к своему первоначальному сообщению от 12/10/2020, пожалуйста, не могли бы вы взглянуть