Domanda

Sto cercando di utilizzare una funzione della libreria di Microsoft WinHttp che è stata esposta dagli sviluppatori di Win32com. Purtroppo la maggior parte della biblioteca non sembra essere documentati e non ci sono esempio del modo corretto di utilizzare le funzioni win32inet tramite la libreria win32com.

Questo è quello che ho finora:

import win32inet
hinternet = win32inet.InternetOpen("foo 1.0", 0, "", "", 0)
# Does not work!!!
proxy = win32inet.WinHttpGetProxyForUrl( hinternet, u"http://www.foo.com", 0  )

Come si può vedere, tutto quello che sto cercando di fare è utilizzare la funzione win32inet per scoprire quale proxy è quello appropriato da utilizzare per un determinato URL, int il suo caso foo.com.

Potete aiutarmi a correggere la sintassi dell'ultima riga? MSN ha qualche buona documentazione per la funzione di essere avvolto ma i args non sembrano per mappare la a quelli della libreria Python perfettamente.

La versione fissa di questo script dovrebbe:

  • Essere in grado di guardare in alto, che proxy da utilizzare per ogni URL.

  • Si deve sempre fare esattamente quello che Internet Explorer avrebbe fatto (vale a dire utilizzare lo stesso proxy)

  • Dovrebbe essere valida su qualsiasi Windows XP set-up valido. Ciò significa che dovrebbe funzionare con un proxy esplicitamente configurato e anche nessun proxy a tutti.

  • Si ha solo bisogno di lavorare su Windows XP a 32 bit con Python 2.4.4. E 'possibile utilizzare qualsiasi versione ufficiale rilasciata di win32com.

Sto usando Python2.4.4 con Win32Com su Windows XP.

UPDATE 0:

O ... Mi può dare un'implementazione alternativa a ctypes? Finché posso farlo funzionare sono felice!

È stato utile?

Soluzione

Ecco il codice che crea sessione HINTERNET e lo utilizza per ottenere dati proxy, utilizzando ctypes per accedere direttamente DLL winhttp. Funziona senza alcun errore ma non ho impostato delega sulla mia macchina, potrebbe essere necessario modificare alcune costanti per farlo bene. Passare attraverso i collegamenti MSDN nel codice, da dove ho visto l'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

Altri suggerimenti

A meno che non v'è una forte ragione per usare win32inet (che è disordinato in questo settore a causa di limitazioni di SWIG), vi consiglio di utilizzare ctypes invece.

Almeno con Python 2.7.6 e Pywin 218 su Windows XP x86 e Windows 8 x64, funziona:

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

Vale la pena di ricordare che l'esempio utilizza l'opzione WINHTTP_AUTOPROXY_CONFIG_URL proxy automatico per passare a un URL esplicita. È possibile utilizzare altre opzioni, per esempio, se si desidera rilevare automaticamente utilizzando DNS o DHCP si può fare:

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

Si possono trovare altre opzioni nel link mostrato sopra (nel codice)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top