python wininet封装模块,pythonwininet封装,windows对Inte


windows对Internet的封装wininet库支持代理,ssl,cookie自动保存,完爆urllib,但是可惜只支持windows,这里就把Python调用这个库的代码发上来。

模块的唯一一个方法会返回header和content,如果有需要可以自行修改HttpQueryInfoA函数的参数来查询其他http属性。

#coding:utf-8import ctypesfrom urlparse import urlparseimport threadingINTERNET_OPEN_TYPE_PRECONFIG = 0INTERNET_OPEN_TYPE_PROXY = 3INTERNET_OPEN_TYPE_DIRECT = 1INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY = 4INTERNET_SERVICE_HTTP = 3INTERNET_FLAG_RELOAD = 2147483648HTTP_ADDREQ_FLAG_REPLACE = 2147483648HTTP_ADDREQ_FLAG_ADD= 536870912INTERNET_OPEN_TYPE_DIRECT = 1INTERNET_FLAG_SECURE = 8388608HTTP_QUERY_STATUS_CODE = 19wininet = ctypes.windll.LoadLibrary('wininet.dll')class wininetHttp():    def httpRequest(self,url,method="GET",proxy="",username="",password="",headers="",data="",timeout=20):        """        发出一个HTTP请求        参数:        url: 完整网址        method: 请求方法,可以是GET或POST        proxy: 代理地址        username: 用户名        password: 密码        headers: 协议头        data: 提交数据        timeout: 请求超时值        返回值:        元组(header,html)        """        requestThread = _httprequest(url,method,proxy,username,password,headers,data)        requestThread.daemon = True #线程随主线程一起退出        requestThread.start()        requestThread.join(timeout)        ret = requestThread.getResponse()        return retclass _httprequest(threading.Thread):    response = (0,'')    def __init__(self,url,method,proxy,username,password,headers,data):        threading.Thread.__init__(self)        self.url = url        self.url_info = urlparse(url)        self.method = method        self.proxy = proxy        self.username = username        self.password = password        self.headers = headers        self.data = data    def run(self):        dwAccessType = self.proxy and INTERNET_OPEN_TYPE_PROXY or INTERNET_OPEN_TYPE_DIRECT        lpszProxyName = self.proxy and 'http=' + self.proxy or None        lpszAgent = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.72 Safari/537.36'        hOpen = wininet.InternetOpenA(lpszAgent,dwAccessType,lpszProxyName,None,0)        if not hOpen:            return        nServerPort = (self.url_info.scheme == 'https') and 443 or 80        hConn = wininet.InternetConnectA(hOpen,self.url_info.netloc.lower(),nServerPort,self.username,self.password,INTERNET_SERVICE_HTTP,0,0)        if not hConn:            wininet.InternetCloseHandle(hOpen)            return        dwFlags = (self.url_info.scheme == 'https') and INTERNET_FLAG_SECURE or INTERNET_FLAG_RELOAD        hRequest = wininet.HttpOpenRequestA(hConn,self.method,self.url_info.path,'HTTP/1.1',None,0,dwFlags,0)        if not hRequest:            wininet.InternetCloseHandle(hConn)            wininet.InternetCloseHandle(hOpen)            return        if not 'Accept: ' in self.headers:            self.headers += 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\\r\\n'        if not 'Referer: ' in self.headers:            self.headers += 'Referer: %s\\r\\n' % self.url        if not 'Accept-Language: ' in self.headers:            self.headers += 'Accept-Language: zh-CN,zh;q=0.8\\r\\n'        if self.method.upper() == 'GET':            wininet.HttpSendRequestA(hRequest, self.headers,len(self.headers),None, 0)        elif self.method.upper() == 'POST':            if self.data != '':                if not 'Content-Type: ' in self.headers:                    self.headers = self.headers + "Content-Type: application/x-www-form-urlencoded\\r\\n"                self.headers = self.headers + "Content-Length: %s\\r\\n" % len(self.data)            wininet.HttpSendRequestA(hRequest, self.headers,len(self.headers),self.data,len(self.data))        else:            wininet.InternetCloseHandle(hRequest)            wininet.InternetCloseHandle(hConn)            wininet.InternetCloseHandle(hOpen)            return        data_buf = (ctypes.c_char * 2048)()        ret_data = ''        x = ctypes.c_int(1)        while x.value != 0:            wininet.InternetReadFile(hRequest,data_buf,2048,ctypes.byref(x))            buf = (ctypes.c_char * x.value)()            ctypes.memmove(buf,data_buf,x.value)            ret_data += buf[:x.value]        head_buf = ctypes.create_string_buffer(2048)        buf_size = ctypes.c_int(2048)        wininet.HttpQueryInfoA(hRequest,22,head_buf,ctypes.byref(buf_size),0)        wininet.InternetCloseHandle(hRequest)        wininet.InternetCloseHandle(hConn)        wininet.InternetCloseHandle(hOpen)        self.response = (head_buf.value,ret_data)        return    def getResponse(self):        return self.response#该片段来自于http://byrx.net

评论关闭