如何使用 Selenium VBA 遍历页面以获取表数据?

问题描述

我有一个包含 1000 个页面的网站,我想从单个工作表中的每个页面中提取表格。我尝试过的事情是将页数放在循环中并提取数据。这样做的问题是它不是自动化的,而是在新工作表中提取每个页面的表格数据。

什么是有效的解决方案,以便网站每个页面的表格提取可以在单张纸上完成,而没有太多延迟,因为有数千个页。 所以我的问题是:

1.如何从网站获取页数,以便我可以在循环中使用它,即 For i = 1 To Numberofpages ?或者除了获取页数之外还有其他方法(例如转到下一页,直到下一页不出现)。

2.如何将每个页面中提取的所有表格放在一个工作表中?

Sub Scrape()

    Dim ResultSections As Selenium.WebElements
    Dim ResultSection As Selenium.WebElement
    Dim i As Long
    
    Set ch = New Selenium.ChromeDriver
    
    ch.Start baseUrl:="http://www.nepalstock.com"
    
    For i = 1 To 3  '3 is number of pages TO BE FOUND which here is taken for Example 
      ch.Get "/main/floorsheet/index/" & i & "/?contract-no=&stock-symbol=&buyer=&seller=&_limit=30"
        Set ResultSections = ch.FindElementsByClass("my-table")
     For Each ResultSection In ResultSections
     ResultSection.AsTable.ToExcel ThisWorkbook.Worksheets.Add.Range("A1")
    Next ResultSection
    Next
    
    End Sub

解决方法

当您写出到工作表时,您需要一种方法来确定最后填充的行,添加您想要的行间距,或者在再次写出之前添加 1 表示没有间距。

如果您不知道哪一列可用于确定最后一行,则使用下面的第一个函数,如果您确实有一列可以依赖,则使用下面的第二个函数并传入适当的列号,例如A 列将为 1。

记得在返回值中加上需要的偏移量:

Public Function GetLastRow(ByVal sh As Worksheet) As Long
    On Error Resume Next
    GetLastRow = sh.Cells.Find(What:="*",_
                            After:=sh.Range("A1"),_
                            Lookat:=xlPart,_
                            LookIn:=xlFormulas,_
                            SearchOrder:=xlByRows,_
                            SearchDirection:=xlPrevious,_
                            MatchCase:=False).row
    On Error GoTo 0
End Function

Public Function GetLastRow(ByVal ws As Worksheet,Optional ByVal columnNumber As Long = 1) As Long

    With ws

      GetLastRow = .Cells(.Rows.Count,columnNumber).End(xlUp).row

    End With

End Function

您将使用如下:

Dim ws As Worksheet

Set ws = ThisWorkbook.Worksheets("Sheet1")

ResultSection.AsTable.ToExcel ws.Cells(GetLastRow(ws,1) + 2,"A") 'leave 1 row gap before writing out next output

'ResultSection.AsTable.ToExcel ws.Cells(GetLastRow(ws) + 2,"A")  'leave 1 row gap before writing out next output

就我个人而言,我通常更喜欢先用结果填充数组,然后一次性写出到工作表。给定指定的页数,失败的风险非常高,而且您还没有实施任何类型的退避重试机制来获取数据。因此,我选择了在循环期间 I/O 昂贵的频繁写入工作表。


计算第一个加载页面的页数:

Dim arr() As String

arr = Split(trim$(ch.FindElementByCss(".pager > a").text),"/")
numberOfPages = arr(ubound(arr))

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...