介绍
介绍
福哥今天要给大家分享一个基于urllib3的http客户端请求对象,大家都知道urllib库是Python用来模拟HTTP请求的,通过urllib库可以使用HTTP协议的GET/POST/PUT/DELETE等等请求。
模拟POST请求时候,可以传入POST数据,支持表单提交方式(application/x-www-form-urlencoded)和JSON方式(application/json)两种数据类型。
可以自定义HTTP头信息,最常用的就是修改浏览器信息(User-Agent)来达到欺骗服务器的目的。比如:我们设置了浏览器信息是一个iPhone端的Safari浏览器,服务器就会返回一个手机端的页面给我们。
可以自定义Cookie信息,绝大部分的网站的登录信息都是通过Cookie实现的,如果我们可以拿到有效的Cookie信息就可以欺骗服务器,让服务器将授权资源内容返回给我们。
TFHttpClient
介绍
urllib3是最新版本库,它有着非常强大的功能支持,还有着非常友好的对象结构设计,最主要的是无论是Python2.7还是Python3都可以使用它,所以福哥选择了urllib3做为依赖库。
福哥设计的这个TFHttpClient是一个仿照Java的Spring框架的WebClient对象的设计风格,就是在调用的时候每一步都是方法调用另一个方法这样的形式,这种设计现在非常主流,看看福哥是怎样实现的吧!
依赖
TFHttpClient依赖urllib、urllib3、json三个库,如果环境里没有的话可以通过pip直接安装。
pip install urllib pip install urllib3
属性
属性比较简单,福哥就在代码里通过注释给一一介绍一下吧
# http 句柄,用来调用urllib3的功能 http = urllib3.PoolManager() # 请求方法 method = "" # 请求URL地址 url = "" # 请求QUERY_STRING params = {} # 表单提交数据 formData = None # JSON数据 jsonData = None # 自定义HTTP头信息 myHeaders = {} # 自定义Cookie信息 myCookies = ""
方法
get
启动一个GET方式的请求
def get(self, url, params=None): self.method = "get" self.url = url if params is not None: self.params = params return self
postForm
启动一个POST方式的请求,请求数据采用表单提交类型
def postForm(self, url, params=None, data=None): self.method = "post" self.url = url if params is not None: self.params = params if data is not None: self.formData = data return self
posJson
启动一个POST方式的请求,请求数据采用JSON类型
def postJson(self, url, params=None, data=None): self.method = "post" self.url = url if params is not None: self.params = params if data is not None: self.jsonData = data return self
cookies
设置Cookie信息,参数是一个对象类型
def cookies(self, cookies): self.myCookies = urllib.urlencode(cookies, True) self.myCookies = self.cookies.replace("&", "; ") return self
headers
设置HTTP信息,参数是一个对象类型
def headers(self, headers): self.myHeaders = headers return self
call
这是核心方法,负责组织请求信息,发送请求数据。如果请求失败会抛出异常,如果请求不是预期状态码也会抛出异常。
def call(self, charset="utf-8", wishStatus=200): # prepare if self.myCookies != "": self.myHeaders["Cookie"] = self.myCookies # request res = None if self.method == "get": myUrl = self.url myQuery = urllib.urlencode(self.params, True) if myQuery != "": if "?" not in myUrl: myUrl += "?" + myQuery else: myUrl += "&" + myQuery res = self.http.request(self.method, myUrl, headers=self.myHeaders) elif self.method == "post": myUrl = self.url myQuery = urllib.urlencode(self.params, True) if myQuery != "": if "?" not in myUrl: myUrl += "?" + myQuery else: myUrl += "&" + myQuery myBody = "" if self.formData is not None: self.myHeaders['Content-Type'] = "application/x-www-form-urlencoded" myBody = urllib.urlencode(self.formData, True) elif self.jsonData is not None: self.myHeaders['Content-Type'] = "application/json" myBody = json.dumps(self.jsonData) res = self.http.request(self.method, myUrl, body=myBody, headers=self.myHeaders) # result if res is not None: if res.status == wishStatus: return res else: raise Exception("Error: invalid status " + str(res.status)) else: raise Exception("Error: no response")
使用
代码
可以看到调用方法的过程没有一个赋值操作,全部都是方法调用,这种写法使代码结构很清晰。
因为Python的代码必须写一行上面,为了可以每一行写一个命令,需要在最外面放一个“()”把全部调用过程括起来。
总结
福哥今天带着童鞋们实现一个Python基于urllib3的http客户端请求对象——TFHttpClient,这个TFHttpClient的设计风格仿照的是Java的Spring框架的WebClient对象的,这种设计风格写出来的代码结构非常清晰,可读性非常好。