前面我们使用过fiddler、postman等工具完成请求的发送,那么在python中如何实现呢?在python中urllib是发送请求最基本的库,且为python的内置库,该库只需要关注请求的链接,参数,提供了强大的解析。在Python2中主要为urllib和urllib2,在Python3中整合成了urllib。而urllib3则是增加了连接池等功能,两者互相都有补充的部分。
urllib、urllib2、urllib3用法及区别
Python2.x有这些库名可用: urllib,urllib2,urllib3,httplib,httplib2,requests。
Python3.x 有这些库名可用: urllib,urllib3,httplib2,requests。
若只使用Python3.x,记住有个urllib的库就行了。Pyhton2.x和Python3.x都有urllib3和requests, 它们不是标准库。urllib3提供线程安全连接池和文件post等支持,与urllib及urllib2的关系不大。requests 自称HTTP for Humans,使用更简洁方便。
Python3.x中将urllib2合并到了urllib,之后此包分成了以下几个模块:
- urllib.request 用于打开和读取URL
- urllib.error 用于处理前面request引起的异常
- urllib.parse 用于解析URL
- urllib.robotparser用于解析robots.txt文件
Python3.x中,随着urllib2合入urllib,一些常用的方法也发生了变化:
- 在Python2.x中使用import urlparse
在Python3.x中会使用import urllib.parse - 在Python2.x中使用urllib2.urlopen或urllib.urlopen(已弃用)
在Python3.x中会使用urllib.request.urlopen - 在Python2.x中使用urllib2.Request
在Python3.x中会使用urllib.request.Request - 在Python2.x中使用urllib.quote
在Python3.x中会使用urllib.request.quote - 在Python2.x中使用urllib.urlencode
在Python3.x中会使用urllib.parse.urlencode - 在Python2.x中使用cookielib.CookieJar
在Python3.x中会使用http.CookieJar
注:在Python3.3后urllib2已经不能再用,所有urllib2全部用urllib.request来代替。
urlib.request
get请求
#gettests.py
from urllib import request
reponse = request.urlopen('http://127.0.0.1:8888/LoginIndexFunction')
print(reponse.read().decode("utf-8"))
注意:这里通过响应对象可以调用read方法获取响应结果,但是结果是byte对象,需要获取具体的字符串对象的话,则需要调用decode方法实现指定的编码格式解码字符串。
post请求
#posttests.py
from urllib import request,parse
data={
"customer_name": "woodProgram1",
"customer_phone": "13322222222",
"customer_mail": "123456@163.com",
"customer_type": "C",
"customer_address": "广州天河"
}
params=bytes(parse.urlencode(data),encoding="utf-8")
#get_response=request.urlopen("http://127.0.0.1:7777/addCustomer?%s"%params)
#下面默认发送请求的方式是GET,如果需要使用POST的话,则必须声明data参数
#注意:此处如果是post的话,其参数除了要urlencode编码以外还要完成encode编码,并编码成ascii码
get_response = request.urlopen("http://127.0.0.1:8888/addCustomer",data=params)
print(get_response.read().decode("utf-8"))
或者以下代码
from urllib import request,parse
data={
"customer_name": "woodProgram1",
"customer_phone": "18907047890",
"customer_mail": "fjwojefo@163.com",
"customer_type": "C",
"customer_address": "广州天河"
}
params=parse.urlencode(data)
get_response=request.urlopen("http://127.0.0.1:7777/addCustomer",data=params.encode("ascii"))
print(get_response.read().decode())
观察两段代码发现没,在使用urllib发送post请求时,其携带的参数必须是通过parse模块进行解析的,且data参数传入的类型必须是一个byte对象。所以可以在传入之前将参数进行转码成byte对象,或者在传入的时候声明其编码格式ASCII码,即可完成请求的发送。
urllib.parse
urllib.parse是urllib中用来解析各种数据格式的模块。在url中,不能使用ASCII不包含的特殊字符、中文等。将中文字符加入到url中:
- quote():将特殊字符进行url编码,转换成可以url可以传输的格式
- unquote():将编码后的数据转换回来
from urllib import parse
keyword = '北京海淀'
print(parse.quote(keyword))
print(parse.unquote('%E5%8C%97%E4%BA%AC%E6%B5%B7%E6%B7%80'))
超时判断
from urllib import request,parse,error
import socket
data={
"customer_name": "woodProgram3",
"customer_phone": "13324445553",
"customer_mail": "4563@163.com",
"customer_type": "C",
"customer_address": "北京"
}
params=bytes(parse.urlencode(data),encoding="utf-8")
try:
get_response=request.urlopen("http://127.0.0.1:8888/addCustomer",data=params,timeout=0.001)
print(get_response.read().decode("utf-8"))
except Exception as e:
if isinstance(e,socket.timeout):#判断错误原因
print('time out!')
urlib.error
在urllib中主要设置了两个异常,一个是URLError,一个是HTTPError,HTTPError是URLError的子类。
HTTPError还包含了三个属性:
- code:请求的状态码
- reason:错误的原因
- headers:响应的报头
from urllib import request
from urllib import error
if __name__ == "__main__":
#一个不存在的连接
url = "http://127.0.0.1:8888/LoginIndexFunctio"
req = request.Request(url)
try:
get_response= request.urlopen(req)
except error.URLError as e:
if hasattr(e, 'code'):
print("HTTPError")
print(e.code)
elif hasattr(e, 'reason'):
print("URLError")
print(e.reason)
响应类型,状态码,响应头
from urllib import request
from urllib import error
if __name__ == "__main__":
#一个存在的连接
url = "http://127.0.0.1:8888/LoginIndexFunction"
req = request.Request(url)
try:
get_response = request.urlopen(req)
except error.URLError as e:
if hasattr(e, 'code'):
print("HTTPError")
print(e.code)
elif hasattr(e, 'reason'):
print("URLError")
print(e.reason)
# 返回响应结果
print(get_response.read().decode())
# 返回状态码
print(get_response.getcode())
# 返回响应头
print(get_response.getheaders())
# 获取url
print(get_response.geturl())