VBA Web抓取-更改日历的日期

我想编写一个vba程序,该程序可以从网页自动下载历史库存数据。选择数据并单击下载按钮已在起作用。但是我也想更改日期,不适用于我的代码。

我想更改日期的Element的相应HTML代码,您可以在以下链接下找到该日期:

我要更改日期的元素的HTML代码

我现在使用的代码如下:

Public Sub MakeChanges()

'VBE > Tools > References > Selenium Type Library

'Download: https://github.com/florentbr/SeleniumBasic/releases/tag/v2.0.9.0

Dim d As WebDriver, t As Date

Set d = New ChromeDriver

Const url = "https://www.dukascopy.com/swiss/english/marketwatch/historical/"

With d

.Start "Chrome"

.get url

.SwitchToFrame .FindElementByCss("script + iframe")

t = Timer

Do

With .FindElementByCss("[data-instrument='EUR/USD']")

.Click

If .Attribute("aria-selected") Then Exit Do

End With

Loop While Timer - t < 10

MsgBox "please login"

'set the date

With .FindElementByCss("a-b-c.a-ab-v-y-x > div")

.FindElementByTag("span").innerText = "2017-01-01"

End With

'end set date

With .FindElementByCss(".d-wh-vg-v-p > div")

If Not .Attribute("aria-disabled") Then .Click

End With

Stop

.Quit

End With

End Sub

我非常感谢您的帮助!

回答:

请尝试以下方法。实际上,它单击年份和月份的下拉菜单,然后通过itemindex属性值选择适当的项目。

在年份的情况下,取决于当前显示的内容,期望的年份可能不在下拉列表中。该代码使用固定次数的<>按钮单击来确定是否可以找到所需的年份。可以在代码顶部将此数字设置为常量,并在需要时在此更改。

要选择日期,将循环收集天数,如果找到了所需的天数,则将其选中。

Javascript用于等待某些元素变为可单击状态,以及用于出现下拉菜单的定时循环。这会根据事件何时可操作来计时,以产生所需的结果。

Option Explicit

Public Sub MakeChanges()

'VBE > Tools > References > Selenium Type Library

'Download: https://github.com/florentbr/SeleniumBasic/releases/tag/v2.0.9.0

Const url = "https://www.dukascopy.com/swiss/english/marketwatch/historical/"

Const MAX_WAIT_SEC As Long = 10

Const JS_WAIT_CLICKABLE = _

"var target = this, endtime = Date.now() + arguments[0];" & _

"(function check_clickable() {" & _

" var r = target.getBoundingClientRect(), x = r.left+r.width/2, y = r.top+r.height/2;" & _

" for (var e = document.elementFromPoint(x , y); e; e = e.parentElement)" & _

" if (e === target){ callback(target); return; }" & _

" if (Date.now() > endtime) { callback(target); return; }" & _

" setTimeout(check_clickable, 60);" & _

"})();" 'by @florentbr

Dim d As WebDriver, t As Date

Dim myYear As String, myMonth As String, myDay As String

Set d = New ChromeDriver

myYear = "2017"

myMonth = "January"

myDay = "1"

With d

.start "Chrome"

.get url

.SwitchToFrame .FindElementByCss("script + iframe") '<==switch to frame

'You should add tests for acceptable values e.g. January-December for MonthName, day as appropriate for month

Dim monthIndex As Long, yearIndex As Long, item As Object, dropDown As Object

monthIndex = Month(DateValue("01 " & myMonth & " 2019")) - 1 '<== get month number from name and -1 to get value to use in attribute selector

t = Timer

Do '<== timed loop for month dropdown to be present

On Error Resume Next

Set dropDown = .FindElementByCss(".d-wh-vg-xh span span")

On Error GoTo 0

If Timer - t > MAX_WAIT_SEC Then Exit Do

Loop While dropDown Is Nothing

If dropDown Is Nothing Then Exit Sub

With dropDown '<== wait for drop down to be clickable

.ExecuteAsyncScript(JS_WAIT_CLICKABLE, 3000) _

.Click

End With

With .FindElementByCss(".d-Ch-fi-mi")

.ExecuteAsyncScript(JS_WAIT_CLICKABLE, 3000) _

.Click '<== display month dropdown

End With

.FindElementByCss(".d-Ch-fi-u [itemindex='" & monthIndex & "']").Click '<select month by index

Dim yearIndices As Object, i As Long, j As Long, currentYear As String, z As Long, dayFound As Boolean

currentYear = .FindElementByCss(".d-Ch-fi-ni").Text '<= find currently displayed year

Set yearIndices = CreateObject("Scripting.Dictionary")

For i = CLng(currentYear) - 5 To CLng(currentYear) + 5 '<== gather range of year options in dropdown into

'dictionary where key is year and value is the value required to select in attribute selector

yearIndices(CStr(i)) = CStr(j)

j = j + 1

Next

If yearIndices.Exists(myYear) Then '<check dictionary to see if year desired present

yearIndex = yearIndices(myYear)

.FindElementByCss(".d-Ch-fi-ni").Click '<== display year dropdown

.FindElementByCss("div:nth-child(11) [itemindex='" & yearIndex & "']").Click '<==select year

Else '<== year not present so loop clicking either year add or year subtract to see if desired year does become present

Dim adjustButton As Object

Set adjustButton = IIf(CLng(currentYear) > CLng(myYear),.FindElementByCss("d-Ch-fi-previousYear"), .FindElementByCss("d-Ch-fi-nextYear"))

Do

adjustButton.Click

If z > 15 Then Exit Sub

z = z + 1

Loop Until .FindElementByCss(".d-Ch-fi-ni").Text = myYear

End If

Dim daysList As Object

Set daysList = .FindElementsByCss("div:nth-child(11) td") '<==gather all the days

For Each item In daysList '<==loop days in month until required one found

If item.Text = myDay Then

item.Click

Exit For

End If

Next

Stop

.Quit

End With

End Sub

以上是 VBA Web抓取-更改日历的日期 的全部内容, 来源链接: utcz.com/qa/422562.html

回到顶部