前面我们使用过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'))

python接口测试:1.9 Python中urllib详细应用_状态码


超时判断

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!')

python接口测试:1.9 Python中urllib详细应用_字符串_02

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)

python接口测试:1.9 Python中urllib详细应用_状态码_03


响应类型,状态码,响应头

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())


python接口测试:1.9 Python中urllib详细应用_状态码_04