【问题标题】:Cannot get the text inside a <p> tag using VBA无法使用 VBA 获取 <p> 标记内的文本
【发布时间】:2019-06-15 03:48:19
【问题描述】:

我有以下网址

https://www.wavemotion.gr/shop/smartphone-accessories/easy-one-touch-wireless-fast-charging-mount

我正在尝试通过以下方式获取产品的可用性

For i = 2 To lastrow

mylink = wks.Cells(i, 2).Value

ie.Navigate mylink

While ie.Busy Or ie.ReadyState < 4: DoEvents: Wend
t = Timer
Do
    DoEvents
    On Error Resume Next

    Set instock = ie.Document.querySelector(".stock.in-stock").innerText

    If instock Is Nothing Then
    Set availability = ie.Document.querySelector(".stock.out-of-stock").innerText
    Else
    Set availability = instock
    End If

    wks.Cells(i, "D") = availability


    If Timer - t > MAX_WAIT_SEC Then Exit Do
    On Error GoTo 0
Loop

Next i

但我总是在

上得到什么都没有
Set instock = ie.Document.querySelector(".stock.in-stock").innerText

我检查了查询

https://try.jsoup.org/

它正在工作

我在这里做错了什么?没有任何 id 只针对类名

<p class="stock in-stock">Διαθέσιμο</p>

【问题讨论】:

    标签: excel vba web-scraping


    【解决方案1】:

    所以,这里发生的事情是您尝试将Set 字符串数据类型innerText 转换为对象变量instock。它返回 Nothing 的原因是因为您的 On Error Resume Next 语句正在抑制错误消息。如果你把它拿出来运行它,你会得到一个Type Mismatch。您需要做的是将其拆分为将对象分配给对象变量的一行,然后是读取分配对象的innerText 的行。

    Set instock = ie.Document.querySelector(".stock.in-stock")
    
    If instock Is Nothing Then
        Set availability = ie.Document.querySelector(".stock.out-of-stock")
    Else
        Set availability = instock
    End If
    
    wks.Cells(i, "D") = availability.innerText
    

    【讨论】:

      【解决方案2】:

      有一种更好、更快的方法。使用 xmlhttp 并从存储在脚本标签之一中的 json 中解析出该信息。如果发出大量请求,您可能需要每 x 个请求添加一次等待,以防出现限制/阻塞。注意:您可以对 InternetExplorer 使用相同的方法,从而删除许多代码行,尽管您有另一个库 (.bas) 依赖项。

      您需要从here 安装 jsonconverter.bas 并转到 vbe > tools > references > 并添加对 Microsoft Scripting Runtime 的引用

      Option Explicit
      Public Sub GetStocking()
          Dim json As Object, html As HTMLDocument
          Set html = New HTMLDocument
          With CreateObject("MSXML2.XMLHTTP")
              .Open "GET", "https://www.wavemotion.gr/shop/smartphone-accessories/easy-one-touch-wireless-fast-charging-mount", False
              .send
              html.body.innerHTML = StrConv(.responseBody, vbUnicode)
          End With
      
          Set json = JsonConverter.ParseJson(html.querySelector("script[type='application/ld+json']").innerHTML)
      
          Debug.Print json("offers")("availability")
      End Sub
      

      这是整个 json 包含的内容:


      Internet Explorer 版本:

      Option Explicit
      Public Sub GetInfo()
          Dim ie As New InternetExplorer, i As Long, s As String, scripts As Object, json As Object
          With ie
              .Visible = False
              .Navigate2 "https://www.wavemotion.gr/shop/smartphone-accessories/easy-one-touch-wireless-fast-charging-mount"
      
              While .Busy Or .readyState < 4: DoEvents: Wend
      
              Set scripts = .document.querySelectorAll("script[type='application/ld+json']")
      
              For i = 0 To scripts.Length - 1
                  s = scripts.item(i).innerHTML
                  If InStr(s, "availability") > 0 Then
                      Set json = JsonConverter.ParseJson(s)
                      Exit For
                  End If
              Next
              .Quit
              If Not json Is Nothing Then Debug.Print json("offers")("availability")
          End With
      End Sub
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-02-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-29
        相关资源
        最近更新 更多