2009-07-03 3 views
3

Я пытаюсь использовать функцию библиотеки Microsoft WinHttp, которая была открыта разработчиками Win32com. К сожалению, большая часть библиотеки, похоже, не документирована, и нет примера правильного использования функций win32inet через библиотеку win32com.Каков правильный способ использования win32inet.WinHttpGetProxyForUrl

Это то, что я до сих пор:

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 есть good documentation for the function being wrapped, но аргументы, похоже, не отлично сопоставляют их с библиотеками python.

Фиксированная версия этого скрипта необходимо:

  • Уметь посмотреть, какой прокси использовать для любого заданного URL.

  • Он должен всегда делать то, что будет делать Internet Explorer (то есть использовать один и тот же прокси-сервер)

  • Он должен быть действительным на любом допустимом Windows XP вверх установленный. Это означает, что он должен работать с явно настроенным прокси-сервером, а также без прокси-сервера.

  • Необходимо только работать с Windows XP 32bit с Python 2.4.4. Он может использовать любую официальную выпущенную версию win32com.

Я использую Python2.4.4 с Win32Com в Windows XP.

ОБНОВЛЕНИЕ 0:

ИЛИ ... Вы можете дать мне альтернативную реализацию в cTypes? Пока я могу заставить его работать, я счастлив!

+0

Когда вы пишете «Не работает !!!»: есть ли сообщение об ошибке? результат отличается от того, что вы ожидаете? и т. д. Пожалуйста, предоставьте дополнительную информацию. – ars

ответ

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 
+0

Хорошо, это потрясающая помощь ... и теперь, когда я начинаю рассказывать о типах ctypes.wintypes, я могу теоретически создать любую структуру, которая мне нравится. это удивительно, как полезно просто иметь один рецепт, чтобы начать с. –

1

Если нет веских причин для использования win32inet (что является беспорядочным в этой области из-за ограничений SWIG), я рекомендую вместо этого использовать ctypes.

+0

Почему? Является ли модуль win32inet ненадежным? –

+0

Ну, если бы это сработало, я полагаю, вы бы не отправили этот вопрос ;-). Вы все еще не ответили на вопрос 'ars' (о том, какую ошибку вы получаете), поэтому я не совсем уверен, в чем проблема, с которой вы столкнулись. Я получаю ошибку getargs, которая указывает на нестандартную передачу аргументов, что является следствием ограничений, о которых я упоминал. –

+0

Да, это ошибка. Аргументы неправильные - я просто не уверен, что это за правильные! –

1

По крайней мере, с 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 

Стоит отметить, что в данном примере используется autoproxy варианта WINHTTP_AUTOPROXY_CONFIG_URL для того, чтобы пройти в явном URL.Вы можете использовать и другие варианты, например, если вы хотите, автоопределение с помощью DNS или DHCP вы можете сделать:

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

Вы можете найти другие варианты в ссылку показано выше (в коде)