【问题标题】:Wait until specific elements loaded等到加载特定元素
【发布时间】:2019-05-23 12:04:08
【问题描述】:

我正在尝试抓取一个网站,我正在处理许多元素。我需要等待元素加载完毕。

这是我到现在为止的尝试,但我等待了很长时间,有时我会出错。

.FindElementById("ContentPlaceHolder1_Button1").Click
.Wait 2000
GoBack1:
Set elePrint = .FindElementById("IconImg_CrystalReportViewer1_toptoolbar_print", timeout:=20000, Raise:=False)
If elePrint Is Nothing Then
    Application.Wait Now() + TimeValue("00:00:01"): GoTo GoBack1
Else
    elePrint.Click
End If
GoBack2:
Set eleExport = .FindElementById("theBttnbobjid_1545642213647_dialog_submitBtn", timeout:=20000, Raise:=False)
If eleExport Is Nothing Then
    Application.Wait Now() + TimeValue("00:00:01"): GoTo GoBack2
Else
    eleExport.Click
End If

有没有更好的方法来做到这一点?

这是html部分

<tbody><tr valign="middle"><td height="21" width="5" style="background-image:url('aspnet_client/system_web/4_0_30319/crystalreportviewers13/js/crviewer/../dhtmllib/images/skin_standard/button.gif');background-position:0px 0px;"></td><td id="theBttnCenterImgbobjid_1545656314367_dialog_submitBtn" align="center" class="wizbutton" style="padding-left:3px;padding-right:3px;background-image:url('aspnet_client/system_web/4_0_30319/crystalreportviewers13/js/crviewer/../dhtmllib/images/skin_standard/button.gif');background-position:0px -42px;"><nobr><a id="theBttnbobjid_1545656314367_dialog_submitBtn" href="javascript:void(0)" class="wizbutton" role="button">Export</a></nobr></td><td height="21" width="5" style="background-image:url('aspnet_client/system_web/4_0_30319/crystalreportviewers13/js/crviewer/../dhtmllib/images/skin_standard/button.gif');background-position:0px -21px;"></td></tr></tbody>

【问题讨论】:

    标签: excel vba selenium-webdriver web-scraping


    【解决方案1】:

    您可以尝试循环您的元素,直到它们可用为止。

    On Error Resume Next
    Do While .FindElementById("theBttnbobjid_1545642213647_dialog_submitBtn") Is Nothing
        DoEvents
    Loop
    On Error Goto 0
    

    如果由于某种原因网页挂起,我也会考虑在您的循环中添加一个计时器 - 如果是这种情况,您可以重新加载网页或执行一些其他错误处理操作。

    【讨论】:

    • 非常感谢您的大力帮助。这比我的效果更好
    • 为什么你好! +
    【解决方案2】:

    您可以将其缩短为

    Do 
    Loop While .FindElementsByCss("#theBttnbobjid_1545642213647_dialog_submitBtn").Count = 0 
    

    虽然你应该设置一个超时时间

    Const MAX_WAIT_SEC As Long = 10
    Dim t 
    t = Timer
    Do 
        If Timer - t > MAX_WAIT_SEC Then Exit Do
    Loop While .FindElementsByCss("#theBttnbobjid_1545642213647_dialog_submitBtn").Count = 0 
    

    不会出现错误,也无需让步控制。如果找不到该项目,.Count 将为零。

    如果 id 是动态的并且你有一个常量子字符串(它只出现在页面上的一个 id 属性上(为了安全起见 - 可能不是必需的)你可以在 css 中使用 ^、*、$ 运算符)。例如,如果起始字符串在页面间保持不变,则将 css 选择器更改为

    [id^='theBttnbobjid']
    

    如果出现不止一次,并且索引在页面之间是恒定的,则使用索引稍后进行交互,例如

    .FindElementsByCss("[id^='theBttnbobjid']")(2)
    

    【讨论】:

    • 非常感谢您的帮助。我注意到这个#theBttnbobjid_1545642213647_dialog_submitBtn 是可变的。在这种情况下我该如何处理..?我正在处理很多页面,每次都有不同的选择器!太奇怪了
    • 是的,这是真的..我检查了另一个页面,结果是theBttnbobjid_1545656314367_dialog_submitBtn
    • 对不起。我以为我已经发布了 html 部分,但似乎我已经在 LINK 的另一个线程中发布了......我也在这里包含了 html 部分
    • 总是第二个吗?如果是这样,您可以使用上述方法,但是当您与目标交互时使用 index .FindElementsByCss("[id^='theBttnbobjid']")(2) 。我认为索引是基于硒的 1,否则使用 1。
    • 非常感谢您的帮助。你是传奇
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-29
    • 1970-01-01
    • 2018-11-01
    • 1970-01-01
    • 2020-08-27
    • 1970-01-01
    相关资源
    最近更新 更多