【问题标题】:VBA WebScraping Script Returns Subscript OutOf RangeVBA Web Scraping 脚本返回超出范围的下标
【发布时间】:2019-07-28 00:40:40
【问题描述】:

问题:

我一直在尝试从网站上抓取数据,但它总是给我一个错误 Subscript OutOf Range。我不知道为什么。我在另一个网站上使用完全相同的代码,它工作得非常好。

是的,我已将 divs 更改为我想从中抓取的新网站。

代码:

Option Explicit
Public Sub Loiça()
    Dim data As Object, i As Long, html As HTMLDocument, r As Long, c As Long, item As Object, div As Object
    Set html = New HTMLDocument                  '<== VBE > Tools > References > Microsoft HTML Object Library

    Const START_URL As String = "https://mediamarkt.pt/pages/search-results-page?q=maquina+roupa&page=1"

    With CreateObject("MSXML2.XMLHTTP")
        .Open "GET", START_URL, False
        .setRequestHeader "User-Agent", "Mozilla/5.0"
        .send
        html.body.innerHTML = .responseText
        Dim numPages As Long, numResults As Long, arr() As String
        arr = Split(html.querySelector(".snize-search-results-header").innerText, Chr$(32))
        numResults = arr(UBound(arr))
        numPages = 1


        For i = 1 To numPages
             If i > 1 Then
                .Open "GET", Replace$("https://mediamarkt.pt/pages/search-results-page?q=maquina+roupa&page=1", "page=1", "page=" & i), False
                .setRequestHeader "User-Agent", "Mozilla/5.0"
                .send
                 html.body.innerHTML = .responseText
            End If
            Set data = html.getElementsByClassName("snize-four-columns")
            For Each item In data
                r = r + 1: c = 1
                For Each div In item.getElementsByTagName("div")
                    With ThisWorkbook.Worksheets("Loiça")
                        .Cells(r, c) = div.innerText
                    End With
                    c = c + 1
                Next
            Next
        Next
    End With
    '----------------------------------------------------------------------------------------------------------------------------------------------------------------------'
End Sub

【问题讨论】:

  • 错误出现在哪一行?
  • @QHarr 错误发生在第 15 行 numResults = arr(UBound(arr))

标签: excel vba web-scraping screen-scraping


【解决方案1】:

这个

html.querySelector(".snize-search-results-header").innerText

返回一个空字符串,因此当您拆分时,您的 arr 中会出现 -1。

这个值可能需要 javascript 才能在页面上运行。检查返回的 html。我认为没有返回任何价值。使用 selenium 或 IE 之类的方法,让 js 在页面上运行并使用值更新内容

在这种情况下,你还需要 lbound,这样你就可以使用一个函数来返回使用 IE 的值

numPages  =  GetNumberOfPages 

Public Function GetNumberOfPages() As Long
    Dim IE As New InternetExplorer
    With IE
        .Visible = False
        .Navigate2 "https://mediamarkt.pt/pages/search-results-page?q=maquina+roupa&page=1"

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

        Dim numPages As Long, numResults As Long, arr() As String
        arr = Split(.document.querySelector(".snize-search-results-header").innerText, Chr$(32))
        numResults = arr(LBound(arr))
        GetNumberOfPages =  numResults
        .Quit
    End With
End Function

对于下一页,您正在查看不同的类名(我认为)

Set data = html.getElementsByClassName("snize-product")

检查 html 以进行验证。

【讨论】:

  • 使用 IE 意味着将 .setRequestHeader "User-Agent", "Mozilla/5.0" 更改为 .setRequestHeader "User-Agent", "internetexplorer.application",因为我也已经尝试过了:/
  • 不,我的意思是根据我上面的编辑。您始终可以将原始 xmlhttp 的响应写入文件并进行检查。我不认为你的价值在那里,但我不能在这里测试。我建议使用像上面这样的函数来使用 IE/Selenium 获取 numPages,然后像之前一样继续使用 xmlhttp,假设在这些请求的 .responseText 中返回了所需的数据。
  • 我现在能够得到 numResults,谢谢,现在我只需要弄清楚如何将值报废到工作表中。
  • 你需要循环类名为 snize-product 的元素
  • 是的,我知道,现在它没有给我任何错误,我检查了numResults 的值,它完全正确!现在唯一的问题是它没有将任何结果抓取到 excel 中:/
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多