【发布时间】:2021-05-12 10:04:21
【问题描述】:
我正在尝试使用 VBA 中的 Selenium 浏览此网页:https://www.familysearch.org/search/collection/1401638/。我使用 Chrome 作为浏览器并检查以查看页面中的元素。我不熟悉 javascript,但我是 VBA 专家。我可以浏览页面上看似静态的元素,例如单击右上角的登录按钮。但是我还没有弄清楚如何与具有标签 Search Collection 的中心的表单进行交互。
这是我目前的代码:
Sub WebScraper()
Dim FSBrowser As New WebDriver
Dim FSWebElements As WebElements
FSBrowser.Start "chrome", "https://www.familysearch.org/search"
FSBrowser.Get "/collection/1401638/" ' United States Census, 1850
FSBrowser.FindElementById("signInLink").Click
'FSBrowser.FindElementById("userName").SendKeys ("xxxx")
'FSBrowser.FindElementById("password").SendKeys ("xxxx")
'FSBrowser.FindElementById("login").Click
FSBrowser.Quit
End Sub
我想在出生地文本框中输入“弗吉尼亚”,然后点击搜索。
在 Inspect 中呈现的完整 HTML 代码真的很长,因为有相当多的表单元素。这是来自 javascript 和两个元素的表单信息:
<fs-search-form mobile-breakpoint="500">
<form id="form" method="get" class="search-form " action="/search/record/results">
<input type="text" class="fs-field-group__input" name="birthLikePlace" id="birthLikePlace">
<button type="submit" class="fs-button fs-button--recommended">Search</button>
这似乎是一项简单的任务,但我显然遗漏了一些东西。有人可以告诉我那是什么吗?看起来通过名称或birthLikePlace 的 Id 查找元素会起作用,但它不起作用。
编辑: 似乎 shadow-root 在这个问题上发挥了重要作用。它被标记为打开,但我怀疑还有更多我没有看到的内容。以下是birthLikePlace 的完整部分:
<sf-search-field-group field-list="["birthLikePlace", "birthLikeDate"]" trigger-id="birth">
#shadow-root (open)
<style> ... </style>
<div class="field-section" visible="">
<h2 class="section-header fs-h5">KEY: null (en)</h2>
<dom-if style="display: none;"><template is="dom-if"></template></dom-if>
<dom-if style="display: none;"><template is="dom-if"></template></dom-if>
<div class="trigger-group shown active flexible-container" for="birth">
<legend role="button" class="closer " for="birth" aria-label="Hide search fields for birth"> </legend>
<slot></slot> </div> </div>
<sf-search-field field-id="birthLikePlace" field-type="place">
#shadow-root (open)
<style> ... </style>
<span class="field" visible="" field-id="birthLikePlace">
<dom-if style="display: none;"><template is="dom-if"></template></dom-if>
<span class="event-place flex-item">
<label for="birthLikePlace_place">Birthplace</label>
<span class="fs-field-group">
<input type="text" class="fs-field-group__input" name="birthLikePlace" id="birthLikePlace">
<span class="fs-field-group__attachment fs-tooltip">
<span class="fs-tooltip__trigger">
<input type="checkbox" name="birthLikePlace.exact" id="birthLikePlaceexact">
<label aria-label="Match birthplace exactly" for="birthLikePlaceexact"></label> </span>
<span class="fs-tooltip__body" role="tooltip">::before Match birthplace exactly ::after</span> </span> </span> </span>
<dom-if style="display: none;"><template is="dom-if"></template></dom-if>
<dom-if style="display: none;"><template is="dom-if"></template></dom-if>
<dom-if style="display: none;"><template is="dom-if"></template></dom-if>
<dom-if style="display: none;"><template is="dom-if"></template></dom-if>
<dom-if style="display: none;"><template is="dom-if"></template></dom-if>
<dom-if style="display: none;"><template is="dom-if"></template></dom-if>
</span>
</sf-search-field>
<sf-search-field field-id="birthLikeDate" field-type="year"> ... </sf-search-field>
</sf-search-field-group>
【问题讨论】:
-
乍一看,您似乎可以使用发出 post 请求的 xmlhttp requests 方法登录到该站点。你试过了吗?
-
我想先尝试使用 Selenium,因为我想使用 Chrome 作为浏览器而不是 Internet Explorer。 xmlhttp 会是完成这项任务的更好方法吗?
-
Selenium 绝对是比 IE 更好的选择。 Xmlhttp requests 方法始终是最好的方法,如果你能以正确的方式处理它并且你希望抓取的内容不是高度动态的意味着 javascript 加密。
-
这里的请求只是开始的地方,所以我可以理解我在哪里遗漏了一些东西。一旦我弄清楚了基础知识,我就会计划更多。该网站基本上都是用 javascript 编写的并且是完全动态的。
-
如果您想在登录后在出生地文本框中输入文本,您想为脚本定义一个显式超时以等待该框可用,例如
Set obirthPlace = FSBrowser.FindElementById("birthLikePlace", timeout:=10000): obirthPlace.SendKeys "virginia"
标签: excel vba selenium web-scraping