【问题标题】:VBA: Web scraping with <ul and <li and <div and <spanVBA:使用 <ul 和 <li 以及 <div 和 <span 进行网页抓取
【发布时间】:2019-11-29 11:32:45
【问题描述】:

我正在使用 VBA 从&lt;span 代码中的 HTML 中提取数据,该代码位于 &lt;Div 下方,位于 &lt;li 下方,位于 &lt;ul 下方

我正在尝试从 HTML 中提取“日期和事项”。 Excel中“日期”应在A列中,“事项”应在B列中。

我的代码的缺点是,它将所有 Datematter 拉到单个单元格中。

Sub GetDat()
    Dim IE As New InternetExplorer, html As HTMLDocument
    Dim elem As Object, data As String

    With IE
        .Visible = True
        .navigate "https://www.MyURL/sc/wo/Worders/index?id=76888564"
        Do While .readyState <> READYSTATE_COMPLETE: Loop
        Set html = .document
    End With

    data = ""

    For Each elem In html.getElementsByClassName("simple-list")(0).getElementsByTagName("li")
        data = data & " " & elem.innerText
    Next elem

    Range("A1").Value = data

    IE.Quit
End Sub

我需要的输出如图所示:

HTML:

【问题讨论】:

    标签: html excel vba web-scraping


    【解决方案1】:

    您可以获取两个节点列表,一个用于日期,一个用于事务,然后将这些内容循环到工作表中。根据data-bind属性值匹配datesmatters classname:

    Dim dates As Object, matters As Object, i As Long, ws As Worksheet
    
    Set ws = ThisWorkbook.Worksheets("Sheet1")
    Set dates = ie.document.querySelectorAll("[data-bind^='text:createdDate']") '.wo-notes-col-1 [data-bind^='text:createdDate']
    Set matters = ie.document.querySelectorAll(".wo-notes")
    
    With ws
    
        For i = 0 To dates.Length - 1
            .Cells(i + 1, 1) = dates.Item(i).innertext
            .Cells(i + 1, 2) = matters.Item(i).innertext
        Next
    
    End With
    

    从 C 列读取值的示例:

    Option Explicit
    
    Public Sub GetMatters()
        Dim ws As Worksheet, lastRow As Long, urls(), results(), ie As SHDocVw.InternetExplorer, r As Long
    
        Set ie = New SHDocVw.InternetExplorer
        Set ws = ThisWorkbook.Worksheets("Sheet1")
        lastRow = ws.Cells(ws.Rows.Count, "C").End(xlUp).Row
        urls = Application.Transpose(ws.Range("C2:C" & lastRow).Value)
        ReDim results(1 To 1000, 1 To 2)
    
        With ie
            .Visible = True
    
            For i = LBound(urls) To UBound(urls)
                .navigate2 "https://www.MyURL/sc/wo/Worders/index?id=" & urls(i)
                While .Busy Or .readyState <> 4: DoEvents: Wend
    
                Dim dates As Object, matters As Object, i As Long
    
                Set dates = .document.querySelectorAll("[data-bind^='text:createdDate']") '.wo-notes-col-1 [data-bind^='text:createdDate']
                Set matters = .document.querySelectorAll(".wo-notes")
    
                For i = 0 To dates.Length - 1
                    r = r + 1
                    results(r, 1) = dates.Item(i).innertext
                    results(r, 2) = matters.Item(i).innertext
                Next
                Set dates = Nothing: Set matter = dates
            Next
            .Quit
        End With
    
        ws.Cells(2, 1).Resize(UBound(results, 1), UBound(results, 2)) = results
    End Sub
    

    参考资料:

    1. document.querySelectorAll
    2. css selectors

    【讨论】:

    • 感谢 QHarr,花一些时间来解决我的问题。你能帮我循环几次代码吗?
    • 多次循环代码是什么意思?上面写出的表格是否如预期的那样?
    • 表示我在 URL 76888564 中提到的数字将改变频率。这意味着我需要使用这个宏来处理多个数字(WorkOrders)。是否可以循环多个工作订单。造成不便,敬请见谅。谢谢
    • 这些新结果将用于不同的工单?
    • 您想要一个类似于此处所示结构的循环:stackoverflow.com/a/57234600/6241235
    猜你喜欢
    • 1970-01-01
    • 2016-09-12
    • 1970-01-01
    • 2022-07-01
    • 2020-11-30
    • 1970-01-01
    • 1970-01-01
    • 2018-06-28
    • 2018-10-23
    相关资源
    最近更新 更多