苦節2年…Internet Explorer 11(IE11)のファイルダウンロード時の通知バー上の保存ボタン押下をpywinauto、win32gui、win32conを駆使してpythonで自動化します。
~ダウンロードボタン押下後のダウンロード完了までは割愛~
~①IE11ウィンドウを最前面にします(pyautoguiはクライアントで稼働させる分には優秀だがサーバで稼働させるとうまく動かない)~
from pywinauto import application
from pywinauto.findwindows import WindowNotFoundError, WindowAmbiguousError
#InitApp object
app=application.Application()
try:
app.connect(class_name="IEFrame",title_re=".%s." % '**** - Internet Explorer')
#Access asp's window object
app_dialog=app.top_window()
app_dialog.minimize()
app_dialog.restore()
#app_dialog.set_focus()
except(WindowNotFoundError):
print('"%s" not found' % app)
pass
except(WindowAmbiguousError):
print('Too many "%s" windows found' % app)
pass
~②IE11ウィンドウ親と子ウィンドウの保存ボタンのハンドルを取得して通知バーのハンドルを特定します※****は対象サイト名等(pyautoguiはクライアントで稼働させる分には優秀だがサーバで稼働させるとうまく動かない)~
p_handle=win32gui.FindWindow("IEFrame", "**** - Internet Explorer")
p_class_name=win32gui.GetClassName(p_handle)
p_handle_name=win32gui.GetWindowText(p_handle)
handles_dict={str(p_handle):[p_class_name,p_handle_name]}
print('p',hex(p_handle),p_class_name,p_handle_name)
print('p',p_handle,p_class_name,p_handle_name)
c_handles=[]
win32gui.EnumChildWindows(p_handle,lambda handle,list: list.append(handle),chandles)
while True:
for ch in c_handles:
c_class_name=win32gui.GetClassName(ch)
c_handle_name=win32gui.GetWindowText(ch)
print('c', hex(ch),c_class_name,c_handle_name)
handles_dict[str(ch)]=[c_class_name,c_handle_name]
if c_class_name=='DirectUIHWND':
print('Frame Notification Bar Hwnd:',hex(ch))
print('Frame Notification Bar Hwnd:',ch)
Hwnd=ch
break
if c_class_name=='DirectUIHWND':
print("Frame Notification Bar found...")
break
~③特定したIE11子ウィンドウの通知バーのハンドルにPostMessageでAlt+Nキー送信のうえ保存ボタン押下する方法もありますがサーバでは最後の保存ボタンがうまく押せないため保存ボタンのハンドルにTABとSPACEキーを送ります。(pyautoguiはクライアントで稼働させる分には優秀だがサーバで稼働させるとうまく動かない)~
time.sleep(2)
print("VK_TAB")
win32gui.PostMessage(Hwnd,win32con.WM_KEYDOWN,win32con.VK_TAB,0)
win32gui.PostMessage(Hwnd,win32con.WM_KEYUP,win32con.VK_TAB,0)
time.sleep(2)
print("VK_SPACE")
win32gui.PostMessage(Hwnd,win32con.WM_KEYDOWN,win32con.VK_SPACE,0)
win32gui.PostMessage(Hwnd,win32con.WM_KEYUP,win32con.VK_SPACE,0)
~非常に煩雑ですが大抵のWindowsクライアント環境はもちろんWindowsサーバ環境であっても保存ボタンが押下できる…はずです、まさか保存ボタン1つでこんなに悩むことになるとは…~