RESTful
flask-restful:
我他么的,蓝图最终还是不能在restful中使用。。不过也不需要蓝图来使用。。一样可以拆分为多个,但是不能像java一样,一个函数响应两个访问方法。
在新建立一个api类,继承自Resource。在里面写 get/post方法
然后通过
api.add_resource(HelloResource,'/hello')
来写下来路由。
- 注意事项: return {‘mes’:‘usr list’}。中间一定是:
了解一下其他的rest库
-
flask-restless:
- 直接将数据模型和restful-api联系到一起。太重了
-
flask-rest-jsonapi:
- 更加轻量级
重点学习flask-restful
- endpoint:用于反向解析出url。默认是函数名。前后端分离,基本上不需要写 endpoint。
- 总体写法上来看,还是不太满意一个资源对象对应一个get or post方法,可能是我自己不太习惯
- 另外可以在对象上面进行save方法进行封装。
- json中 Response格式:
"""JSON , Respons
单个对象的格式:
{
"status" :200,
"meg" : "ok",
"data" : {
"property":"value",
"property":"value",
"property":"value",
}
}
多个对象的格式:
{
"status" :200,
"meg" : "ok",
"data" : [
{
"property":"value",
"property":"value",
"property":"value",
},
{
"property":"value",
"property":"value",
"property":"value",
},//json object
{
"property":"value",
"property":"value",
"property":"value",
}//json object
]
}
"""
代码中也有记下:
data:object是不能够使用的,会报错。对象不能json序列化
解决方案:使用格式化工具
- @marshal_with('格式字典‘),装饰器
- marshal(数据,格式字典(模版)) 函数
- 需要一个格式字典,里面对象的类型字典
例如:
goods_fields = {
'g_name' : fields.String,
'g_price' : fields.Float
}
嵌套使用:
goods_data_fields = {
'status': fields.Integer,
'meg' : fields.String,
'data' : fields.Nested(goods_fields)
}
-
如果某一个字段写在格式模版里面,但是传入数据对应起来里面没有这个字段的,那么默认为null
-
如果模版字段少于数据,那么只显示模版格式字段
-
总而言之,以格式模版为主。
-
get goods List:使用fields.List()
例如:
goodsList_data_fields = {
'status': fields.Integer,
'meg': fields.String,
'data': fields.List(fields.Nested(goods_fields))
}
- 定好api输出模版格式重要。没有输入数据,输出null即可
- 模版设置,输出时候的别名
- 一般来说模版中的key要和数据中的key一样
- fields.String(attribute = ‘g_name’)
'name' : fields.String(attribute='g_name')
-
模版指定默认值,default_value: default=‘xxx’
-
fields:
- Raw(基类)
- format
- output
- 调用顺序,先调用output,获取值,然后调用format再对值进行格式化(不同类型的格式,比如int,Stirng的format方法不同,将结果进行格式化)
- 各种类型比如
- bool
- int
- String
- url:反向解决url吗,fields.Url(‘endpoint(默认类名小写,或者add的时候自己指定)’ )
- Raw(基类)
-
delete 方法,删除
-
put 方法,更新
-
patch 方法,差量更新,没有传的值,从查到的值里面,用旧的值。
name = c_name or goods.c_name
- abort()结束。可以添加说明
abort(404,message=‘good no exist’,meg=‘fail’),也可以扩充自带的状态码
Request参数
- Request参数转换(其实就是封装request.form 参数)
RequestParser - 先定义一个RequestParser对象,然后向对象中添加字段,然后从对象中获取字段
- 对象在添加参数的时候,可以实现数据的预校验(参数是否必须,进行数据的类型限制,设置提示)
parser = reqparse.RequestParser()
parser.add_argument('g_name',type=str,required=True,help='please input good name')
parser.add_argument('g_price',type=int,help='please input good price')
#传多个值:设置append属性
parser.add_argument('mu',action='append')
## 使用:
@marshal_with(goods_data_fields)
def post(self):
# g_name = request.form.get('g_name')
# g_price = request.form.get('g_price')
args = parser.parse_args()
g_name = args.get('g_name')
g_price = args.get('g_price')
- 传多个值:在原来的request里面使用getList
- parser.add_argument(‘mu’,action=‘append’)
- mu = args.get(‘mu’) or mu = request.form.getlist(‘mu’)
- 接受指定别名。
- location,指定参数的来源
parser_copy = parser.copy()//复制一个出来。
爬虫与反爬虫
- 基于ip频率反爬
- 客户端使用代理服务器
- 基于UA
- 使用UA池
- 基于Cookie或用户反爬
- Cookie池
- 登陆大量账号,将cookie存下来。
- 有人一直在搞验证码
今天总结:
-
restful: 软件架构风格,前后端分离,后端只负责数据处理,前端通过异步请求的方式和后端交互。路径是名词,url代表一种资源。通过http请求方法来实现资源转换
-
flask-restful: 在api上注册使用
-
难点:数据(对象)的序列化,指定字段的输出模版。(其实也都还好)
-
输入过滤,reqparse.RequestParser
- 参数名字,类型,是否必须,错误提示,指定来源,多值处理,别名。
- copy
-
abort:
- 指定错误码:
- 指定错误描述:
老师最后讲了一些关于爬虫与反爬虫的事例。
flask-restful 结合blueprint使用:
- xx = BluePrint()
- api = Api(xx)
- 通过蓝图对象来注册api,组成api对象。