将同一个 Http 从 sub 传递到函数后无法重用
Trouble reusing the same Http after passing it from a sub to a function
我已经使用 xhr 编写了一个脚本来从这个 website 中解析第一个 post 的 link 然后传递 link
和 http
到函数以从其内页获取标题。 重要的是我将 link
和 http
都传递给函数,以便重用我最初使用的相同 http.
我的脚本似乎以正确的方式工作,但我不确定我是否以正确的方式完成了整个事情。我困惑的原因是我在使用 like getHTTP(ByVal Http, ByVal link) As Variant
时得到了结果。当我选择 getHTTP(ByVal Http, ByVal link) As String
或 getHTTP(ByVal Http, ByVal link)
时,我什至得到了结果。此外,我没有在函数参数中明确定义 link as String
或 Http 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://whosebug.com"
Const Url$ = "https://whosebug.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
What is the right way to pass http between sub and function in order to reuse the same http?
像这样的东西可能是合适的:
Sub GetInfo()
Const base As String = "https://whosebug.com"
Const url As String = "https://whosebug.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
以上假设 "happy path" 所以可能会受益于一些异常处理...
像下面这样的东西应该可以实现你想要实现的目标:
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://whosebug.com"
Const Url$ = "https://whosebug.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
如果我正确理解了您的问题,并且您需要对函数中的 http 实例进行更改以传递给您的调用子程序,那么传递 http ByRef 就足够了。传递变量 ByRef 会将函数中对 http 实例所做的更改传递给子函数,以便在函数外部使用。所以在函数中对http所做的修改会传递给sub,不会丢失。您将在这两个地方使用相同的 http 对象实例。传递 http ByVal 不会将函数中对 http 所做的更改传递给 sub。如下更改您的函数参数声明。
Function getHTTP(ByRef Http, ByVal link) As Variant
我已经使用 xhr 编写了一个脚本来从这个 website 中解析第一个 post 的 link 然后传递 link
和 http
到函数以从其内页获取标题。 重要的是我将 link
和 http
都传递给函数,以便重用我最初使用的相同 http.
我的脚本似乎以正确的方式工作,但我不确定我是否以正确的方式完成了整个事情。我困惑的原因是我在使用 like getHTTP(ByVal Http, ByVal link) As Variant
时得到了结果。当我选择 getHTTP(ByVal Http, ByVal link) As String
或 getHTTP(ByVal Http, ByVal link)
时,我什至得到了结果。此外,我没有在函数参数中明确定义 link as String
或 Http 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://whosebug.com"
Const Url$ = "https://whosebug.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
What is the right way to pass http between sub and function in order to reuse the same http?
像这样的东西可能是合适的:
Sub GetInfo()
Const base As String = "https://whosebug.com"
Const url As String = "https://whosebug.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
以上假设 "happy path" 所以可能会受益于一些异常处理...
像下面这样的东西应该可以实现你想要实现的目标:
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://whosebug.com"
Const Url$ = "https://whosebug.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
如果我正确理解了您的问题,并且您需要对函数中的 http 实例进行更改以传递给您的调用子程序,那么传递 http ByRef 就足够了。传递变量 ByRef 会将函数中对 http 实例所做的更改传递给子函数,以便在函数外部使用。所以在函数中对http所做的修改会传递给sub,不会丢失。您将在这两个地方使用相同的 http 对象实例。传递 http ByVal 不会将函数中对 http 所做的更改传递给 sub。如下更改您的函数参数声明。
Function getHTTP(ByRef Http, ByVal link) As Variant