问题描述
我正在尝试使用 Microsoft WinHttp 库的一项功能,该功能已由 Win32com 的开发人员公开.不幸的是,该库的大部分内容似乎都没有记录,也没有通过 win32com 库使用 win32inet 功能的正确方法示例.
I'm trying to use a feature of the Microsoft WinHttp library that has been exposed by the developers of Win32com. Unfortunately most of the library does not seem to be documented and there are no example of the correct way to use the win32inet features via the win32com library.
这是我目前所拥有的:
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.
As you can see, all I am trying to do is use the win32inet feature to find out which proxy is the appropriate one to use for a given URL, int his case foo.com.
你能帮我更正最后一行的语法吗?MSN 有一些关于被包装函数的良好文档 但 args 似乎没有完美地映射到 python 库的那些.
Can you help me correct the syntax of the last line? MSN has some good documentation for the function being wrapped but the args do not seem to map the to those of the python library perfectly.
这个脚本的固定版本应该:
The fixed version of this script should:
能够查找要使用的代理对于任何给定的 URL.
Be able to look up which proxy to usefor any given URL.
它应该始终与 Internet Explorer 完全相同(即使用相同的代理)
It should always do exactly what Internet Explorer would do (i.e. use the same proxy)
它应该在任何有效的 Windows XP 设置上都有效.这意味着它应该与显式配置的代理一起工作,并且根本没有代理.
It should be valid on any valid Windows XP set-up. That means it should work with an explicitly configured proxy and also no proxy at all.
它只需要在带有 Python 2.4.4 的 Windows XP 32 位上运行.可以使用任何官方发布的win32com版本.
It only needs to work on Windows XP 32bit with Python 2.4.4. It can use any official released version of win32com.
我在 Windows XP 上使用 Python2.4.4 和 Win32Com.
I'm using Python2.4.4 with Win32Com on Windows XP.
更新 0:
或者...你能给我一个 cTypes 的替代实现吗?只要我能成功,我就很高兴!
OR... can you give me an alternative implementation in cTypes? As long as I can make it work I'm happy!
推荐答案
这里是创建 HINTERNET 会话并使用它来获取代理详细信息的代码,使用 ctypes 直接访问 winhttp DLL.它可以正常工作,没有任何错误,但我的机器上没有设置代理,您可能需要调整一些常量才能使其正确.浏览代码中的 msdn 链接,从那里我看到了 API.
Here is the code which creates HINTERNET session and uses that to get proxy details, using ctypes to directly access winhttp DLL.It works without any error but I have no proxy set on my machine, you may have to tweak few constants to get it right. Go thru the msdn links in code, from where I have seen the 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
这篇关于使用 win32inet.WinHttpGetProxyForUrl 的正确方法是什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!