【问题标题】:Unable to reuse the same driver between two subs无法在两个潜艇之间重用相同的驱动程序
【发布时间】:2019-03-16 06:54:29
【问题描述】:

我创建了一个宏,使用 selenium 从网站获取不同帖子的链接,并在导航到目标页面后解析每个帖子的标题。我的第一个示例只是按预期完成了使用单个 sub 编写的操作。

我想使用两个 subs 修改我的宏,并在两个 subs 之间重用相同的驱动程序,就像我在第二个示例中尝试的那样。

工作一个(使用单个子):

Sub FetchLinks()
    Const link$ = "https://stackoverflow.com/questions/tagged/web-scraping"
    Dim driver As New ChromeDriver, post As Object
    Dim itmLink As Variant, R&, iDic As Object
    Set iDic = CreateObject("Scripting.Dictionary")

    With driver
        .get link
        For Each post In .FindElementsByCss(".summary .question-hyperlink", timeout:=10000)
            iDic(post.Attribute("href")) = 1
        Next post

        For Each itmLink In iDic.keys
            driver.get itmLink
            Debug.Print .FindElementByCss("h1 > a.question-hyperlink").Text
        Next itmLink
    End With
End Sub

无法使其工作(试图在另一个子系统中传递驱动程序以重用它):

Sub FetchLinks()
    Const link$ = "https://stackoverflow.com/questions/tagged/web-scraping"
    Dim driver As New ChromeDriver, post As Object

    With driver
        .get link
        For Each post In .FindElementsByCss(".summary .question-hyperlink", timeout:=10000)
            FetchData driver, post.Attribute("href")
        Next post
    End With
End Sub

Sub FetchData(ByRef driver, ByRef nlink As String)
    Dim elem As Object

    With driver
        .get nlink
        Debug.Print .FindElementByCss("h1 > a.question-hyperlink").Text
    End With
End Sub

如何在两个订阅者之间共享 chromedriver 以便从内页抓取一些内容?

【问题讨论】:

    标签: vba selenium web-scraping


    【解决方案1】:

    您将获得一个过时的元素引用,因为您正在离开着陆页的内部子页面。然后,您尝试在外循环中继续引用此页面。将链接放入字典并循环。另外,请通过ByVal

    Option Explicit
    
    Public Sub FetchLinks()
        Const link$ = "https://stackoverflow.com/questions/tagged/web-scraping"
        Dim driver As ChromeDriver, post As Object, key As Variant
        Dim dict As Object
        Set dict = CreateObject("Scripting.Dictionary"): Set driver = New ChromeDriver
        With driver
            .get link
    
            For Each post In .FindElementsByCss(".summary .question-hyperlink", timeOut:=10000)
                dict(post.Attribute("href")) = 1
            Next
            For Each key In dict.keys
                FetchData driver, key
            Next key
        End With
    End Sub
    
    Public Sub FetchData(ByVal driver As ChromeDriver, ByVal nlink As String)
        With driver
            .get nlink
            Debug.Print .FindElementByCss("h1 > a.question-hyperlink").Text
        End With
    End Sub
    

    【讨论】:

    • 是的,它以正确的方式工作。我对此有两个快速的问题(非常小)。 1.当你使用这个ByVal driver时,它是否作为一个变体工作? 2. 为什么你使用 byval 而不是 byref?我可以理解nlinklink 不同,因此您使用了byval 但driver 在两个潜艇中都相同,那么为什么ByVal driver?总是很高兴在循环中找到您。再次感谢。
    • 我使用 ByVal 是因为您不会更改被调用子程序中任一变量的值,而且我只是忘记为驱动程序输入数据类型(我的错误)。它会被隐式称为变体,但我猜它也可以作为显式输入的 Chromedriver。
    • 我已更新为作为 ChromeDriver 而不是变体传递。
    • 所以,像ByVal driver As ChromeDriver这样使用时,不需要再次实例化chromedriver,对吧?我问了太多问题,因为我从来没有学过基础知识。
    • 不,它不需要实例化。如果您注意到我将您的自动实例化更改为显式实例化。别担心,ByVal 和 ByRef /Pointers 是我的弱项。我通常会问ducks - 他们是大师。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-20
    • 2014-09-12
    • 1970-01-01
    • 2022-01-13
    • 2017-10-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多