【问题标题】:Get "href=link" from html page and navigate to that link using vba从 html 页面获取“href=link”并使用 vba 导航到该链接
【发布时间】:2018-07-25 01:20:24
【问题描述】:

我正在 Excel VBA 中编写代码以获取类的 href 值并导航到该 href 链接 (即)这是href 值,我想进入我的特定 Excel 工作表,我想通过我的 VBA 代码自动导航到该链接。

<a href="/questions/51509457/how-to-make-the-word-invisible-when-its-checked-without-js" class="question-hyperlink">How to make the word invisible when it's checked without js</a>

我得到的结果是我能够得到包含标签的类值How to make the word invisible when it's checked without js href 链接/questions/51509457/how-to-make-the-word-invisible-when-its-checked-without-js 这是我想要得到并浏览我的代码的内容。

请帮帮我。提前致谢

下面是整个代码:

Sub useClassnames()
    Dim element As IHTMLElement
    Dim elements As IHTMLElementCollection
    Dim ie As InternetExplorer
    Dim html As HTMLDocument

    'open Internet Explorer in memory, and go to website
    Set ie = New InternetExplorer
    ie.Visible = True
    ie.navigate "https://stackoverflow.com/questions"
    'Wait until IE has loaded the web page

    Do While ie.readyState <> READYSTATE_COMPLETE
        DoEvents
    Loop

    Set html = ie.document
    Set elements = html.getElementsByClassName("question-hyperlink")

    Dim count As Long
    Dim erow As Long
    count = 0

    For Each element In elements
        If element.className = "question-hyperlink" Then
            erow = Sheets("Exec").Cells(Rows.count, 1).End(xlUp).Offset(1, 0).Row
            Sheets("Exec").Cells(erow, 1) = html.getElementsByClassName("question-hyperlink")(count).innerText
            count = count + 1
        End If
    Next element

    Range("H10").Select
End Sub

我在这个网站上找不到任何人问的任何答案。请不要将此问题建议为重复。

<div class="row hoverSensitive">
        <div class="column summary-column summary-column-icon-compact  ">
                                <img src="images/app/run32.png" alt="" width="32" height="32">
                        </div>
        <div class="column summary-column  ">
            <div class="summary-title summary-title-compact text-ppp">
                                        <a href="**index.php?/runs/view/7552**">MMDA</a>

            </div>
            <div class="summary-description-compact text-secondary text-ppp">
                                                                            By on 7/9/2018                                                  </div>
        </div>      
        <div class="column summary-column summary-column-bar  ">
                            <div class="table">
<div class="column">
    <div class="chart-bar ">
                                                                                                                        <div class="chart-bar-custom link-tooltip" tooltip-position="left" style="background: #4dba0f; width: 125px" tooltip-text="100% Passed (11/11 tests)"></div>
                                                                                                                                                                                                                                                                                                                                                                                                            </div>
</div>
    <div class="column chart-bar-percent chart-bar-percent-compact">
    100%'

【问题讨论】:

  • 看起来你有 innerText 你需要 getAttribute("href")
  • 如果我这样做,我不会得到空白单元格
  • 还有其他办法吗?
  • @JeremyKahan 还有其他方法吗。
  • 谁能解释一下下面的代码:

标签: html excel vba internet-explorer web-scraping


【解决方案1】:

方法①

使用 XHR 使用问题主页 URL 发出初始请求;应用 CSS 选择器检索链接,然后将这些链接传递给 IE 以导航到


用于选择元素的 CSS 选择器:

你想要元素的href 属性。你已经得到了一个例子。您可以使用 getAttribute,或者正如 @Santosh 所指出的,将 href 属性 CSS 选择器与其他 CSS 选择器组合以定位元素。

CSS 选择器:

a.question-hyperlink[href]

查找具有question-hyperlink 类和href 属性的父标签a 的元素。

然后,您将 CSS 选择器组合与 documentquerySelectorAll 方法一起应用,以收集链接的节点列表。


XHR 获取初始链接列表:

我会先将它作为 XHR 发布,速度要快得多,然后将您的链接收集到一个集合/nodeList 中,您稍后可以使用您的 IE 浏览器进行循环。

Option Explicit
Public Sub GetLinks()
    Dim sResponse As String, HTML As New HTMLDocument, linkList As Object, i As Long
    Const BASE_URL As String = "https://stackoverflow.com"
    With CreateObject("MSXML2.XMLHTTP")
        .Open "GET", "https://stackoverflow.com/questions", False
        .send
        sResponse = StrConv(.responseBody, vbUnicode)
    End With
    sResponse = Mid$(sResponse, InStr(1, sResponse, "<!DOCTYPE "))

    With HTML
        .body.innerHTML = sResponse
        Set linkList = .querySelectorAll("a.question-hyperlink[href]")
        For i = 0 To linkList.Length - 1
            Debug.Print Replace$(linkList.item(i), "about:", BASE_URL)
        Next i
    End With
    'Code using IE and linkList
End Sub

在上面的linkList 是一个节点列表,其中包含主页中所有匹配的元素,即问题登录页面上的所有hrefs。您可以循环nodeList.Length 并对其进行索引以检索特定的href,例如链接列表.item(i)。由于返回的链接是相对的,您需要将路径的相对about: 部分替换为协议+域,即"https://stackoverflow.com"

现在您已经快速获得了该列表,并且可以访问项目,您可以将任何给定的更新href 传递给IE.Navigate


使用 IE 和 nodeList 导航到问题

For i = 0 To linkList.Length - 1
    IE.Navigate Replace$(linkList.item(i).getAttribute("href"), "about:", BASE_URL)
Next i

方法②

使用 XHR 使用 GET 请求发出初始请求并搜索问题标题;应用 CSS 选择器检索链接,然后将这些链接传递给 IE 进行导航。


Option Explicit
Public Sub GetLinks()
    Dim sResponse As String, HTML As New HTMLDocument, linkList As Object, i As Long
    Const BASE_URL As String = "https://stackoverflow.com"
    Const TARGET_QUESTION As String = "How to make the word invisible when it's checked without js"
    With CreateObject("MSXML2.XMLHTTP")
        .Open "GET", "https://stackoverflow.com/search?q=" & URLEncode(TARGET_QUESTION), False
        .send
        sResponse = StrConv(.responseBody, vbUnicode)
    End With
    sResponse = Mid$(sResponse, InStr(1, sResponse, "<!DOCTYPE "))

    With HTML
        .body.innerHTML = sResponse
        Set linkList = .querySelectorAll("a.question-hyperlink[href]")
        For i = 0 To linkList.Length - 1
            Debug.Print Replace$(linkList.item(i).getAttribute("href"), "about:", BASE_URL)
        Next i
    End With
    If linkList Is Nothing Then Exit Sub
    'Code using IE and linkList
End Sub

'https://stackoverflow.com/questions/218181/how-can-i-url-encode-a-string-in-excel-vba   @Tomalak
Public Function URLEncode( _
   StringVal As String, _
   Optional SpaceAsPlus As Boolean = False _
) As String

  Dim StringLen As Long: StringLen = Len(StringVal)

  If StringLen > 0 Then
    ReDim result(StringLen) As String
    Dim i As Long, CharCode As Integer
    Dim Char As String, Space As String

    If SpaceAsPlus Then Space = "+" Else Space = "%20"

    For i = 1 To StringLen
      Char = Mid$(StringVal, i, 1)
      CharCode = Asc(Char)
      Select Case CharCode
        Case 97 To 122, 65 To 90, 48 To 57, 45, 46, 95, 126
          result(i) = Char
        Case 32
          result(i) = Space
        Case 0 To 15
          result(i) = "%0" & Hex(CharCode)
        Case Else
          result(i) = "%" & Hex(CharCode)
      End Select
    Next i
    URLEncode = Join(result, "")
  End If
End Function

【讨论】:

  • 为了避免.getAttribute("href")在for循环中使用.querySelectorAll("a.question-hyperlink[href]")
  • 不是真的一旦你改变了,可以使用Debug.Print linkList(i)访问值
  • 这回答了你的问题@MDI 吗?
【解决方案2】:
  1. 这个If element.className = "question-hyperlink" Then 是没用的,因为它总是正确的,因为你getElementsByClassName("question-hyperlink") 所以所有元素肯定都属于question-hyperlink 类。 If 语句可以删除。

  2. 您在变量element 中有每个链接,因此您不需要count。而不是html.getElementsByClassName("question-hyperlink")(count).innerText 使用element.innerText

所以它应该是这样的:

Set elements = html.getElementsByClassName("question-hyperlink")
Dim erow As Long

For Each element In elements
    erow = Worksheets("Exec").Cells(Rows.count, 1).End(xlUp).Offset(1, 0).Row
    Worksheets("Exec").Cells(erow, 1) = element.innerText
    Worksheets("Exec").Cells(erow, 2) = element.GetAttribute("href") 'this should give you the URL
Next element

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-06-05
    • 2020-09-07
    • 2011-03-05
    • 2021-04-19
    • 1970-01-01
    • 2014-08-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多