windows环境下的Python HTTP请求模块
来源:互联网 发布:被芯哪个牌子好 知乎 编辑:程序博客网 时间:2024/05/16 23:50
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
ctypes
from
urlparse
import
urlparse
import
threading
INTERNET_OPEN_TYPE_PRECONFIG
=
0
INTERNET_OPEN_TYPE_PROXY
=
3
INTERNET_OPEN_TYPE_DIRECT
=
1
INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY
=
4
INTERNET_SERVICE_HTTP
=
3
INTERNET_FLAG_RELOAD
=
2147483648
HTTP_ADDREQ_FLAG_REPLACE
=
2147483648
HTTP_ADDREQ_FLAG_ADD
=
536870912
INTERNET_OPEN_TYPE_DIRECT
=
1
INTERNET_FLAG_SECURE
=
8388608
HTTP_QUERY_STATUS_CODE
=
19
wininet
=
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
ret
class
_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
因为wininet无法设置超时,所以模块中的超时是利用Python threading模块来控制。
学Python才几天,如果代码中有写的不对的地方或者是有更好的解决方案,欢迎联系我一起讨论~
代码自由使用,转载需注明原出处
其实Python的学习,只要多看官方doc就可以了。(●´∀`●)
0 0
- windows环境下的Python HTTP请求模块
- windows环境下安装Python的redis扩展模块
- python的http请求模块urllib+requests
- windows环境下python安装 pymssql 模块
- windows的python开发环境下如何安装其他模块(httplib2)
- Windows下用Python 3.4+自带的venv模块创建虚拟环境
- Windows下用Python 3.4+自带的venv模块创建虚拟环境
- windows 下安装 python 的 mysqldb 模块
- windows下Python模块的安装
- Windows下安装Python模块的方法
- windows下安装Python的XlsxWriter模块
- Windows下 Python 模块的安装方法
- windows下安装python的numpy模块
- windows下安装Python的IPy模块
- Windows下Python模块的安装
- Windows下 Python 模块的安装方法
- Windows下Python模块的安装
- python发送http请求之requests模块
- vtk 笔记 --- 图片的X与Y轴变换,旋转
- linux fd 系列
- 第一天
- 2013中国软件技术大会 参会笔录及感想
- 【九度】题目1283:第一个只出现一次的字符
- windows环境下的Python HTTP请求模块
- 英语伤痛十五年
- Android 随笔(二) 真机调试
- 新手开淘宝网店怎样一个月安全达到一钻
- 《无人区》—电影随评
- RHEL 6.4(i386)编译安装GoldenDict
- 黑马程序员--枚举 结构(08)
- 一次痛苦的EasyUI使用和优化历程
- 易语言Excel工作簿方法