博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Flask详解
阅读量:2176 次
发布时间:2019-05-01

本文共 26643 字,大约阅读时间需要 88 分钟。

Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理,然后触发Flask框架,开发人员基于Flask框架提供的功能对请求进行相应的处理,并返回给用户,如果要返回给用户复杂的内容时,需要借助jinja2模板来实现对模板的处理,即:将模板和数据进行渲染,将渲染后的字符串返回给用户浏览器。

“微”(micro) 并不表示你需要把整个 Web 应用塞进单个 Python 文件(虽然确实可以 ),也不意味着 Flask 在功能上有所欠缺。微框架中的“微”意味着 Flask 旨在保持核心简单而易于扩展。Flask 不会替你做出太多决策——比如使用何种数据库。而那些 Flask 所选择的——比如使用何种模板引擎——则很容易替换。除此之外的一切都由可由你掌握。如此,Flask 可以与您珠联璧合。

默认情况下,Flask 不包含数据库抽象层、表单验证,或是其它任何已有多种库可以胜任的功能。然而,Flask 支持用扩展来给应用添加这些功能,如同是 Flask 本身实现的一样。众多的扩展提供了数据库集成、表单验证、上传处理、各种各样的开放认证技术等功能。Flask 也许是“微小”的,但它已准备好在需求繁杂的生产环境中投入使用。

pip3 install flask
from werkzeug.wrappers import Request, Response@Request.applicationdef hello(request):    return Response('Hello World!')if __name__ == '__main__':    from werkzeug.serving import run_simple    run_simple('localhost', 4000, hello)
werkzeug

一. 基本使用

from flask import Flaskapp = Flask(__name__)@app.route('/')def hello_world():    return 'Hello World!'if __name__ == '__main__':    app.run()

flask添加装饰器

from flask import Flaskimport functoolsdef auth(func):    @functools.wraps(func) # 保留函数的元信息    def inner(*args,**kwargs):        print('before')        ret = func(*args,**kwargs)        print('after')        return ret    return innerapp = Flask(__name__)@app.route('/index')@authdef index():    print('index')    return 'index'if __name__ == '__main__':    app.run()

指定端口号

from werkzeug.wrappers import Request, Responsefrom werkzeug.serving import run_simple@Request.applicationdef hello(request):    # ...    # Flask框架    #    return Response('Hello World!')if __name__ == '__main__':    run_simple('localhost', 4000, hello) # hello()

示例:before_request和after_request

from flask import Flask,render_template,request,redirect,sessionapp = Flask(__name__)app.secret_key = '39jrlasdfoajslfu8af'# [b1,b2]@app.before_requestdef b1():    print('b1')    return 'gun'@app.before_requestdef b2():    print('b2')# [a1,a2] -> [a2,a1]@app.after_requestdef a1(response):    print('a1')    return response@app.after_requestdef a2(response):    print('a2')    return response@app.route('/index')def index():    print('index')    return 'index'if __name__ == '__main__':    app.run()

基于装饰器做用户认证

from flask import Flask,render_template,request,redirect,sessionapp = Flask(__name__)app.secret_key = '39jrlasdfoajslfu8af'import functoolsdef auth(func):    @functools.wraps(func) # 保留函数的元信息  一定要记得添加这行代码    def inner(*args,**kwargs):        if not session.get('user_info'):            return redirect('/login')        ret = func(*args,**kwargs)        return ret    return inner@app.route('/login',methods=['GET','POST'])def login():    if request.method == 'GET':        return render_template('login.html')    user = request.form.get('user')    pwd = request.form.get('pwd')    if user == 'xiao' and pwd == 'xiao':        session['user_info'] = user        return redirect('/index')    return render_template('login.html',msg="用户名或密码错误")@app.route('/index')@authdef index():    kuang_list = [        {
'id':1,'name':'name1','address':'昌平'}, {
'id':2,'name':'name2','address':'昌平'}, {
'id':3,'name':'name3','address':'昌平'}, ] return render_template('index.html',klist=kuang_list) # return render_template('index.html',**{'klist':kuang_list})@app.route('/detail')@authdef detail(): nid = request.args.get('nid') return render_template('detail.html')@app.route('/logout')def logout(): del session['user_info'] return redirect('/login')if __name__ == '__main__': app.run()

基于before_request实现用户认证

from flask import Flask,render_template,request,redirect,sessionapp = Flask(__name__)app.secret_key = '39jrlasdfoajslfu8af'@app.before_requestdef xxxxxxxxxxxxxx():    if request.path == '/login':        return None    if not session.get('user_info'):        return redirect('/login')@app.route('/login',methods=['GET','POST'])def login():    print('我是login')    if request.method == 'GET':        return render_template('login.html')    user = request.form.get('user')    pwd = request.form.get('pwd')    if user == 'xiao' and pwd == 'xiao':        session['user_info'] = user        return redirect('/index')    return render_template('login.html',msg="用户名或密码错误")@app.route('/index')def index():    print('我是index')    kuang_list = [        {
'id':1,'name':'name1','address':'昌平'}, {
'id':2,'name':'name2','address':'昌平'}, {
'id':3,'name':'name3','address':'昌平'}, ] return render_template('index.html',klist=kuang_list) # 这种传参方式,要注意 # return render_template('index.html',**{'klist':kuang_list}) # 这种传参方式,要加**打散@app.route('/detail')def detail(): nid = request.args.get('nid') return render_template('detail.html')@app.route('/logout')def logout(): del session['user_info'] return redirect('/login')if __name__ == '__main__': app.run()

二、配置文件

flask中的配置文件是一个flask.config.Config对象(继承字典),默认配置为:        {            'DEBUG':                                get_debug_flag(default=False),  是否开启Debug模式            'TESTING':                              False,                          是否开启测试模式            'PROPAGATE_EXCEPTIONS':                 None,                                       'PRESERVE_CONTEXT_ON_EXCEPTION':        None,            'SECRET_KEY':                           None,            'PERMANENT_SESSION_LIFETIME':           timedelta(days=31),            'USE_X_SENDFILE':                       False,            'LOGGER_NAME':                          None,            'LOGGER_HANDLER_POLICY':               'always',            'SERVER_NAME':                          None,            'APPLICATION_ROOT':                     None,            'SESSION_COOKIE_NAME':                  'session',            'SESSION_COOKIE_DOMAIN':                None,            'SESSION_COOKIE_PATH':                  None,            'SESSION_COOKIE_HTTPONLY':              True,            'SESSION_COOKIE_SECURE':                False,            'SESSION_REFRESH_EACH_REQUEST':         True,            'MAX_CONTENT_LENGTH':                   None,            'SEND_FILE_MAX_AGE_DEFAULT':            timedelta(hours=12),            'TRAP_BAD_REQUEST_ERRORS':              False,            'TRAP_HTTP_EXCEPTIONS':                 False,            'EXPLAIN_TEMPLATE_LOADING':             False,            'PREFERRED_URL_SCHEME':                 'http',            'JSON_AS_ASCII':                        True,            'JSON_SORT_KEYS':                       True,            'JSONIFY_PRETTYPRINT_REGULAR':          True,            'JSONIFY_MIMETYPE':                     'application/json',            'TEMPLATES_AUTO_RELOAD':                None,        }    方式一:        app.config['DEBUG'] = True        PS: 由于Config对象本质上是字典,所以还可以使用app.config.update(...)    方式二:        app.config.from_pyfile("python文件名称")            如:                settings.py                    DEBUG = True                app.config.from_pyfile("settings.py")        app.config.from_envvar("环境变量名称")            环境变量的值为python文件名称名称,内部调用from_pyfile方法        app.config.from_json("json文件名称")            JSON文件名称,必须是json格式,因为内部会执行json.loads        app.config.from_mapping({'DEBUG':True})            字典格式        app.config.from_object("python类或类的路径")   # 写在flask启动的py文件里面进行配置版本            app.config.from_object('pro_flask.settings.TestingConfig')            settings.py                class Config(object):   # 基础版本                    DEBUG = False                    TESTING = False                    DATABASE_URI = 'sqlite://:memory:'                class ProductionConfig(Config):  # 生产环境,线下环境                    DATABASE_URI = 'mysql://user@localhost/foo'                class DevelopmentConfig(Config):  # 开发环境                    DEBUG = True                class TestingConfig(Config):   # 测试环境 各个环境下连接的数据库是不一样的                    TESTING = True            PS: 从sys.path中已经存在路径开始写                PS: settings.py文件默认路径要放在程序root_path目录,如果instance_relative_config为True,则就是instance_path目录

三、路由系统

  • @app.route('/user/<username>')  # 传字符串   他们的内部都对应一个转换器
  • @app.route('/post/<int:post_id>')   # 传数字
  • @app.route('/post/<float:post_id>')  # 浮点数
  • @app.route('/post/<path:path>')   # 路径,拼url
  • @app.route('/login', methods=['GET', 'POST']),method列表里面添加的允许的请求方式,如果不添加method列表,则只允许GET请求。

常用路由系统有以上五种,所有的路由系统都是基于一下对应关系来处理:

DEFAULT_CONVERTERS = {    'default':          UnicodeConverter,    'string':           UnicodeConverter,    'any':              AnyConverter,    'path':             PathConverter,    'int':              IntegerConverter,    'float':            FloatConverter,    'uuid':             UUIDConverter,}
def auth(func):            def inner(*args, **kwargs):                print('before')                result = func(*args, **kwargs)                print('after')                return result        return inner        @app.route('/index.html',methods=['GET','POST'],endpoint='index')        @auth        def index():            return 'Index'        或                def index():            return "Index"        self.add_url_rule(rule='/index.html', endpoint="index", view_func=index, methods=["GET","POST"])        or        app.add_url_rule(rule='/index.html', endpoint="index", view_func=index, methods=["GET","POST"])        app.view_functions['index'] = index        或        def auth(func):            def inner(*args, **kwargs):                print('before')                result = func(*args, **kwargs)                print('after')                return result        return inner        class IndexView(views.View):            methods = ['GET']            decorators = [auth, ]            def dispatch_request(self):                print('Index')                return 'Index!'        app.add_url_rule('/index', view_func=IndexView.as_view(name='index'))  # name=endpoint        或        class IndexView(views.MethodView):            methods = ['GET']            decorators = [auth, ]            def get(self):                return 'Index.GET'            def post(self):                return 'Index.POST'        app.add_url_rule('/index', view_func=IndexView.as_view(name='index'))  # name=endpoint        @app.route和app.add_url_rule参数:            rule,                       URL规则            view_func,                  视图函数名称            defaults=None,              默认值,当URL中无参数,函数需要参数时,使用defaults={
'k':'v'}为函数提供参数 endpoint=None, 名称,用于反向生成URL,即: url_for('名称') methods=None, 允许的请求方式,如:["GET","POST"] strict_slashes=None, 对URL最后的 / 符号是否严格要求, 如: @app.route('/index',strict_slashes=False), 访问 http://www.xx.com/index/ 或 http://www.xx.com/index均可 @app.route('/index',strict_slashes=True) 仅访问 http://www.xx.com/index redirect_to=None, 重定向到指定地址 如: @app.route('/index/
', redirect_to='/home/
') 或 def func(adapter, nid): return "/home/888" @app.route('/index/
', redirect_to=func) subdomain=None, 子域名访问 from flask import Flask, views, url_for app = Flask(import_name=__name__) app.config['SERVER_NAME'] = 'wupeiqi.com:5000' @app.route("/", subdomain="admin") def static_index(): """Flask supports static subdomains This is available at static.your-domain.tld""" return "static.your-domain.tld" @app.route("/dynamic", subdomain="
") def username_index(username): """Dynamic subdomains are also supported Try going to user1.your-domain.tld/dynamic""" return username + ".your-domain.tld" if __name__ == '__main__': app.run()
a.注册路由原理
from flask import Flask, views, url_for            from werkzeug.routing import BaseConverter            app = Flask(import_name=__name__)            class RegexConverter(BaseConverter):                """                自定义URL匹配正则表达式                """                def __init__(self, map, regex):                    super(RegexConverter, self).__init__(map)                    self.regex = regex                def to_python(self, value):                    """                    路由匹配时,匹配成功后传递给视图函数中参数的值                    :param value:                     :return:                     """                    return int(value)                def to_url(self, value):                    """                    使用url_for反向生成URL时,传递的参数经过该方法处理,返回的值用于生成URL中的参数                    :param value:                     :return:                     """                    val = super(RegexConverter, self).to_url(value)                    return val            # 添加到flask中            app.url_map.converters['regex'] = RegexConverter            @app.route('/index/
') def index(nid): print(url_for('index', nid='888')) return 'Index' if __name__ == '__main__': app.run()
b. 自定制正则路由匹配
app.url_map.converters['regex'] = RegexConverter# 这个写在启动py文件里,告诉flask我自己要定义一个路由转换器啦,名字叫regex# 转换器对应的类就是RegexConverterclass RegexConverter(BaseConverter):    """    自定义URL匹配正则表达式    """    def __init__(self, map, regex):# 参数regex接收传过来的nid参数        super(RegexConverter, self).__init__(map)        self.regex = regex    def to_python(self, value):        """        路由匹配时,匹配成功后传递给视图函数中参数的值        :param value:        :return:        """        return int(value)    def to_url(self, value):        """        使用url_for反向生成URL时,传递的参数经过该方法处理,返回的值用于生成URL中的参数        :param value:        :return:        """        val = super(RegexConverter, self).to_url(value)        return valapp.url_map.converters['xxx'] = RegexConverter@app.route('/index/
',methods=['GET','POST']) # 定义好转换器之后,就这样写了。def index(nid): print(nid,type(nid)) v = url_for('index',nid=999) # /index/999 print(v) return "Index"

 

添加路由的两种方式

# 路由方式一(*):@app.route('/index',methods=['GET','POST'])def index():    return "Index"# 路由方式二:def order():    return 'Order'app.add_url_rule('/order',view_func=order)

反向生成url

@app.route('/index',methods=['GET','POST'],endpoint='n1')  # endpoint 给路由起别名。如果不起别名,就用函数名def index():    v1 = url_for('n1')    v2 = url_for('login')   # url_for 反向生成url    v3 = url_for('logout')    print(v1,v2,v3)    return "Index"@app.route('/login',methods=['GET','POST'])def login():    return "login"@app.route('/logout',methods=['GET','POST'])def logout():    return "logout"

 

四、模板

1、模板的使用

Flask使用的是Jinja2模板,所以其语法和Django无差别

2、自定义模板方法

Flask中自定义模板方法的方式和Bottle相似,创建一个函数并通过参数的形式传入render_template,如:

    

自定义函数

{
{ww()|safe}}
html
#!/usr/bin/env python# -*- coding:utf-8 -*-from flask import Flask,render_templateapp = Flask(__name__)  def wupeiqi():    return '

Wupeiqi

' @app.route('/login', methods=['GET', 'POST'])def login(): return render_template('login.html', ww=wupeiqi) app.run()
run.py
    
Title {
% macro input(name, type='text', value='') %} {
% endmacro %} {
{ input('n1') }} {
% include 'tp.html' %}

asdf{
{ v.k1}}

其他

注意:Markup等价django的mark_safe

五、请求和响应

from flask import Flaskfrom flask import requestfrom flask import render_templatefrom flask import redirectfrom flask import make_responseapp = Flask(__name__)@app.route('/login.html', methods=['GET', "POST"])def login():    # 请求相关信息    # request.method  请求的方法    # request.args    获取GET请求的内容    # request.args.get("id")    获取id的值    # request.args。getlist('ids')    获取多个值    # data = request.args    # data_dict = data.to_dict()  通过to_dict()方法转化成字典    # request.remote_addr  获取ip    # request.form    获取POST请求的值,获取form表单里面的内容    # request.values  所有的请求参数    # request.cookies 获取cookies    # request.headers 获取headers信息,是个list    # request.path    仅获取端口号和参数中间的路由  /testrequest    # request.full_path    # request.script_root 什么都没获取到    # request.url     获取完整的url,带参数 http://192.168.1.183:5000/testrequest?a&b    # request.base_url 获取除参数外的url部分 http://192.168.1.183:5000/testrequest    # request.url_root 仅获取地址和端口号 http://192.168.1.183:5000/    # request.host_url    # request.host    # request.files 随请求上传的文件    # obj = request.files['the_file_name']    # obj.save('/var/www/uploads/' + secure_filename(f.filename))    # request.data 是请求的数据    # 响应相关信息    # return "字符串" 实际上是调用make_response    # return render_template('html模板路径',**{}) **{'obj':obj}形式    # return render_template('html模板路径',obj=obj)    # return redirect('/index.html')    # return jsonify(**{'obj':obj})  返回json数据  from flask import jsonify    # response = make_response(render_template('index.html'))    # response是flask.wrappers.Response类型    # response.delete_cookie('key')    # response.set_cookie('key', 'value')    # response.headers['X-Something'] = 'A value'    # return response    return "内容"if __name__ == '__main__':    app.run()

六、Session

除请求对象之外,还有一个 session 对象。它允许你在不同请求间存储特定用户的信息。它是在 Cookies 的基础上实现的,并且对 Cookies 进行密钥签名要使用会话,你需要设置一个密钥。

  • 设置:session['username'] = 'xxx'

  • 删除:session.pop('username', None)
from flask import Flask, session, redirect, url_for, escape, request app = Flask(__name__) @app.route('/')def index():    if 'username' in session:        return 'Logged in as %s' % escape(session['username'])    return 'You are not logged in' @app.route('/login', methods=['GET', 'POST'])def login():    if request.method == 'POST':        session['username'] = request.form['username']        return redirect(url_for('index'))    return '''        

''' @app.route('/logout')def logout(): # remove the username from the session if it's there session.pop('username', None) return redirect(url_for('index')) # set the secret key. keep this really secret:app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'

基本使用
pip3 install Flask-Session                run.py            from flask import Flask            from flask import session            from pro_flask.utils.session import MySessionInterface            app = Flask(__name__)            app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'            app.session_interface = MySessionInterface()            @app.route('/login.html', methods=['GET', "POST"])            def login():                print(session)                session['user1'] = 'alex'                session['user2'] = 'alex'                del session['user2']                return "内容"            if __name__ == '__main__':                app.run()        session.py            #!/usr/bin/env python            # -*- coding:utf-8 -*-            import uuid            import json            from flask.sessions import SessionInterface            from flask.sessions import SessionMixin            from itsdangerous import Signer, BadSignature, want_bytes            class MySession(dict, SessionMixin):                def __init__(self, initial=None, sid=None):                    self.sid = sid                    self.initial = initial                    super(MySession, self).__init__(initial or ())                def __setitem__(self, key, value):                    super(MySession, self).__setitem__(key, value)                def __getitem__(self, item):                    return super(MySession, self).__getitem__(item)                def __delitem__(self, key):                    super(MySession, self).__delitem__(key)            class MySessionInterface(SessionInterface):                session_class = MySession                container = {}                def __init__(self):                    import redis                    self.redis = redis.Redis()                def _generate_sid(self):                    return str(uuid.uuid4())                def _get_signer(self, app):                    if not app.secret_key:                        return None                    return Signer(app.secret_key, salt='flask-session',                                  key_derivation='hmac')                def open_session(self, app, request):                    """                    程序刚启动时执行,需要返回一个session对象                    """                    sid = request.cookies.get(app.session_cookie_name)                    if not sid:                        sid = self._generate_sid()                        return self.session_class(sid=sid)                    signer = self._get_signer(app)                    try:                        sid_as_bytes = signer.unsign(sid)                        sid = sid_as_bytes.decode()                    except BadSignature:                        sid = self._generate_sid()                        return self.session_class(sid=sid)                    # session保存在redis中                    # val = self.redis.get(sid)                    # session保存在内存中                    val = self.container.get(sid)                    if val is not None:                        try:                            data = json.loads(val)                            return self.session_class(data, sid=sid)                        except:                            return self.session_class(sid=sid)                    return self.session_class(sid=sid)                def save_session(self, app, session, response):                    """                    程序结束前执行,可以保存session中所有的值                    如:                        保存到resit                        写入到用户cookie                    """                    domain = self.get_cookie_domain(app)                    path = self.get_cookie_path(app)                    httponly = self.get_cookie_httponly(app)                    secure = self.get_cookie_secure(app)                    expires = self.get_expiration_time(app, session)                    val = json.dumps(dict(session))                    # session保存在redis中                    # self.redis.setex(name=session.sid, value=val, time=app.permanent_session_lifetime)                    # session保存在内存中                    self.container.setdefault(session.sid, val)                    session_id = self._get_signer(app).sign(want_bytes(session.sid))                    response.set_cookie(app.session_cookie_name, session_id,                                        expires=expires, httponly=httponly,                                        domain=domain, path=path, secure=secure)
自定义Session
#!/usr/bin/env python# -*- coding:utf-8 -*-"""pip3 install redispip3 install flask-session"""from flask import Flask, session, redirectfrom flask.ext.session import Sessionapp = Flask(__name__)app.debug = Trueapp.secret_key = 'asdfasdfasd'app.config['SESSION_TYPE'] = 'redis'from redis import Redisapp.config['SESSION_REDIS'] = Redis(host='192.168.0.94',port='6379')Session(app)@app.route('/login')def login():    session['username'] = 'alex'    return redirect('/index')@app.route('/index')def index():    name = session['username']    return nameif __name__ == '__main__':    app.run()
第三方session

 

七、蓝图

蓝图用于为应用提供目录划分:

小型应用程序:

大型应用程序:

其他:

  • 蓝图URL前缀:xxx = Blueprint('account', __name__,url_prefix='/xxx')
  • 蓝图子域名:xxx = Blueprint('account', __name__,subdomain='admin')
    # 前提需要给配置SERVER_NAME: app.config['SERVER_NAME'] = 'wupeiqi.com:5000'
    # 访问时:admin.wupeiqi.com:5000/login.html

八、message

message是一个基于Session实现的用于保存数据的集合,其特点是:使用一次就删除。闪现

from flask import Flask, flash, redirect, render_template, request, get_flashed_messages        app = Flask(__name__)        app.secret_key = 'some_secret'        @app.route('/')        def index1():            messages = get_flashed_messages()            print(messages)            return "Index1"        @app.route('/set')        def index2():            v = request.args.get('p')            flash(v)            return 'ok'        if __name__ == "__main__":            app.run()
View Code

九、中间件

from flask import Flask, flash, redirect, render_template, request app = Flask(__name__)app.secret_key = 'some_secret' @app.route('/')def index1():    return render_template('index.html') @app.route('/set')def index2():    v = request.args.get('p')    flash(v)    return 'ok' class MiddleWare:    def __init__(self,wsgi_app):        self.wsgi_app = wsgi_app     def __call__(self, *args, **kwargs):         return self.wsgi_app(*args, **kwargs) if __name__ == "__main__":    app.wsgi_app = MiddleWare(app.wsgi_app)    app.run(port=9999)
View Code

十、请求扩展

#!/usr/bin/env python# -*- coding:utf-8 -*-from flask import Flask, Request, render_templateapp = Flask(__name__, template_folder='templates')app.debug = True@app.before_first_requestdef before_first_request1():    print('before_first_request1')@app.before_first_requestdef before_first_request2():    print('before_first_request2')@app.before_requestdef before_request1():    Request.nnn = 123    print('before_request1')@app.before_requestdef before_request2():    print('before_request2')@app.after_requestdef after_request1(response):    print('before_request1', response)    return response@app.after_requestdef after_request2(response):    print('before_request2', response)    return response@app.errorhandler(404)def page_not_found(error):    return 'This page does not exist', 404@app.template_global()def sb(a1, a2):    return a1 + a2@app.template_filter()def db(a1, a2, a3):    return a1 + a2 + a3@app.route('/')def hello_world():    return render_template('hello.html')if __name__ == '__main__':    app.run()
View Code
调用方式:{
{sb(1,2)}} {
{ 1|db(2,3)}}

十一、Flask插件

  • WTForms    
  • SQLAchemy
  • 等...    http://flask.pocoo.org/extensions/

补充:

pip install pipreqs 安装这个模块之后项目里会自动生成一个requirements.txt文件,里面显示的是这个项目安装的模块及其版本信息。 生成依赖文件requirements.txt  命令: pipreqs ./   (./表示当前文件) 安装依赖文件requirements.txt  命令: pip install -r requirements.txt

 

转载地址:http://koykb.baihongyu.com/

你可能感兴趣的文章
【Loadrunner】【浙江移动项目手写代码】代码备份
查看>>
Python几种并发实现方案的性能比较
查看>>
[Jmeter]jmeter之脚本录制与回放,优化(windows下的jmeter)
查看>>
Jmeter之正则
查看>>
【JMeter】1.9上考试jmeter测试调试
查看>>
【虫师】【selenium】参数化
查看>>
【Python练习】文件引用用户名密码登录系统
查看>>
学习网站汇总
查看>>
【Python】用Python打开csv和xml文件
查看>>
【Loadrunner】性能测试报告实战
查看>>
【自动化测试】自动化测试需要了解的的一些事情。
查看>>
【selenium】selenium ide的安装过程
查看>>
【手机自动化测试】monkey测试
查看>>
【英语】软件开发常用英语词汇
查看>>
Fiddler 抓包工具总结
查看>>
【雅思】雅思需要购买和准备的学习资料
查看>>
【雅思】雅思写作作业(1)
查看>>
【雅思】【大作文】【审题作业】关于同不同意的审题作业(重点)
查看>>
【Loadrunner】通过loadrunner录制时候有事件但是白页无法出来登录页怎么办?
查看>>
【English】【托业】【四六级】写译高频词汇
查看>>