Win32inet.winhttpgetProxyForurl을 사용하는 올바른 방법은 무엇입니까?
문제
Win32com의 개발자가 노출 한 Microsoft Winhttp 라이브러리의 기능을 사용하려고합니다. 불행히도 대부분의 라이브러리는 문서화되지 않은 것으로 보이며 Win32com 라이브러리를 통해 Win32Inet 기능을 사용하는 올바른 방법의 예는 없습니다.
이것이 내가 지금까지 가지고있는 것입니다.
import win32inet
hinternet = win32inet.InternetOpen("foo 1.0", 0, "", "", 0)
# Does not work!!!
proxy = win32inet.WinHttpGetProxyForUrl( hinternet, u"http://www.foo.com", 0 )
보시다시피, 내가하려는 것은 Win32Inet 기능을 사용하여 주어진 URL에 사용하기에 적합한 프록시인지 확인하는 것입니다.
마지막 줄의 구문을 수정하도록 도와 줄 수 있습니까? MSN에는 일부가 있습니다 래핑되는 기능에 대한 좋은 문서 그러나 Args는 Python 라이브러리의 것들에 완벽하게 매핑되지 않는 것 같습니다.
이 스크립트의 고정 된 버전은 다음과 같습니다.
특정 URL에 사용할 프록시를 찾을 수 있습니다.
인터넷 익스플로러가 할 일을 항상 정확하게 수행해야합니다 (즉, 동일한 프록시를 사용합니다)
유효한 Windows XP 설정에서 유효해야합니다. 즉, 명시 적으로 구성된 프록시로 작동하고 프록시가 전혀 없어야합니다.
Python 2.4.4와 함께 Windows XP 32 비트에서만 작동하면됩니다. 공식 릴리스 버전의 Win32com을 사용할 수 있습니다.
Windows XP에서 Win32com과 함께 Python2.4.4를 사용하고 있습니다.
업데이트 0 :
아니면 ... CTYPES에서 대체 구현을 줄 수 있습니까? 내가 작동하게 할 수있는 한 나는 행복하다!
해결책
다음은 Hinternet Session을 생성하고이를 사용하여 CTYPES를 사용하여 WinHTTP DLL에 직접 액세스하는 데있어 프록시 세부 정보를 얻는 코드입니다. 오류없이 작동하지만 내 컴퓨터에 프록시가 설정되어 있지 않으므로 제대로 얻기 위해 상수를 조정해야 할 수도 있습니다. API를 본 곳에서 코드에서 MSDN 링크를 통해 이동하십시오.
import ctypes
import ctypes.wintypes
winHttp = ctypes.windll.LoadLibrary("Winhttp.dll")
# http://msdn.microsoft.com/en-us/library/aa384098(VS.85).aspx
# first get a handle to HTTP session
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY=0
WINHTTP_NO_PROXY_NAME=WINHTTP_NO_PROXY_BYPASS=0
WINHTTP_FLAG_ASYNC=0x10000000
HINTERNET = winHttp.WinHttpOpen("PyWin32", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, WINHTTP_FLAG_ASYNC)
print HINTERNET
# now get proxy using HTTP session
# http://msdn.microsoft.com/en-us/library/aa384097(VS.85).aspx
"""
BOOL WinHttpGetProxyForUrl(
__in HINTERNET hSession,
__in LPCWSTR lpcwszUrl,
__in WINHTTP_AUTOPROXY_OPTIONS *pAutoProxyOptions,
__out WINHTTP_PROXY_INFO *pProxyInfo
);
"""
# create C structure for WINHTTP_AUTOPROXY_OPTIONS
#http://msdn.microsoft.com/en-us/library/aa384123(VS.85).aspx
"""
typedef struct {
DWORD dwFlags;
DWORD dwAutoDetectFlags;
LPCWSTR lpszAutoConfigUrl;
LPVOID lpvReserved;
DWORD dwReserved;
BOOL fAutoLogonIfChallenged;
} WINHTTP_AUTOPROXY_OPTIONS;
"""
class WINHTTP_AUTOPROXY_OPTIONS(ctypes.Structure):
_fields_ = [("dwFlags", ctypes.wintypes.DWORD),
("dwAutoDetectFlags", ctypes.wintypes.DWORD),
("lpszAutoConfigUrl", ctypes.wintypes.LPCWSTR),
("lpvReserved", ctypes.c_void_p ),
("dwReserved", ctypes.wintypes.DWORD),
("fAutoLogonIfChallenged",ctypes.wintypes.BOOL),]
WINHTTP_AUTOPROXY_AUTO_DETECT = 0x00000001;
WINHTTP_AUTO_DETECT_TYPE_DHCP = 0x00000001;
WINHTTP_AUTO_DETECT_TYPE_DNS_A = 0x00000002;
options = WINHTTP_AUTOPROXY_OPTIONS()
options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT
options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP|WINHTTP_AUTO_DETECT_TYPE_DNS_A
options.lpszAutoConfigUrl = 0
options.fAutoLogonIfChallenged = False
# create C structure for WINHTTP_AUTOPROXY_OPTIONS
# http://msdn.microsoft.com/en-us/library/aa383912(VS.85).aspx
"""
struct WINHTTP_PROXY_INFO {
DWORD dwAccessType;
LPWSTR lpszProxy;
LPWSTR lpszProxyBypass;
};
"""
class WINHTTP_PROXY_INFO(ctypes.Structure):
_fields_ = [("dwAccessType", ctypes.wintypes.DWORD),
("lpszProxy", ctypes.wintypes.LPCWSTR),
("lpszProxyBypass", ctypes.wintypes.LPCWSTR),]
info = WINHTTP_PROXY_INFO()
ret = winHttp.WinHttpGetProxyForUrl(HINTERNET, "http://www.google.com", ctypes.pointer(options), ctypes.pointer(info) )
print "proxy success?",ret
if not ret:
# some error lets see what is that?
import win32api
import win32con
errorCode = win32api.GetLastError()
print "win32 Error:",errorCode
s = ""
print win32api.FormatMessage(errorCode)
print info.dwAccessType, info.lpszProxy, info.lpszProxyBypass
다른 팁
사용해야 할 강력한 이유가 없다면 win32inet
(이 영역에서 지저분합니다. SWIG
), 나는 당신이 사용하는 것이 좋습니다 ctypes
대신에.
적어도 Python 2.7.6
그리고 Pywin 218
Windows XP X86 및 Windows 8 X64에서는 다음과 같습니다.
import win32inet
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa384098(v=vs.85).aspx
hinternet = win32inet.WinHttpOpen("foo", 0, "", "", 0)
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa384123(v=vs.85).aspx
autoproxy_options = (2, 0, u"http://your-proxy-script-path", None, 0, 1)
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa384097(v=vs.85).aspx
proxy = win32inet.WinHttpGetProxyForUrl(hinternet, u"http://www.google.com",
autoproxy_options)
print proxy
이 예제는 명시 적 URL을 통과시키기 위해 Autoproxy 옵션 Winhttp_autoProxy_Config_url을 사용합니다. 예를 들어 DNS 또는 DHCP를 사용하여 자동으로 설정하려면 다른 옵션을 사용할 수 있습니다.
autoproxy_options = (1, 1|2, u"", None, 0, 1)
위에 표시된 링크에서 다른 옵션을 찾을 수 있습니다 (코드에서)