Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel 硒-NG-IF还是下一种元素?_Excel_Vba_Selenium_Web Scraping - Fatal编程技术网

Excel 硒-NG-IF还是下一种元素?

Excel 硒-NG-IF还是下一种元素?,excel,vba,selenium,web-scraping,Excel,Vba,Selenium,Web Scraping,我正在使用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"&

我正在使用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:testemail@gmail.com" ng-if="candidate.hasEmailAddress()" class="ng-binding ng-scope">testemail@gmail.com</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>
知道我遗漏了什么吗?此外,是否可以简单地让selenium选择ngIf元素-例如
提前感谢您的时间和洞察力!非常感谢

css选择器中的看起来像是混合了XPath的语法;这两个例子可能会被类名中的空格绊倒。我将使用:

CandidateEmail = bot.FindElementByCss(".hire-icon-email-outline.header-list-icon")
初始点告诉它查找具有指定类名的元素,您需要用点替换类中的空格,否则它将被视为两个类

哦,我刚刚注意到您正在寻找“a”元素,它应该可以通过以下方式找到(如果这是整个HTML):

或者(同样,如果您发布的是整个HTML),其中只有一个“a”元素,这意味着以下内容应该可以工作:

CandidateEmail = bot.FindElementByCss("a")

考虑将css attribute=value选择器与^starts with运算符组合使用,以通过其href值将电子邮件元素作为目标

bot.FindElementByCss("[href^=mailto]")
如果需要,您可以进一步指定添加一个额外的属性选择器(或者在上面的第一个属性选择器中切换第二个):

也可以考虑一个相邻的兄弟组合器,在电子邮件图标之后指定一个标签。

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

很明显,我拥有了我所需要的一切,只是需要更多的发挥

能够通过以下步骤使其正常工作

CandidateEmail = bot.FindElementByXPath("//a[@ng-if='candidate.hasEmailAddress()']").Attribute("innerText")

我感谢您的回复-我不希望使用特定的内容来查找href,因为这是整个网站的常见挑战,而不仅仅是特定于电子邮件地址。例如,即使试图在给定代码中查找电话号码,我也必须遵循相同的方法。我尝试使用相邻的兄弟组合器,但它不起作用。它们的结构类似,因此您可以拥有一个列表子字符串,并在循环过程中连接这些子字符串。您是否尝试了“编辑为css选择器”应该是更快的方法。感谢您的响应,适用于其他选择器的格式是
CandidateName=bot.FindElementByCss(“[class$='candidate-name ng binding'].Attribute(“innerText”)
仅使用ng-binding.ng-scope不起作用,因为它通常在html的其余部分中使用。这只是完整代码中的一个非常小的代码片段。第一个示例不起作用。我尝试添加.Attribute(“innerText”)最后,这也没有改变任何东西。除非我看到完整的HTML,否则我很难指定任何唯一的选择器。如果你发布所有HTML,我相信你会得到答案。
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
CandidateEmail = bot.FindElementByXPath("//a[@ng-if='candidate.hasEmailAddress()']").Attribute("innerText")