Vba Can';t在没有";的情况下执行我的代码;“错误时继续下一步”;

Vba Can';t在没有";的情况下执行我的代码;“错误时继续下一步”;,vba,selenium,web-scraping,Vba,Selenium,Web Scraping,在VBA中结合selenium编写一个爬虫程序来解析网页中不同产品的价格,我在执行时遇到了一个问题。当它发现某些价格为零时,它就会崩溃。使用“错误恢复下一步”,我可以得到完整的结果。但是,我希望执行代码时不使用“on error resume next”。如果没有硒元素,我可以使用长度属性来消除它。但是,硒并不支持这一点。希望我能在这里找到解决办法 Sub Redmart_scraping() Dim driver As New ChromeDriver Dim posts As Object,

在VBA中结合selenium编写一个爬虫程序来解析网页中不同产品的价格,我在执行时遇到了一个问题。当它发现某些价格为零时,它就会崩溃。使用“错误恢复下一步”,我可以得到完整的结果。但是,我希望执行代码时不使用“on error resume next”。如果没有硒元素,我可以使用长度属性来消除它。但是,硒并不支持这一点。希望我能在这里找到解决办法

Sub Redmart_scraping()
Dim driver As New ChromeDriver
Dim posts As Object, post As Object

With driver
    .get "https://redmart.com/bakery"
    Set posts = .FindElementsByCss("li.productPreview")
End With

On Error Resume Next

For Each post In posts
    i = i + 1
    Cells(i, 1) = post.FindElementByCss("span[class^=ProductPrice__price]").Text
Next post
End Sub
由来已久的“空指针”讨厌。检查空值很重要。有一个更好的方法可以做到这一点,但你明白了(双关语)


由来已久的“空指针”讨厌。检查空值很重要。有一个更好的方法可以做到这一点,但你得到了要点(双关语)

下一步错误恢复
只需跳过任何运行时错误-你不想在一般情况下应用这一点是正确的

如果您无法从一开始就防止这些错误的发生(例如,通过测试
null
),您应该在错误恢复时激活
,然后只为实际可能产生这些错误的代码部分激活
,然后立即用
错误转到0

在这些
On Error
块中,您还可以使用
Err
对象显式测试发生了哪些错误(因此将被忽略)。通过这种方式,您可以重新引发所有未预料到的错误,并且只忽略那些您预料到的错误。 注意:引发错误必须在
On error
块之外进行,但离开该块将重置
Err
对象。因此,您必须将所有必要的错误信息保存在另一个变量(或多个变量)中,以便在离开
On error
块后访问它


我担心VBA提供的错误处理的总体设计混乱,没有更好的方法。

在错误恢复下一步
只跳过任何运行时错误-您不想在一般情况下应用这一点是正确的

如果您无法从一开始就防止这些错误的发生(例如,通过测试
null
),您应该在错误恢复时激活
,然后只为实际可能产生这些错误的代码部分激活
,然后立即用
错误转到0

在这些
On Error
块中,您还可以使用
Err
对象显式测试发生了哪些错误(因此将被忽略)。通过这种方式,您可以重新引发所有未预料到的错误,并且只忽略那些您预料到的错误。 注意:引发错误必须在
On error
块之外进行,但离开该块将重置
Err
对象。因此,您必须将所有必要的错误信息保存在另一个变量(或多个变量)中,以便在离开
On error
块后访问它


我担心VBA提供的错误处理的总体设计混乱,没有更好的方法。

您可以按如下方式提取价格:

Sub Redmart_scraping()
Dim driver As New ChromeDriver
Dim posts As Object
Dim i As Long

With driver
    .get "https://redmart.com/bakery"
End With

Columns("A:A").NumberFormat = "[$$-409]#,##0.00"

For Each posts In driver.FindElementsByClass("productPreview")
    i = i + 1
    'Cells(i, 2) = posts.Text
    For Each Item In Split(posts.Text, vbLf)
        If InStr(1, Item, "$", vbTextCompare) > 0 Then
            If InStr(2, Item, "$", vbTextCompare) > 0 Then
                Cells(i, 1) = Mid(Item, 2, InStr(2, Item, "$", vbTextCompare) - 2)
            Else
                Cells(i, 1) = Right(Item, Len(Item) - 1)
            End If

       End If
    Next
Next
End Sub
请注意,
posts.Text
包含一个项目所需的所有信息。因此,除了价格,您还可以提取商品名称、折扣、客户评级、重量、折扣前价格和保证的新鲜日期。。取消注释
”单元格(i,2)=posts.Text
,然后自己查看


我把剩下的有趣的工作留给你。祝你好运

您可以按如下方式提取价格:

Sub Redmart_scraping()
Dim driver As New ChromeDriver
Dim posts As Object
Dim i As Long

With driver
    .get "https://redmart.com/bakery"
End With

Columns("A:A").NumberFormat = "[$$-409]#,##0.00"

For Each posts In driver.FindElementsByClass("productPreview")
    i = i + 1
    'Cells(i, 2) = posts.Text
    For Each Item In Split(posts.Text, vbLf)
        If InStr(1, Item, "$", vbTextCompare) > 0 Then
            If InStr(2, Item, "$", vbTextCompare) > 0 Then
                Cells(i, 1) = Mid(Item, 2, InStr(2, Item, "$", vbTextCompare) - 2)
            Else
                Cells(i, 1) = Right(Item, Len(Item) - 1)
            End If

       End If
    Next
Next
End Sub
请注意,
posts.Text
包含一个项目所需的所有信息。因此,除了价格,您还可以提取商品名称、折扣、客户评级、重量、折扣前价格和保证的新鲜日期。。取消注释
”单元格(i,2)=posts.Text
,然后自己查看


我把剩下的有趣的工作留给你。祝你好运

看起来,从已接受的答案来看,您的脚本在促销价格上失败。请使用2个属性选择器结合或设置原始posts变量。那么就没有空值可处理了。(迟来的回答-在寻找资源时遇到此问题!)


看起来,从已接受的答案来看,您的脚本在促销价格上失败。请使用2个属性选择器结合或设置原始posts变量。那么就没有空值可处理了。(迟来的回答-在寻找资源时遇到此问题!)


根据文档,这就是Florent B.为避免任何索引错误并使代码贯穿始终而建议的方法

Sub ScrapePrice()
    Dim driver As New ChromeDriver, post As Object

    With driver
        .get "https://redmart.com/bakery"
        For Each post In .FindElementsByCss("li.productPreview")
            If Not post.FindElementByCss("span[class^='ProductPrice__price']", Raise:=False, timeout:=0) Is Nothing Then
                R = R + 1: Cells(R, 1) = post.FindElementByCss("span[class^='ProductPrice__price']").Text
            End If
        Next post
    End With
End Sub

根据文档,这就是Florent B.为避免任何索引错误并使代码贯穿始终而建议的方法

Sub ScrapePrice()
    Dim driver As New ChromeDriver, post As Object

    With driver
        .get "https://redmart.com/bakery"
        For Each post In .FindElementsByCss("li.productPreview")
            If Not post.FindElementByCss("span[class^='ProductPrice__price']", Raise:=False, timeout:=0) Is Nothing Then
                R = R + 1: Cells(R, 1) = post.FindElementByCss("span[class^='ProductPrice__price']").Text
            End If
        Next post
    End With
End Sub

谢谢道格·科茨爵士的回答。您提供的代码无法避免此问题。当它到达第一个空值时会中断。但是,您提供的代码会一直运行到值用尽为止,因为“下一步错误恢复”也在那里。@SMth80然后执行下一步错误恢复?先生,我首先这样做了,并给了您反馈。再次感谢。我以前从未玩过这些东西,所以这纯粹是一个问题,不是批评,但不会
Isnull(post.findelementbypath(“../h4/a”).Text)
需要
Isnull(post.findelementbypath(“../h4/a”))
-也就是说,
findelementbypath
不是潜在的
Null
,然后尝试查找
Null
的Text
属性将崩溃,而不是返回
Null
?我假设您需要检查这两个属性是否都为Null,我没有考虑到这一点。我打算安装selenium只是为了100%确定,但是呃,谢谢Doug Coats爵士的回答。您提供的代码无法避免此问题。当它到达第一个空值时会中断。但是,您提供的代码会一直运行,直到值用尽为止,因为“出错时继续下一步”也在那里。@SMth80然后在出错时取出r