Сайт использует CloudFlare для защиты от DDoS / DoS. Это означает, что вы почти наверняка закончите с ошибкой xmlhttp, поскольку перенаправление будет происходить довольно быстро, и вы не получите ожидаемый контент во время циклов URL.
Вам также необходимо обработать не найденные страницы и задержать перенаправление CloudFlare, если это произойдет.
Следующие данные предназначены для тех, кто, возможно, захочет добавить в некоторых тестах, что в столбце A действительно есть URL-адреса. Я предполагаю, что URL-адреса находятся в столбце A листа sheet1, и эта информация записывается, начиная со столбца B. Я использую массивы для ускорить работу, а также обработку ошибок и указание на то, что не вся информация, которую вы хотите, может присутствовать на каждой странице / для каждого списка.
Option Explicit
Public Sub GetResults()
Dim html As HTMLDocument, page As Long, ws As Worksheet, index As Long
Dim results(), URLs(), ie As InternetExplorer, t As Date
Const MAX_WAIT_SEC As Long = 15
Application.ScreenUpdating = False
Set ie = New InternetExplorer
Set html = New HTMLDocument
Set ws = ThisWorkbook.Worksheets("Sheet1")
URLs = Application.Transpose(ws.Range("A1:A2").Value)
ReDim results(1 To UBound(URLs))
With ie
.Visible = True
For page = LBound(URLs) To UBound(URLs)
If InStr(URLs(page), "http") > 0 Then
.Navigate2 URLs(page)
While .Busy Or .readyState < 4: DoEvents: Wend
t = Timer
Do
If Timer - t > MAX_WAIT_SEC Then Exit Do
Loop While .document.querySelectorAll("#section_main").Length = 0
If Not InStr(.document.body.innerHTML, "404 - Sorry, we couldn't find what you were looking for. ") > 0 And _
Not InStr(.document.body.innerHTML, "No listings currently for sale") > 0 Then
index = index + 1
results(index) = GetInfo(.document, URLs(page))
Else
ReDim Preserve results(1 To UBound(results) - 1)
End If
End If
Next
.Quit
End With
Dim i As Long, j As Long, rowCounter As Long, arr()
rowCounter = 1
Dim headers()
headers = Array("URL", "Seller", "Feedback", "Condition", "Color", "Storage", "Price", "Headline")
ws.Cells(1, 2).Resize(1, UBound(headers) + 1) = headers
For i = LBound(results) To UBound(results)
arr = results(i)
For j = LBound(arr) To UBound(arr)
rowCounter = rowCounter + 1
ws.Cells(rowCounter, 2).Resize(1, UBound(arr(j)) + 1) = arr(j)
Next
Next
Application.ScreenUpdating = True
End Sub
Public Function GetInfo(ByVal html As HTMLDocument, ByVal url As String) As Variant
Dim dict As Object, results(), nodeList, numSellers As Long, counter As Long
Dim listings As Object, listing As Object, ws As Worksheet
Set dict = CreateObject("Scripting.Dictionary")
dict.Add "URL", url
dict.Add "Seller", vbNullString
dict.Add "Feedback", vbNullString
dict.Add "Condition", vbNullString
dict.Add "Color", vbNullString
dict.Add "Storage", vbNullString
dict.Add "Price", vbNullString
dict.Add "Headline", vbNullString
Set listings = html.getElementById("section_main").getElementsByClassName("listing_row listing_None listing_None")
ReDim results(1 To listings.Length)
For Each listing In listings
counter = counter + 1
On Error Resume Next
dict("Seller") = listing.querySelector(".text-nowrap").innerText
dict("Feedback") = listing.querySelector("[data-value]").getAttribute("data-value")
dict("Condition") = listing.querySelector(".condition_label").innerText
dict("Color") = listing.querySelector(".color_label").innerText
dict("Storage") = listing.querySelector(".storage_label").innerText
dict("Price") = listing.querySelector(".price").innerText
dict("Headline") = listing.querySelector(".headline.hidden-xs.text-nowrap").innerText
On Error GoTo 0
results(counter) = dict.Items
Set dict = ClearDict(dict)
Next
GetInfo = results
End Function
Public Function ClearDict(ByRef dict As Object) As Object
Dim key As Variant
For Each key In dict
If key <> "URL" Then dict(key) = vbNullString
Next
Set ClearDict = dict
End Function
Ссылка:
- Библиотека объектов Microsoft HTML
- Microsoft Internet Controls