3

我正在尝试使用已由 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,例如 foo.com。

你能帮我纠正最后一行的语法吗?MSN为被包装的函数提供了一些很好的文档,但 args 似乎并没有完美地映射到 python 库的那些。

此脚本的固定版本应:

  • 能够查找用于任何给定 URL 的代理。

  • 它应该总是做 Internet Explorer 会做的事情(即使用相同的代理)

  • 它应该在任何有效的 Windows XP 设置上都有效。这意味着它应该与明确配置的代理一起使用,并且根本没有代理。

  • 它只需要在带有 Python 2.4.4 的 Windows XP 32bit 上工作。它可以使用任何官方发布的win32com版本。

我在 Windows XP 上使用 Python2.4.4 和 Win32Com。

更新0:

或者......你能给我一个 cTypes 的替代实现吗?只要我能成功,我就很高兴!

4

3 回答 3

6

这是创建 HINTERNET 会话并使用它来获取代理详细信息的代码,使用 ctypes 直接访问 winhttp DLL。它可以正常工作,但我的机器上没有设置代理,您可能需要调整一些常量才能使其正确。通过代码中的 msdn 链接,我从那里看到了 API。

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
于 2009-07-08T06:09:28.317 回答
1

除非有强烈的使用理由win32inet(由于 的限制,这在这方面很混乱SWIG),否则我建议您ctypes改用。

于 2009-07-07T13:50:57.603 回答
1

至少在 Windows XP x86Python 2.7.6Pywin 218Windows 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

值得一提的是,该示例使用自动代理选项 WINHTTP_AUTOPROXY_CONFIG_URL 来传递显式 URL。您可以使用其他选项,例如,如果您想使用 DNS 或 DHCP 进行自动检测,您可以执行以下操作:

autoproxy_options = (1, 1|2, u"", None, 0, 1)

您可以在上面显示的链接中找到其他选项(在代码中)

于 2014-01-14T15:37:42.807 回答