使用VBA Selenium Webdriver刮擦表,但是速度太慢

时间:2019-09-10 09:18:09

标签: excel vba selenium web-scraping

我在VBA中使用Selenium Web驱动程序来刮擦表,但实际使用起来太慢了。我需要对VBA代码进行一些改进才能真正使用它。

我一直在该特定网站上使用IE自动化。复制整个HTML表并将其粘贴是一个非常快速的过程。但是,由于该网站确实发生了一些变化,因此我无法再在该网站上使用IE。 因此,我尝试设置一个硒Web驱动程序,并使用Chrome刮擦同一张桌子。由于无法复制整个表(因为我不知道如何复制),因此我必须写下“ for each”语句以对表的每个单元格重复复制和粘贴过程。不幸的是,这样做使每个单元花费了将近半秒,这使它有点无法使用。 我编写的代码确实有效,但是正如我提到的那样,它的速度要慢一些。我可能会将目标表分配为Web元素或其他内容,以加快此过程。 (我尝试并失败了) 在我看来,使Web驱动程序搜索网站的每个“针对每个语句”的操作都减慢了整个过程的速度,但我不确定。

Sub NewSeleniumScraper(ByVal metricname, ByVal metricDate, Optional testval As String)


Dim WD As New Selenium.WebDriver
Dim Chrome As Object
Dim ws As Worksheet
Dim sheetsname As String
Lastrow = ws.Range("A1").CurrentRegion.Rows.Count


For Each tr In WD.FindElementByClass("table-wrap").FindElementByTag("tbody").FindElementsByTag("tr")
    c = 1
        For Each td In tr.FindElementsByTag("td")
            ws.Cells(Lastrow + r, c).Value = td.Text
            c = c + 1
        Next td
    r = r + 1
Next tr

我编写的代码将每个值复制到搜索表中,并将其逐个粘贴到工作表的最后一行下方。我想加快此过程,因为当前每个单元格大约需要0.5秒,因此复制表需要一个小时的时间。

这是表格的结构。

(都是类名)

"table-wrap"
"theader", "tbody"
many "tr" (for each row)
many "td" (for each cell in the row)

我需要抓的是td的值。

2 个答案:

答案 0 :(得分:0)

这需要很长时间,因为您正在遍历表的所有元素,并且显然该表中有很多元素。您不仅可以打开宏记录器,导航到要从中导入数据的页面,单击指向所需表的对象,然后一次导入所有数据吗?完成后,您将拥有所需的所有代码。尝试一下,看看你的生活如何。

答案 1 :(得分:0)

谢谢大家的评论,对我有很大帮助。 我对代码进行了几处更改

  1. 我无法将所有行“设置”为元素(不确定是 正确的词)

我发现您不需要“模糊”网络元素。我删除了“暗淡” 语句,然后仅对Web元素添加“设置”语句。 (我不确定这是否会加快流程)

  1. 我无法用表中的值填充数组。

我现在知道,您应该将数组“ redim”作为具有固定大小的2D数组,但是失败了,因为我试图填充动态1D数组,就好像它是2D数组。

下面是新代码。

Set trs = WD.FindElementByClass("table-wrap").FindElementByTag("tbody").FindElementsByTag("tr")

rcount = trs.Count
ccount = trs(1).FindElementsByTag("td").Count
ReDim Preserve dataArray(1 To rcount, 1 To ccount)



r = 1
For Each tr In trs

    c = 1

    Set tds = tr.FindElementsByTag("td")

        For Each td In tds
            dataArray(r, c) = td.Text
            c = c + 1
        Next td
    r = r + 1
Next tr


Range(Cells(Lastrow + 1, 1), Cells(Lastrow + rcount, ccount)).Value = dataArray

我希望这对与我类似的人有所帮助。