如何使用 Selenium VBA 遍历页面以获取 Table 数据?
How to loop over the pages to get Table data using Selenium VBA?
我有一个有 1000 个页面的网站,我想在单个工作sheet 中从每个页面中提取 tables。我尝试过的事情是将页数放在循环中并提取数据。问题在于它不是自动化的,它会在新工作sheet.
中提取每个页面的 table 数据
什么是有效的解决方案,这样 table 网站每个页面的提取都可以 在单个 sheet 没有太多延迟,因为有数千页。
所以我的问题是:
1.How 从网站获取页数,以便我可以在循环中使用它,即 For i = 1 To Numberofpages
?或者除了获取页数之外还有其他方法吗(例如转到下一页直到下一页不出现)。
2.How 将从每页提取的所有内容 table 放在单个作品中 sheet ?
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
当您写到 sheet 时,您需要一种方法来确定最后填充的行,在再次写出之前添加您想要的行间距,或者添加 1 表示没有间距。
如果您不知道哪一列可用于确定最后一行,则使用下面的第一个函数,如果您确实有可以依赖的列,则使用下面的第二个函数并传入适当的列号码例如A 列为 1.
记得在 return 值中添加所需的偏移量:
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
就个人而言,我通常更喜欢先用结果填充一个数组,然后一次性写入 sheet。给定指定的页数,出现故障的风险非常高,并且您尚未实施任何类型的退避重试机制来获取数据。因此,我选择了 I/O 昂贵的频繁写入工作 sheet 在你的循环中。
计算第一个加载页面的页数:
Dim arr() As String
arr = Split(trim$(ch.FindElementByCss(".pager > a").text),"/")
numberOfPages = arr(ubound(arr))
我有一个有 1000 个页面的网站,我想在单个工作sheet 中从每个页面中提取 tables。我尝试过的事情是将页数放在循环中并提取数据。问题在于它不是自动化的,它会在新工作sheet.
中提取每个页面的 table 数据什么是有效的解决方案,这样 table 网站每个页面的提取都可以 在单个 sheet 没有太多延迟,因为有数千页。 所以我的问题是:
1.How 从网站获取页数,以便我可以在循环中使用它,即 For i = 1 To Numberofpages
?或者除了获取页数之外还有其他方法吗(例如转到下一页直到下一页不出现)。
2.How 将从每页提取的所有内容 table 放在单个作品中 sheet ?
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
当您写到 sheet 时,您需要一种方法来确定最后填充的行,在再次写出之前添加您想要的行间距,或者添加 1 表示没有间距。
如果您不知道哪一列可用于确定最后一行,则使用下面的第一个函数,如果您确实有可以依赖的列,则使用下面的第二个函数并传入适当的列号码例如A 列为 1.
记得在 return 值中添加所需的偏移量:
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
就个人而言,我通常更喜欢先用结果填充一个数组,然后一次性写入 sheet。给定指定的页数,出现故障的风险非常高,并且您尚未实施任何类型的退避重试机制来获取数据。因此,我选择了 I/O 昂贵的频繁写入工作 sheet 在你的循环中。
计算第一个加载页面的页数:
Dim arr() As String
arr = Split(trim$(ch.FindElementByCss(".pager > a").text),"/")
numberOfPages = arr(ubound(arr))