ما هي الطريقة الصحيحة لاستخدام win32inet.WinHttpGetProxyForUrl
سؤال
أحاول استخدام ميزة من مايكروسوفت 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 ميزة لمعرفة أي الوكيل هو واحد المناسبة لاستخدام عنوان معين ، الباحث قضيته foo.com.
هل يمكنك مساعدتي في تصحيح جملة من السطر الأخير ؟ MSN بعض وثائق جيدة للحصول على وظيفة يجري ملفوفة ولكن وسائط لا يبدو أن خريطة لتلك بيثون مكتبة تماما.
الثابتة نسخة من هذا البرنامج النصي:
قادرا على البحث عن أي وكيل لاستخدام لأي عنوان URL معين.
ينبغي دائما تفعل بالضبط ما Internet Explorer تفعل (أياستخدام نفس الوكيل)
وينبغي أن تكون صالحة على أي ويندوز XP صالحة انشاء.وهذا يعني أنه يجب أن تعمل مع صراحة تكوين الوكيل و أيضا لا يوجد وكيل في كل شيء.
فإنه يحتاج فقط إلى العمل على ويندوز XP 32bit مع بيثون 2.4.4.فإنه يمكن استخدام أي النسخة الرسمية الصادرة من win32com.
أنا باستخدام Python2.4.4 مع Win32Com على ويندوز XP.
التحديث 0:
أو...هل يمكن أن تعطيني بديل التنفيذ في cTypes?طالما أنا يمكن أن تجعل من العمل أنا سعيد!
المحلول
هنا هو رمز مما يخلق 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
نصائح أخرى
ما لم يكن هناك سبب قوي باستخدام win32inet
(وهو فوضوي في هذا المجال بسبب القيود المفروضة SWIG
) انا ننصح باستخدام ctypes
بدلا من ذلك.
على الأقل مع Python 2.7.6
و Pywin 218
على ويندوز 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)
يمكنك العثور على خيارات أخرى في الرابط أظهرت أعلاه (في القانون)