windows环境下的Python HTTP请求模块
2013年8月18日 2条评论 Article
网络上关于Python的HTTP请求大部分都是利用了urllib,httplib,pycurl,但是经过我试用之后,都没有对cookie以及ssl良好的支持,所以本模块主要使用了wininet API来发送HTTP请求,经过测试之后,wininet库很好的封装了ssl,cookie的支持,因此将wininet库在Python中的调用方式公开。
因为wininet是windows对Internet的封装,所以只支持windows系统。
在Linux下,我们可以选择curl库来执行http请求。 PS : chrome的网络请求就是使用了curl。
Python中对curl的封装有pycurl,但是pycurl的作者封装的curl是不带ssl版本,所以无法发起https请求,在这里就不提了,有兴趣的朋友可以访问pycurl的下载地址来试用。
上代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
#coding:utf-8 import
from
import
import
INTERNET_OPEN_TYPE_PRECONFIG =
INTERNET_OPEN_TYPE_PROXY =
INTERNET_OPEN_TYPE_DIRECT =
INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY =
INTERNET_SERVICE_HTTP =
INTERNET_FLAG_RELOAD =
HTTP_ADDREQ_FLAG_REPLACE =
HTTP_ADDREQ_FLAG_ADD =
INTERNET_OPEN_TYPE_DIRECT =
INTERNET_FLAG_SECURE =
HTTP_QUERY_STATUS_CODE =
wininet =
'wininet.dll' ) class
def
self ,url,method = "GET" ,proxy = " ",username=" ",password=" ",headers=" ",data=" ",timeout = 20 ): """ 发出一个HTTP请求 参数: url: method: proxy: username: password: headers: data: timeout: 返回值: 元组(header,html) """ requestThread =
requestThread.daemon =
requestThread.start() requestThread.join(timeout) ret =
return
class
response =
0 ,'') def
self ,url,method,proxy,username,password,headers,data): threading.Thread.__init__( self ) self .url =
self .url_info =
self .method =
self .proxy =
self .username =
self .password =
self .headers =
self .data =
def
self ): dwAccessType =
.proxy and
or
lpszProxyName =
.proxy and
.proxy or
lpszAgent =
hOpen =
None , 0 ) if
return nServerPort =
self .url_info.scheme = =
) and
hConn =
self .url_info.netloc.lower(),nServerPort, self .username, self .password,INTERNET_SERVICE_HTTP, 0 , 0 ) if
wininet.InternetCloseHandle(hOpen) return dwFlags =
self .url_info.scheme = =
) and
or
hRequest =
self .method, self .url_info.path, 'HTTP/1.1' , None , 0 ,dwFlags, 0 ) if
wininet.InternetCloseHandle(hConn) wininet.InternetCloseHandle(hOpen) return if
.headers: self .headers + =
if
.headers: self .headers + =
.url if
.headers: self .headers + =
if
.method.upper() = =
: wininet.HttpSendRequestA(hRequest, self .headers, len ( self .headers), None , 0 ) elif
.method.upper() = =
: if
.data =
if
.headers: self .headers =
.headers +
self .headers =
.headers +
( 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 =
*
)() ret_data =
x =
1 ) while
=
: wininet.InternetReadFile(hRequest,data_buf, 2048 ,ctypes.byref(x)) buf =
*
ctypes.memmove(buf,data_buf,x.value) ret_data + =
head_buf =
2048 ) buf_size =
2048 ) wininet.HttpQueryInfoA(hRequest, 22 ,head_buf,ctypes.byref(buf_size), 0 ) wininet.InternetCloseHandle(hRequest) wininet.InternetCloseHandle(hConn) wininet.InternetCloseHandle(hOpen) self .response =
return def
self ): return
.response |
因为wininet无法设置超时,所以模块中的超时是利用Python threading模块来控制。
学Python才几天,如果代码中有写的不对的地方或者是有更好的解决方案,欢迎联系我一起讨论~
代码自由使用,转载需注明原出处
其实Python的学习,只要多看官方doc就可以了。(●´∀`●)