我正在尝试使用VBA从使用ReactJS的HTML网站中选择一个下拉项。对于此示例,我们可以使用以下网站:
https://jedwatson.github.io/react-select/
<span class="Select-value-label" role="option" aria-selected="true" id="react-select-2--value-item">New South Wales</span>
如果HTML页面列出了下拉列表中的所有选项,我可以轻松地将elementID
设置为其中一个下拉值。
Set ie = CreateObject("InternetExplorer.Application")
With ie
.Visible = True
.Navigate "about:blank"
'with for page load
ieWaitForURL
.Navigate "https://jedwatson.github.io/react-select/"
ie.Document.getelementbyid("react-select-2--value-item").Value = "Victoria"
但是ReactJS网站的HTML没有列出下拉列表的所有选项,并且当我做出不同的选择时,innertext的值会发生变化。
如果HTML中没有列出所有选项,有没有办法从使用VBA的ReactJS下拉列表中进行选择?
它实际上比我想象的容易得多。以下使用硒碱。安装selenium basic,确保最新的chromedriver.exe在selenium文件夹中,vbe> tools> references>添加对selenium类型库的引用
我将所有选项值都显示在字典中。此外,从下拉列表中选择一个项目。
这里的关键是选项菜单不是传统的select
元素,与孩子option
s,但使用React Select。可能值的范围是通过来自this script的Ajax提取的。
我将展示如何使用python直接从该脚本中检索可能的值,但如果您真的感兴趣,我很乐意转换为vba。单击下拉列表后,可以收集可用值列表。
如果您想沿着IE路线走下去,您可以使用相同的方法,但需要触发将打开下拉列表的事件。我认为这些也在js脚本中有详细说明。
Option Explicit
Public Sub MakeSelection()
Dim d As WebDriver, i As Long, dropDownOptions As Object
Const URL = "https://jedwatson.github.io/react-select/"
Set d = New ChromeDriver
Set dropDownOptions = CreateObject("Scripting.Dictionary")
With d
.Start "Chrome"
.get URL
.FindElementByCss("button:nth-of-type(2)").Click
.FindElementByCss(".Select-arrow-zone").ClickAndHold
Dim item As Object
For Each item In .FindElementsByCss(".Select-menu div") 'put list of options in dictionary
dropDownOptions(item.Text) = i
i = i + 1
Next
For Each item In .FindElementsByCss(".Select-menu div") 'loop to select an option
If item.Text = "Victoria" Then 'If item.Text = dropDownOptions.item(3) etc....
item.Click
Exit For
End If
Next
Stop
.Quit
End With
End Sub
用于解析json中可能的下拉值的Python脚本:
这显示了通过下拉列表更新的3个不同元素部分(标签,类和值)
import requests
import re
import json
r = requests.get('https://jedwatson.github.io/react-select/app.js')
s = str(r.content)
p1 = re.compile('t\.AU=(.*)')
p2 = re.compile('.+?(?=,\[\d+\])')
data1 = re.findall(p1, s)[0]
data2 = re.findall(p2, data1)[0].replace(',disabled:!0','')
replacements = ['value:','label:','className:']
for item in replacements:
data2 = re.sub(item, '"' + item[:-1] + '":' , data2)
finals = data2.split(',t.US=')
finalAus = json.loads(finals[0])
# finalUs = json.loads(finals[1])
d = {}
i = 0
for item in finalAus:
d[item['label']] = i
# item['label']
# item['value']
# item['className']
i+=1
print(d)