Вопрос по 32-bit, python, windows – Как правильно использовать win32inet.WinHttpGetProxyForUrl

3

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

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

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 имеет некоторыехорошая документация для функции но аргументы, кажется, не отображают точно таковые из библиотеки python.

Фиксированная версия этого скрипта должна:

Be able to look up which proxy to use for any given URL.

It should always do exactly what Internet Explorer would do (i.e. use the same proxy)

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.

It only needs to work on Windows XP 32bit with Python 2.4.4. It can use any official released version of win32com.

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

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

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

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

Ваш Ответ

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
Ладно, это потрясающая помощь ... и теперь, когда я знаю о ctypes.wintypes, я могу теоретически создать любую структуру, которая мне нравится. Удивительно, насколько полезно иметь один рецепт, с которого можно начинать. Salim Fadhley
1

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

Почему это? Модуль win32inet ненадежен? Salim Fadhley
Ну, если бы это сработало, я полагаю, вы бы не разместили этот вопрос ;-). Вы до сих пор не ответилиarsопрос @ (о том, какую ошибку вы получаете), поэтому я не совсем уверен, с какой проблемой вы сталкиваетесь. Я получаю ошибку getargs, которая указывает на нестандартную передачу аргументов, что является следствием упомянутых ограничений. Vinay Sajip
Да, это ошибка. Аргументы неверны - я просто не уверен, какие из них правильные! Salim Fadhley
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)

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

Похожие вопросы