0

我使用 xhr 编写了一个脚本来解析来自该网站的第一篇文章的链接,然后将link和传递http给一个函数以从它的内页获取标题。重要的是我将 thelink和 the都传递http给函数,以便重用我一开始使用的相同 http

我的脚本似乎以正确的方式工作,但我不确定我是否以正确的方式完成了整个事情。我感到困惑的原因是当我使用 like 时我得到了结果getHTTP(ByVal Http, ByVal link) As Variant。当我选择getHTTP(ByVal Http, ByVal link) As Stringor时,我什至得到了结果getHTTP(ByVal Http, ByVal link)。此外,我没有明确定义link as StringHttp as XMLHTTP60在函数参数内。

我试过(完美地工作):

Function getHTTP(ByVal Http, ByVal link) As Variant
    Dim Html As New HTMLDocument, oTitle$
    
    With Http
        .Open "GET", link, False
        .send
        Html.body.innerHTML = .responseText
        oTitle = Html.querySelector("h1[itemprop='name'] > a").innerText
        getHTTP = oTitle
    End With
End Function

Sub GetInfo()
    Const base$ = "https://stackoverflow.com"
    Const Url$ = "https://stackoverflow.com/questions/tagged/web-scraping"
    Dim Http As New XMLHTTP60, Html As New HTMLDocument
    Dim firstLink$, postTitle$

    With Http
        .Open "GET", Url, False
        .send
        Html.body.innerHTML = .responseText
        firstLink = base & Replace(Html.querySelector(".summary .question-hyperlink").getAttribute("href"), "about:", "")
        postTitle = getHTTP(Http, firstLink)
        MsgBox postTitle
    End With
End Sub

为了重用相同的http,在子和函数之间传递http的正确方法是什么?

4

3 回答 3

1

这样的事情可能是合适的:

Sub GetInfo()

    Const base As String = "https://stackoverflow.com"
    Const url As String = "https://stackoverflow.com/questions/tagged/web-scraping"
    Dim Html As HTMLDocument
    Dim firstLink As String, postTitle As String

    firstLink = base & Replace(GetPage(url).querySelector(".summary .question-hyperlink") _
                .getAttribute("href"), "about:", "")
    Debug.Print firstLink

    postTitle = GetPage(firstLink).querySelector("h1[itemprop='name'] > a").innerText
    Debug.Print postTitle

End Sub

Function GetPage(url As String) As HTMLDocument
    Dim Html As HTMLDocument
    Static Http As XMLHTTP60

    If Http Is Nothing Then
        Set Http = New XMLHTTP60
        'log in here
    End If

    With Http
        .Open "GET", url, False
        .send
        If .Status = 200 Then
            Set Html = New HTMLDocument
            Html.body.innerHTML = .responseText
        Else
            Debug.Print .Status
            'warn user
        End If
    End With
    Set GetPage = Html
End Function

最重要的是假设“幸福的道路”,所以可能会从一些异常处理中受益......

于 2020-05-08T17:10:37.970 回答
1

类似以下内容应该可以实现您想要实现的目标:

Function getHTTP(ByVal Http, link) As String
    With Http
        .Open "GET", link, False
        .send
        getHTTP = .responseText
    End With
End Function

Sub GetInfo()
    Const base$ = "https://stackoverflow.com"
    Const Url$ = "https://stackoverflow.com/questions/tagged/web-scraping"
    Dim Http As Object, Html As New HTMLDocument
    Dim firstLink$
    
    Set Http = CreateObject("MSXML2.XMLHTTP")

    Html.body.innerHTML = getHTTP(Http, Url)
    firstLink = base & Replace(Html.querySelector(".summary .question-hyperlink").getAttribute("href"), "about:", "")
    
    Html.body.innerHTML = getHTTP(Http, firstLink)
    MsgBox Html.querySelector("h1[itemprop='name'] > a").innerText
End Sub
于 2021-01-04T07:36:40.383 回答
0

如果我正确理解了您的问题并且您需要对函数中的 http 实例进行更改以传递给您的调用子,那么传递 http ByRef就足够了。传递变量 ByRef 会将函数中对 http 实例所做的更改传递给子函数,以便在函数外部使用。所以函数中对http所做的修改会传递给sub,不会丢失。您将在两个地方使用相同的 http 对象实例。传递 http ByVal 不会将函数中对 http 所做的更改传递给子。如下更改您的函数参数声明。

    Function getHTTP(ByRef Http, ByVal link) As Variant
于 2021-01-09T10:23:24.400 回答