Страницы: 1
RSS
VBA - как добраться до хэндлов окна Просмотр и Отслеживание загрузок в Internet Explorer 11
 
Прошу помощи или хотя бы промытия мозгов :cry:

Задача обычная - автоматизировать скачку файлов через 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 - 26.08.2021 00:09:17
 
S M, могу предложить только "костыль". Установить какой-либо автокликер, у которого есть свой язык макрокоманд (например, Jitbit Macro Recorder) и добавить в Ваш код на ВБА исполнение автокликером его кода, связанного с кликом по кнопке в соответствующем окне.

Формула массива (ФМ) вводится Ctrl+Shift+Enter
Memento mori
 
Selenium VBA пойдет за макрокликер?

Дело в том что я с ним тоже пробовала... но вызываемая ботом Селениума страница отображается как "не найдено" в браузере.
В хроме еще сопровождается пометкой "управляется автоматизированным тестировочным ПО",.. стоит обновить ручками и все загружается и работает.
:evil:  
Изменено: vikttur - 25.08.2021 23:45:24
 
Думаю, есть более прямой путь - ознакомиться с инструкцией по API  (это сайт Мэра Москвы). В Вашем примере выдается вполне цивилизованный JSON-формат.
Изменено: sokol92 - 25.08.2021 12:21:39
Владимир
 
sokol92
Я предпочитаю считать это сайтом все-таки города Москвы, ну да неважно.

У меня от ВБА то мозги уже плавятся, а вы говорите АПИ ))
 
mos.ru Официальный сайт Мэра Москвы

Так Вы в своем примере обращаетесь именно к WEB API, а ответ получаете в JSON-формате. Для обработки JSON-файлов есть примеры макросов на VBA. Не думаю, что способ через браузер лучше.

А еще лучше способ - попросить спецов по Power Query  (PQ) - они все сделают в наилучшем виде.
Изменено: sokol92 - 25.08.2021 12:33:35
Владимир
 
sokol92,  я пробовала через PQ - приходит отказ от сервера.
Возможно я чего-то не знаю насчет заголовков. Но я пробовала передавать приблизительно все значимое, что проявляется в том же браузере в режиме отладки.
Все равно - ответ одинаковый "доступ запрещен".
Поэтому и возникла мысль - просто воспользоваться браузером)

Для обработки непосредственно джсонов достаточно PQ. Он прекрасно с ними справляется... НО только если они лежат на диске)...
 
Да, скорее всего там выполняются js скрипты. Ждите "профильных" специалистов.
Изменено: sokol92 - 25.08.2021 15:52:49
Владимир
 
В общем, доковыряла я, спасибо.
Задачу - накачать кучу индивидуальных файлов с мосры для дальнейшего скармливания 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

Сильно прошу тапками не бить, это второй в моей жизни макрос. :oops:
Предложения по улучшению принимаются с благодарностью.
Было бы очень интересно, конечно, как решить эту задачу с помощью голого Power Query или api запроса или всяких других умных штук, которые у меня не получились :(
Изменено: S M - 26.08.2021 00:09:26
 
Отлично (для второго макроса)! Selenium  - достаточно мощный инструмент. На форуме были примеры его использования.
Владимир
Страницы: 1
Наверх