Python Win32 APIでウインドウを前面に出す
Python Win32 APIでウインドウメッセージ
Win32 APIを使ってHTTP通信をやってみます。WinINetというライブラリを使います。
from ctypes import *
InternetOpen = windll.wininet.InternetOpenW
InternetConnect = windll.wininet.InternetConnectW
HttpOpenRequest = windll.wininet.HttpOpenRequestW
HttpSendRequest = windll.wininet.HttpSendRequestW
InternetReadFile = windll.wininet.InternetReadFile
InternetCloseHandle = windll.wininet.InternetCloseHandle
GetLastError = windll.kernel32.GetLastError
ドキュメント(InternetOpenW)を見ると、下の方にDLL Wininet.dllと書かれています。
これより、モジュールのパスは(user32ではなく)windll.wininetになります。
INTERNET_OPEN_TYPE_PRECONFIG = 0
lpszAgent = "test" # ユーザーエージェント(適当)
hInet = InternetOpen(lpszAgent, INTERNET_OPEN_TYPE_PRECONFIG, None, None, 0)
if hInet == 0:
raise Exception
INTERNET_OPEN_TYPE_PRECONFIG - レジストリから何か設定を読み込むみたいです。
詳しい意味や他のパラメータなど、ドキュメントにすべて書かれています。ただ、どれにすればいいかは試行錯誤です。また、InternetOpenAなど~Aでは通らなかったので、すべて~Wにしています。
(C言語では~Aでも通るのに)
InternetOpenとInternetConnectで初期化、これは最初に一度だけやればよいです。
HttpOpenRequest,HttpSendRequestで送信して、InternetReadFileで応答を(バイト配列で)受信します。
import sys
from ctypes import *
InternetOpen = windll.wininet.InternetOpenW
InternetConnect = windll.wininet.InternetConnectW
InternetCloseHandle = windll.wininet.InternetCloseHandle
HttpOpenRequest = windll.wininet.HttpOpenRequestW
HttpSendRequest = windll.wininet.HttpSendRequestW
InternetReadFile = windll.wininet.InternetReadFile
GetLastError = windll.kernel32.GetLastError
INTERNET_OPEN_TYPE_PRECONFIG = 0
INTERNET_SERVICE_HTTP = 3
INTERNET_DEFAULT_HTTP_PORT = 80
try:
lpszAgent = "test"
hInet = InternetOpen(lpszAgent, INTERNET_OPEN_TYPE_PRECONFIG, None, None, 0)
if hInet == 0:
raise Exception
lpszServerName = "docs.microsoft.com"
hConnect = InternetConnect(hInet, lpszServerName, INTERNET_DEFAULT_HTTP_PORT, None, None, INTERNET_SERVICE_HTTP, 0, None)
if hConnect == 0:
raise Exception
lpszObjectName = "en-us/windows/win32/api/wininet/nf-wininet-internetopenw"
hRequest = HttpOpenRequest(hConnect, "GET", lpszObjectName, None, None, None, 0, None)
if hRequest == 0:
raise Exception
lpszHeaders = "Content-Type: application/x-www-form-urlencoded"
ret = HttpSendRequest(hRequest, lpszHeaders, -1, None, 0)
if ret == 0:
raise Exception
dwRead = c_long(1)
while dwRead.value > 0:
lpBuffer = create_string_buffer(1024)
ret = InternetReadFile(hRequest, lpBuffer, 1024, pointer(dwRead))
if ret == 0:
raise Exception
sys.stdout.buffer.write(lpBuffer.value) # 応答を出力
except Exception as e:
print(GetLastError())
raise e
finally:
if hRequest != 0:
InternetCloseHandle(hRequest)
if hConnect != 0:
InternetCloseHandle(hConnect)
if hInet != 0:
InternetCloseHandle(hInet)
実行結果
<!DOCTYPE html>
...(略)...
<div id="action-panel" role="region" aria-label="Action Panel" class="action-panel has-default-focus" tabindex="-1"></div>
</body>
</html>
参考までに、対応するC言語のソース
gcc .\wininet_test.c -lWininet
(Mingw-w64で確認)
wininet_test.c
#include <windows.h>
#include <wininet.h>
#include <stdio.h>
int main(void)
{
char *lpszAgent = "test";
HINTERNET hInet = InternetOpenA(lpszAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (hInet == NULL)
{
printf("InternetOpenA error %d\n", GetLastError());
goto finally;
}
char *lpszServerName = "docs.microsoft.com";
HINTERNET hConnect = InternetConnectA(hInet, lpszServerName, INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, (DWORD_PTR)NULL);
if (hConnect == NULL)
{
printf("InternetConnectA error %d\n", GetLastError());
goto finally;
}
char *lpszObjectName = "en-us/windows/win32/api/wininet/nf-wininet-internetopenw";
HINTERNET hRequest = HttpOpenRequestA(hConnect, "GET", lpszObjectName, NULL, NULL, NULL, 0, (DWORD_PTR)NULL);
if (hRequest == NULL)
{
printf("HttpOpenRequestA error %d\n", GetLastError());
goto finally;
}
char *lpszHeaders = "Content-Type: application/x-www-form-urlencoded";
BOOL bRet = HttpSendRequestA(hRequest, lpszHeaders, -1, NULL, 0);
if (bRet == FALSE)
{
printf("HttpSendRequestA error %d\n", GetLastError());
goto finally;
}
char buf[1024] = {0};
DWORD dwRead = 0;
do
{
bRet = InternetReadFile(hRequest, buf, 1023, &dwRead);
if (bRet == FALSE)
{
printf("InternetReadFile error %d\n", GetLastError());
goto finally;
}
buf[dwRead] = 0; // ヌル終端
printf(buf);
} while (dwRead > 0);
finally:
if (hRequest != NULL) InternetCloseHandle(hRequest);
if (hConnect != NULL) InternetCloseHandle(hConnect);
if (hInet != NULL) InternetCloseHandle(hInet);
return 0;
}