Задача обычная - автоматизировать скачку файлов через IE (всякие протокольные способы обращения к сайту на данный момент не подходят, надо именно поломать голову и заставить браузер сохранить файлы). Все упирается во всплывающее окно view and track your files которое не внемлет всем моим попыткам до него достучаться
Выкурено много иностранных форумов, но все мои не очень умелые попытки добраться до хэндлов 32770 и DirectUIHWND и передать туда какой-нибудь sendkeys ни к чему не приводят. Просьба к знающим форумянам - подскажите, это вообще возможно?
Пробую заменить IE на какой нибудь хром, вызванный через Shell, - просто открывает нужный джсон в виде текста на странице, безо всяких Открыть/Сохранить и теоретически если передать туда ctrl-s и имя файла то все бы сильно упростилось. Но тоже не получается...
К вопросу о протокольных методов добраться до файла... я попробовала, но какие бы заголовки не пытаться туда передать, что через PQ, что через макрос, результат один - доступ запрещен или 403
Код
Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare PtrSafe Function FindWindowEx& Lib "user32" _
Alias "FindWindowExA" (ByVal hWndParent As Long, ByVal hwndChildAfter As Long, ByVal lpClassName As String, ByVal lpWindowName As String)
Private Declare PtrSafe Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByRef lParam As Any) As Long
Private Declare PtrSafe Function PostMessage Lib "user32.dll" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare PtrSafe Function apiShowWindow Lib "user32" Alias "ShowWindow" _
(ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
Private Declare PtrSafe Function GetDlgItem Lib "user32" (ByVal hDlg As Integer, ByVal nIDDlgItem As Integer) As Integer
Private Declare PtrSafe Function SetForegroundWindow Lib "user32" (ByVal hwnd As LongPtr) As Boolean
Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr)
Private Declare PtrSafe Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
Private Const WM_SETTEXT = &HC 'константа изменения текста
Private Const BM_CLICK = &HF5 'константа нажатие кнопки
Const VK_J = &H4A 'J
Const VK_CONTROL = &H11 'Ctrl
Const WM_KEYDOWN As Long = &H100
Sub Taxi()
Set IE = CreateObject("InternetExplorer.Application"):
On Error Resume Next
addr$ = "https://САЙТБЛАБЛАМЭРАБЛАБЛАМОСКВЫ/altmosmvc/api/v1/taxi/getInfo/?Region=&RegNum=&FullName=&LicenseNum=&Condition=&pagenumber=1"
IE.navigate addr$ ' загружаем сайт
While IE.Busy Or (IE.readyState <> 4): DoEvents: Wend
'тут все потерто потому что все опробованное не работает ^_^
End Sub
S M, могу предложить только "костыль". Установить какой-либо автокликер, у которого есть свой язык макрокоманд (например, Jitbit Macro Recorder) и добавить в Ваш код на ВБА исполнение автокликером его кода, связанного с кликом по кнопке в соответствующем окне.
Формула массива (ФМ) вводится Ctrl+Shift+Enter Memento mori
Дело в том что я с ним тоже пробовала... но вызываемая ботом Селениума страница отображается как "не найдено" в браузере. В хроме еще сопровождается пометкой "управляется автоматизированным тестировочным ПО",.. стоит обновить ручками и все загружается и работает.
Так Вы в своем примере обращаетесь именно к WEB API, а ответ получаете в JSON-формате. Для обработки JSON-файлов есть примеры макросов на VBA. Не думаю, что способ через браузер лучше.
А еще лучше способ - попросить спецов по Power Query (PQ) - они все сделают в наилучшем виде.
sokol92, я пробовала через PQ - приходит отказ от сервера. Возможно я чего-то не знаю насчет заголовков. Но я пробовала передавать приблизительно все значимое, что проявляется в том же браузере в режиме отладки. Все равно - ответ одинаковый "доступ запрещен". Поэтому и возникла мысль - просто воспользоваться браузером)
Для обработки непосредственно джсонов достаточно PQ. Он прекрасно с ними справляется... НО только если они лежат на диске)...
В общем, доковыряла я, спасибо. Задачу - накачать кучу индивидуальных файлов с мосры для дальнейшего скармливания Power Query он выполняет
Получившийся костыль предлагаю общественности
Код
Private Assert As New Assert
Private bot As New selenium.ChromeDriver
Sub Taxi()
Dim keys As New selenium.keys
Dim TextLine$, PathFileName$
Dim i As Long
Dim URL As String
Dim URLrev As String
bot.SetPreference "download.default_directory", "c:\temp"
bot.SetPreference "download.directory_upgrade", True
bot.SetPreference "download.prompt_for_download", False
bot.SetPreference "safebrowsing.enabled", True
bot.SetPreference "plugins.plugins_disabled", Array("Chrome PDF Viewer")
bot.Start "Chrome"
URL = "https://САЙТБЛАБЛАМЭРАБЛАБЛАМОСКВЫ/altmosmvc/api/v1/taxi/getInfo/?Region=&RegNum=&FullName=&LicenseNum=&Condition=&pagenumber="
For i = 3 To 10
URLrev = URL & i
bot.get URLrev
bot.Refresh
'bot.SendKeys keys.Control & "a"
s = bot.FindElementByTag("body").Text
'Debug.Print s
PathFileName = "C:\Users\S_M\Desktop\mosru\page" & i & ".json"
TextLine = s
Open PathFileName For Output As #1
Print #1, TextLine
Close #1
bot.Wait "2000"
Next
End Sub
Сильно прошу тапками не бить, это второй в моей жизни макрос. Предложения по улучшению принимаются с благодарностью. Было бы очень интересно, конечно, как решить эту задачу с помощью голого Power Query или api запроса или всяких других умных штук, которые у меня не получились