我正在使用Selenium开发一个用于内部Intranet的VBA Web scraper,并且我正在解压缩几块。我很幸运使用CSS访问大部分数据,但遇到了一些常用类的情况,并且某些元素的位置可能会有所不同。
<div class="col-xs-12 col-sm-4 header-section header-list">
<li>
<i class="hire-icon-contactcard-outline header-list-icon"></i>
<span class="modal-link ng-binding" data-ng-click="createContactCardModal()">View full contact card</span>
</li>
<li>
<i class="hire-icon-email-outline header-list-icon"></i>
<!-- ngIf: !candidate.hasEmailAddress() -->
<!-- ngIf: candidate.hasEmailAddress() -->
<a href="mailto:[email protected]" ng-if="candidate.hasEmailAddress()" class="ng-binding ng-scope">[email protected]</a>
<!-- end ngIf: candidate.hasEmailAddress() -->
</li>
<li>
<i class="hire-icon-phone-solid header-list-icon"></i>
<!-- ngIf: !candidate.hasPhoneNumber() -->
<!-- ngIf: candidate.hasPhoneNumber() -->
<span ng-if="candidate.hasPhoneNumber()" class="ng-binding ng-scope">123-456-7898</span>
<!-- end ngIf: candidate.hasPhoneNumber() -->
</li>
我一直在尝试以下各种各样,感觉我有点接近,但知道我的代码可能已关闭。
CandidateEmail = bot.FindElementByCss("[class$='hire-icon-email-outline header-list-icon']/following-sibling::[@class='ng-binding ng-scope'])")
CandidateEmail = bot.FindElementByXPath("//i[@class='hire-icon-email-outline header-list-icon']/following-sibling::a[@class='ng-binding ng-scope'])")
知道我可能会缺少什么吗?另外,是否可以简单地让selenium选择ngIf元素 - 例如
提前感谢您的时间和见解!非常感谢!
在css选择器看来你正在混合XPath的语法;并且这两个例子可能会被你的班级名称中的空格绊倒。我会用:
CandidateEmail = bot.FindElementByCss(".hire-icon-email-outline.header-list-icon")
初始点告诉它查找具有指定类名的元素,并且需要用点替换类中的空格,否则它将被视为两个类。
哦,我刚刚注意到你正在寻找应该能够通过以下方式定位的'a'元素(如果这是整个HTML):
CandidateEmail = bot.FindElementByCss("a.ng-binding.ng-scope")
或者(如果您发布的是整个HTML),那里只有一个'a'元素,这意味着以下内容应该有效:
CandidateEmail = bot.FindElementByCss("a")
显然我拥有我需要的一切,只需要更多地玩它。
能够让它通过以下工作
CandidateEmail = bot.FindElementByXPath("//a[@ng-if='candidate.hasEmailAddress()']").Attribute("innerText")
考虑使用css attribute = value选择器组合,^启动运算符以通过其href值来定位email元素。
bot.FindElementByCss("[href^=mailto]")
如果需要,您可以进一步指定添加一个额外的属性选择器(或者实际上为上面的第一个选择第二个):
bot.FindElementByCss("[href^=mailto][ng-if='candidate.hasEmailAddress()']")
另外,考虑一个相邻的兄弟组合子,您可以在其中指定电子邮件图标后面的标签。
bot.FindElementByCss(".hire-icon-email-outline ~ a")
这是子串匹配的一个潜在应用
Dim dict As Object, key As Variant
Set dict = CreateObject("Scripting.Dictionary")
dict.Add "hasEmailAddress", vbNullString
dict.Add "hasPhoneNumber", vbNullString
For Each key In dict.keys
On Error Resume Next
dict(key) = bot.FindElementByCss("[ng-if*=" & key & "]").Text 'assuming no illegal characters in string
Debug.Print key, bot.FindElementByCss("[ng-if*=" & key & "]").Text
On Error GoTo 0
Next