当前位置: 首页 > news >正文

Flask电影网站项目

1 开发环境搭建

1.1 Windows环境

  1. 下载Python。
  2. 下载PyCharm。
  3. 下载virtualenv。
  4. 下载MySQL。可以安转一个数据库GUI。

1.2 Linux环境

  1. 下载VMware Workstation Pro。
  2. 下载ubuntu和xshell。

用xshell需要是虚拟机桥接。

  1. 下载Python。

pip install 名字 -i https://mirrors.aliyun.com/pypi/simple

  1. 下载PyCharm。

整个ubuntu还好说,但要是个最小版的Centos,那真就有点小离谱了,所以整个共享目录。

  1. 下载virtualenv。

为了方便直接使用。

ln -s /usr/local/lib/python3.8/dist-packages/virtualenv /usr/bin/virtualenv
virtualenv -p python3 vir_pyhon3
source vir_python3/bin/activate

  1. 下载MySQL。

sudo apt install mysql-server
sudo service mysql start

密码更改:
https://blog.csdn.net/hwstars/article/details/122738784?ops_request_misc=&request_id=&biz_id=102&utm_term=mysql%E9%A6%96%E6%AC%A1%E5%AE%89%E8%BD%AC%E5%AF%86%E7%A0%81%E5%9C%A8%E5%93%AAubuntu&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-0-122738784.142v70control,201v4add_ask&spm=1018.2226.3001.4187

https://blog.csdn.net/qq_57309855/article/details/127602061?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167319614116800213055420%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=167319614116800213055420&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-1-127602061-null-null.142v70control,201v4add_ask&utm_term=ERROR%201064%20%2842000%29%3A%20You%20have%20an%20error%20in%20your%20SQL%20syntax%3B%20check%20the%20manual%20that%20corresponds%20to%20your%20MySQL%20server%20version%20for%20the%20right%20syntax%20to%20use%20near%20%E2%80%98root%E2%80%99%20at%20line%201&spm=1018.2226.3001.4187
远程连接:
https://blog.csdn.net/a648119398/article/details/122420906?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167319661216800215020531%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=167319661216800215020531&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_positive~default-1-122420906-null-null.142v70control,201v4add_ask&utm_term=navicat%E8%BF%9C%E7%A8%8B%E8%BF%9E%E6%8E%A5mysql&spm=1018.2226.3001.4187

https://blog.csdn.net/fengzijinliang/article/details/51387102?ops_request_misc=&request_id=&biz_id=102&utm_term=navicat%E8%BF%9C%E7%A8%8B%E8%BF%9E%E6%8E%A5mysql&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-1-51387102.142v70control,201v4add_ask&spm=1018.2226.3001.4187

最后一个问题是发现我的my.cnf中并没有需要注释的代码,反而在/etc/mysql/mysql.conf.d/mysqld.cnf文件中,注释掉就好了。
本人所写的博客:https://blog.csdn.net/weixin_61823031/article/details/128608050

2 Flask框架简介

2.1 MVC框架对比

  • Flask:微框架。易学习、Jinja2模板、内置服务器、扩展丰富,易扩展。
  • Django:全能框架、学习成本大
  • Tornado:高性能、异步处理、扩展不多
  • Bottle:小巧

2.2 下载

pip install flask

2.3 运行

Windows下直接使用PyCharm进行。
Linux下运行:

export FLASK_APP=app.py
flask run host 0.0.0.0

然后就可以使用Linux的主机IP地址在浏览器上进行访问即可。

2.4 Flask相关

PotPlayerMini64_yOGyIpyllQ.png
PotPlayerMini64_9PMiKXJ2eC.png
PotPlayerMini64_YMrILUe05M.png

2.5 Flask配置

网络配置
监听网卡:本地网卡(127.0.0.1),整块网卡(0.0.0.0)
PotPlayerMini64_bAGWoNollh.png
这里导入配置的方法,本人选择使用导入py文件配置。
如下:

from flask import Flask
import configs# 初始化实例
app = Flask(__name__)
# 加载配置文件
app.config.from_object(configs)@app.route('/')
def hello_world():  # put application's code herereturn 'Hello World!'if __name__ == '__main__':app.run(host="0.0.0.0")
DEBUG = True

一直有个警告气死我了,调的时候还导致多了第一句废话,更气了!
Xshell_KWPHbNsZ8r.png

3 Flask路由和请求对象

3.1 路由方式

  • route():内部调用add_url_rule()
  • add_url_rule()

加入参数的方式。

@app.route("/<name>"):
def hello(name)return "hello, %s" % name
  • 蓝图

一般使用两个文件来实现,类似如下所示。

from flask import Flask
from controller import start
import configs# 初始化实例
app = Flask(__name__)
# 加载配置文件
app.config.from_object(configs)app.register_blueprint(start, url_prefix="/start")if __name__ == '__main__':app.run(host="0.0.0.0")
from flask import Flask, Blueprintstart = Blueprint("start", __name__)@start.route("/")
def hello():return "hello, world!"@start.route("/my")
def hello2():return "hello, two!"

3.2 HTTP请求

  • DNS解析:根据域名获取IP
  • HTTP请求
  • HTTP响应

获取请求对象的GET和POST参数
请求的示例代码:

@start.route("/get")
def get():var_a = request.args.get("a", "hello")return  "request:%s, params:%s,var_a:%s"%(request.method, request.args, var_a)@start.route("/post", methods=["POST"])
def post():var_a = request.form['a'] if "a" in request.form else ''return "request:%s, params:%s,var_a:%s"%(request.method, request.form, var_a)

post请求直接刷新浏览器是不行的,这里使用了hackbar这样的一款插件来发送post请求。
chrome_ikJfBFDnpF.png
还有一种不需要区分的方式:

@start.route("/get")
def get():req = request.valuesvar_a = req['a'] if 'a' in req else "none"# var_a = request.args.get("a", "hello")return  "request:%s, params:%s,var_a:%s"%(request.method, request.args, var_a)@start.route("/post", methods=["POST"])
def post():req = request.valuesvar_a = req['a'] if 'a' in req else "none"# var_a = request.form['a'] if "a" in request.form else ''return "request:%s, params:%s,var_a:%s"%(request.method, request.form, var_a)

上传文件

@start.route("/upload", methods=["POST"])
def upload():f = request.files['file'] if "file" in request.files else Nonereturn "request:%s, params:%s,file:%s"%(request.method, request.files, f)

使用Postman进行测试。
Postman_ypBpQJVCoW.png
如果对于同一个参数a,同时使用get和post的传参,request.values会接受get方式的请求。

4 Flask响应对象和模板

4.1 Flask响应

  • text/html
@start.route("/text")
def text():return "text/html"@start.route("/text_same")
def text_same():response = make_response("text/html", 200)return response
  • Json
@start.route("/json")
def json():import jsondata = {"a": "b"}# 默认text,所以要改成jsonresponse = make_response(json.dumps(data))response.headers["Content-Type"] = "application/json"return response@start.route("/json_same")
def json_same():data = {"a": "b"}response = make_response(jsonify(data))return response 
  • 模板响应
@start.route("/template")
def template():return render_template("index.html")
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
hello , template!
</body>
</html>

官方文档中的说明。
chrome_r4pVjIOKED.png

4.2 模板引擎Jinja2

  • 传递变量
@start.route("/template")
def template():# 传值# name = "daye"# return render_template("index.html", name=name)name = "daye"context = {"name":name}return render_template("index.html", **context)
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
hello , template!
<p>hello ,{{ name }}</p>
</body>
</html>
  • Jinja2基本语法
@start.route("/template")
def template():# 传值# name = "daye"# return render_template("index.html", name=name)name = "daye"context = {"name": name, 'user': {"nickname": "day3", "qq": 12324, "home": "Bejing"}, 'num_list': [1, 2, 3, 4, 5]}return render_template("index.html", **context)
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body>hello , template!<p>hello ,{{ name }}</p><p>{% if user %}{{ user.nickname }} QQ:{{ user.qq }} 家庭住址:{{ user.home }}{% endif %}</p><p>{% for tmp in num_list %}{{ tmp }}{% endfor %}</p></body>
</html>
  • 模板继承
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>模板</title>
</head>
<body>
{% block content %}{% endblock %}
</body>
</html>
{% extends "common/base.html" %}{% block content %}
<p>this is extend</p>
{% endblock %}
@start.route("/extend")
def extend():return render_template("extend.html")

5 Flask数据库

5.1 数据库配置

下载必要的配置:

pip install flask_sqlalchemy
apt-get install libmysqlclient-dev python3-dev
pip install mysqlclient

增添代码如下所示:

from flask import Blueprint, request, make_response, jsonify, render_template
from sqlalchemy import text
from exts import db@start.route("/template")
def template():# 传值# name = "daye"# return render_template("index.html", name=name)name = "daye"context = {"name": name, 'user': {"nickname": "day3", "qq": 12324, "home": "Bejing"}, 'num_list': [1, 2, 3, 4, 5]}sql = text("select * from `user`")result = db.engine.execute(sql)context['result'] = resultreturn render_template("index.html", **context)
from flask_sqlalchemy import SQLAlchemydb = SQLAlchemy()
from flask import Flask
from controller import start
import configs
from exts import db
# 增加session会话保护(任意字符串,用来对session进行加密)
app.secret_key = "day3"
# db绑定app
db.init_app(app)
DEBUG = True
# 数据库配置
HOSTNAME = '127.0.0.1'
PORT = '3306'
DATABASE = 'mysql'
USERNAME = 'root'
PASSWORD = 'root'
DB_URI = 'mysql+mysqldb://{}:{}@{}:{}/{}?charset=utf8'. \format(USERNAME, PASSWORD, HOSTNAME, PORT, DATABASE)SQLALCHEMY_DATABASE_URI = DB_URI
SQLALCHEMY_TRACK_MODIFICATIONS = True
SQLALCHEMY_ECHO = True

vmware_ovrLj0HpjG.png![chrome_SkWekptSYs.png](https://img-blog.csdnimg.cn/img_convert/e9d7db316872d088b2da12bad0c7ef6a.png#averageHue=#fcfcfb&clientId=uc5b1810e-a7aa-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=151&id=u0421cd6a&margin=[object Object]&name=chrome_SkWekptSYs.png&originHeight=424&originWidth=883&originalType=binary&ratio=1&rotation=0&showTitle=false&size=10845&status=done&style=none&taskId=u130bd777-80b5-4ba3-b0b4-4383027c0f1&title=&width=315.3333435058594)

5.2 Flask通过Model访问数据库

@start.route("/template")
def template():# 传值# name = "daye"# return render_template("index.html", name=name)name = "daye"context = {"name": name, 'user': {"nickname": "day3", "qq": 12324, "home": "Bejing"}, 'num_list': [1, 2, 3, 4, 5]}# 数据库查询# sql = text("select * from `user`")# result = db.engine.execute(sql)result = User.query.all()context['result'] = resultreturn render_template("index.html", **context)
from exts import dbclass User(db.Model):Host = db.Column(db.String(80), primary_key=True)User = db.Column(db.String(120))

5.3 自动生成model

下载自动生成model的库。

pip install flask-sqlacodegen

生成model的命令。

flask-sqlacodegen ‘mysql+mysqldb://root:root@127.0.0.1:3306/mysql?charset=utf8’ --table user --outfile “user.py” --flask

生成的表如下所示:

# coding: utf-8
from flask_sqlalchemy import SQLAlchemydb = SQLAlchemy()class User(db.Model):__tablename__ = 'user'Host = db.Column(db.String(255, 'ascii_general_ci'), primary_key=True, nullable=False, server_default=db.FetchedValue())User = db.Column(db.String(32, 'utf8mb3_bin'), primary_key=True, nullable=False, server_default=db.FetchedValue())Select_priv = db.Column(db.Enum('N', 'Y'), nullable=False, server_default=db.FetchedValue())Insert_priv = db.Column(db.Enum('N', 'Y'), nullable=False, server_default=db.FetchedValue())Update_priv = db.Column(db.Enum('N', 'Y'), nullable=False, server_default=db.FetchedValue())Delete_priv = db.Column(db.Enum('N', 'Y'), nullable=False, server_default=db.FetchedValue())Create_priv = db.Column(db.Enum('N', 'Y'), nullable=False, server_default=db.FetchedValue())Drop_priv = db.Column(db.Enum('N', 'Y'), nullable=False, server_default=db.FetchedValue())Reload_priv = db.Column(db.Enum('N', 'Y'), nullable=False, server_default=db.FetchedValue())Shutdown_priv = db.Column(db.Enum('N', 'Y'), nullable=False, server_default=db.FetchedValue())Process_priv = db.Column(db.Enum('N', 'Y'), nullable=False, server_default=db.FetchedValue())File_priv = db.Column(db.Enum('N', 'Y'), nullable=False, server_default=db.FetchedValue())Grant_priv = db.Column(db.Enum('N', 'Y'), nullable=False, server_default=db.FetchedValue())References_priv = db.Column(db.Enum('N', 'Y'), nullable=False, server_default=db.FetchedValue())Index_priv = db.Column(db.Enum('N', 'Y'), nullable=False, server_default=db.FetchedValue())Alter_priv = db.Column(db.Enum('N', 'Y'), nullable=False, server_default=db.FetchedValue())Show_db_priv = db.Column(db.Enum('N', 'Y'), nullable=False, server_default=db.FetchedValue())Super_priv = db.Column(db.Enum('N', 'Y'), nullable=False, server_default=db.FetchedValue())Create_tmp_table_priv = db.Column(db.Enum('N', 'Y'), nullable=False, server_default=db.FetchedValue())Lock_tables_priv = db.Column(db.Enum('N', 'Y'), nullable=False, server_default=db.FetchedValue())Execute_priv = db.Column(db.Enum('N', 'Y'), nullable=False, server_default=db.FetchedValue())Repl_slave_priv = db.Column(db.Enum('N', 'Y'), nullable=False, server_default=db.FetchedValue())Repl_client_priv = db.Column(db.Enum('N', 'Y'), nullable=False, server_default=db.FetchedValue())Create_view_priv = db.Column(db.Enum('N', 'Y'), nullable=False, server_default=db.FetchedValue())Show_view_priv = db.Column(db.Enum('N', 'Y'), nullable=False, server_default=db.FetchedValue())Create_routine_priv = db.Column(db.Enum('N', 'Y'), nullable=False, server_default=db.FetchedValue())Alter_routine_priv = db.Column(db.Enum('N', 'Y'), nullable=False, server_default=db.FetchedValue())Create_user_priv = db.Column(db.Enum('N', 'Y'), nullable=False, server_default=db.FetchedValue())Event_priv = db.Column(db.Enum('N', 'Y'), nullable=False, server_default=db.FetchedValue())Trigger_priv = db.Column(db.Enum('N', 'Y'), nullable=False, server_default=db.FetchedValue())Create_tablespace_priv = db.Column(db.Enum('N', 'Y'), nullable=False, server_default=db.FetchedValue())ssl_type = db.Column(db.Enum('', 'ANY', 'X509', 'SPECIFIED'), nullable=False, server_default=db.FetchedValue())ssl_cipher = db.Column(db.LargeBinary, nullable=False)x509_issuer = db.Column(db.LargeBinary, nullable=False)x509_subject = db.Column(db.LargeBinary, nullable=False)max_questions = db.Column(db.Integer, nullable=False, server_default=db.FetchedValue())max_updates = db.Column(db.Integer, nullable=False, server_default=db.FetchedValue())max_connections = db.Column(db.Integer, nullable=False, server_default=db.FetchedValue())max_user_connections = db.Column(db.Integer, nullable=False, server_default=db.FetchedValue())plugin = db.Column(db.String(64, 'utf8mb3_bin'), nullable=False, server_default=db.FetchedValue())authentication_string = db.Column(db.Text(collation='utf8mb3_bin'))password_expired = db.Column(db.Enum('N', 'Y'), nullable=False, server_default=db.FetchedValue())password_last_changed = db.Column(db.DateTime)password_lifetime = db.Column(db.SmallInteger)account_locked = db.Column(db.Enum('N', 'Y'), nullable=False, server_default=db.FetchedValue())Create_role_priv = db.Column(db.Enum('N', 'Y'), nullable=False, server_default=db.FetchedValue())Drop_role_priv = db.Column(db.Enum('N', 'Y'), nullable=False, server_default=db.FetchedValue())Password_reuse_history = db.Column(db.SmallInteger)Password_reuse_time = db.Column(db.SmallInteger)Password_require_current = db.Column(db.Enum('N', 'Y'))User_attributes = db.Column(db.JSON)

写好的model读入数据库。

from app import app, db
if __name__ == '__main__':from models import Userwith app.app_context():db.create_all()# app.run(host="0.0.0.0")

6 MVC优化

  • flask_script自定义启动命令
  • 多环境配置文件
  • flask_debugtoolbar
  • 错误拦截器
  • 请求拦截器

7 登录和注册功能实现

7.1 猫影前台功能


用户数据表设计
PotPlayerMini64_hJaHE8q1XJ.png
navicat_n8HsdZ7thg.png
navicat_DfkFjs5Cfs.png
导出建表SQL语句

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (`id` int(0) NOT NULL AUTO_INCREMENT,`nickname` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '昵称',`login_name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '登录用户名',`login_pwd` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '登录密码',`login_salt` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '登录密码随机码',`status` tinyint(0) NOT NULL DEFAULT 1 COMMENT '状态:0:无效 1:有效',`updated_time` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) COMMENT '最后更新时间',`created_time` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) COMMENT '插入时间',PRIMARY KEY (`id`) USING BTREE,UNIQUE INDEX `UNIQUE`(`login_name`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;SET FOREIGN_KEY_CHECKS = 1;

7.2 搭建页面

新建member.py文件

from flask import Blueprint, render_templatemember_page = Blueprint("member_page", __name__)@member_page.route("/reg")
def reg():return render_template("/member/reg.html")@member_page.route("/login")
def login():return render_template("/member/login.html")

使用bootstrap,此时模板文件为

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>模板</title><link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css"></head><body><!-- partial:partials/_sidebar.html --><nav class="navbar navbar-default navbar-inverse" style="border-radius: 0"><div class="container-fluid"><!-- Brand and toggle get grouped for better mobile display --><div class="navbar-header"><button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"><span class="sr-only">Toggle navigation</span><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button><a class="navbar-brand" href="/">猫影</a></div><!-- Collect the nav links, forms, and other content for toggling --><div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"><ul class="nav navbar-nav"><li class="active"><a href="#">影视 <span class="sr-only">(current)</span></a></li></ul><ul class="nav navbar-nav navbar-right"><li><a href="{{ url_for('member_page.login') }}">登录</a></li><li><a href="{{ url_for('member_page.reg') }}">注册</a></li></ul></div><!-- /.navbar-collapse --></div><!-- /.container-fluid --></nav><div class="container" style="min-height: 600px">{% block content %}{% endblock %}</div><footer class="text-center">day3 @2022</footer><script src="/static/bootstrap/js/jquery-2.0.3.js"></script><script src="/static/bootstrap/js/bootstrap.min.js"></script></body>
</html>

注册界面

{% extends "common/base.html" %}
{% block content %}<div class="row" style="margin-top: 50px"><div class="col-lg-6 col-lg-offset-3"><div class="panel panel-default"><div class="panel-heading">用户注册</div><div class="panel-body"><form class="form-horizontal"><div class="form-group"><label for="login_name" class="col-sm-2 control-label">用户名</label><div class="col-sm-10"><input type="text" class="form-control" id="login_name" placeholder="请输入用户名"></div></div><div class="form-group"><label for="login_email" class="col-sm-2 control-label">邮箱</label><div class="col-sm-10"><input type="text" class="form-control" id="login_email" placeholder="请输入邮箱"></div></div><div class="form-group"><label for="login_pw1" class="col-sm-2 control-label">密码</label><div class="col-sm-10"><input type="password" class="form-control" id="login_pw1" placeholder="请输入密码"></div></div><div class="form-group"><label for="login_pw2" class="col-sm-2 control-label">确认密码</label><div class="col-sm-10"><input type="password" class="form-control" id="login_pw2" placeholder="请再次输入密码"></div></div><div class="form-group"><label for="yanzheng" class="col-sm-2 control-label">验证码</label><div class="col-sm-10"><div class="input-group"><input type="text" class="form-control" placeholder="请输入验证码"><span class="input-group-btn"><button class="btn btn-default" type="button" id="yanzheng">获取验证码</button></span></div><!-- /input-group --></div></div><div class="form-group"><div class="col-sm-offset-3 col-sm-6"><button type="submit" class="btn btn-success btn-block">确认</button></div></div></form></div></div></div></div>
{% endblock %}

登录界面

{% extends "common/base.html" %}
{% block content %}<div class="row" style="margin-top: 50px"><div class="col-lg-6 col-lg-offset-3"><div class="panel panel-default"><div class="panel-heading">用户登录</div><div class="panel-body"><form class="form-horizontal"><div class="form-group"><label for="login_name" class="col-sm-2 control-label">用户名</label><div class="col-sm-10"><input type="email" class="form-control" id="login_name" placeholder="请输入用户名"></div></div><div class="form-group"><label for="login_pwd" class="col-sm-2 control-label">密码</label><div class="col-sm-10"><input type="password" class="form-control" id="login_pwd" placeholder="请输入密码"></div></div><div class="form-group"><div class="col-sm-offset-3 col-sm-6"><button type="submit" class="btn btn-success btn-block">登录</button></div></div></form></div></div></div></div>
{% endblock %}

7.3 注册功能实现

模板函数

from app import appclass UrlManager(object):@staticmethoddef buildUrl(path):config_domain = app.config['DOMAIN']return "%s%s"%(config_domain['www'], path)@staticmethoddef buildStaticUrl(path):path = "/static" + pathreturn UrlManager.buildUrl(path)

发送邮箱验证码
register.js

function bindEmailCaptchaClick(){$("#yanzheng").click(function (event){// $this:代表的是当前按钮的jquery对象var $this = $(this);// 阻止默认的事件event.preventDefault();var email = $("#login_email").val();$.ajax({// http://127.0.0.1:500// /auth/captcha/email?email=xx@qq.comurl: "/member/captcha/email?email="+email,method: "GET",success: function (result){var code = result['code'];if(code == 200){var countdown = 5;// 开始倒计时之前,就取消按钮的点击事件$this.off("click");var timer = setInterval(function (){$this.text(countdown);countdown -= 1;// 倒计时结束的时候执行if(countdown <= 0){// 清掉定时器clearInterval(timer);// 将按钮的文字重新修改回来$this.text("获取验证码");// 重新绑定点击事件bindEmailCaptchaClick();}}, 1000);// alert("邮箱验证码发送成功!");}else{alert(result['message']);}},fail: function (){console.log("获取验证码失败");}})});
}// 整个网页都加载完毕后再执行的
$(function (){bindEmailCaptchaClick();
});

路由

@member_page.route("/captcha/email")
def get_email_captcha():# /captcha/email/<email># /captcha/email?email=xxx@qq.comemail = request.args.get("email")# 4/6:随机数组、字母、数组和字母的组合source = string.digits*6captcha = random.sample(source, 6)captcha = "".join(captcha)# I/O:Input/Outputmessage = Message(subject="注册验证码", recipients=[email], body=f"您的验证码是:{captcha}")mail.send(message)# memcached/redis# 用数据库表的方式存储if len(EmailCaptcha.query.filter(EmailCaptcha.email == email).all()) != 0:EmailCaptcha.query.filter(EmailCaptcha.email == email).delete()db.session.commit()email_captcha = EmailCaptcha(email=email, captcha=captcha)db.session.add(email_captcha)db.session.commit()# RESTful API# {code: 200/400/500, message: "", data: {}}return jsonify({"code": 200, "message": "出现错误,请重试!", "data": None})
@member_page.route("/login", methods=['GET', 'POST'])
def login():if request.method == 'GET':return render_template("/member/login.html")else:form = LoginForm(request.form)if form.validate():email = form.email.datapassword = form.password.datauser = User.query.filter_by(login_name=email).first()if not user:print("邮箱在数据库中不存在!")return render_template("/member/login.html")else:if check_password_hash(user.login_pwd, password):# cookie:# cookie中不适合存储太多的数据,只适合存储少量的数据# cookie一般用来存放登录授权的东西# flask中的session,是经过加密后存储在cookie中的session['user_id'] = user.idreturn render_template("/index.html")else:print("密码错误!")return render_template("/member/login.html")else:print(form.errors)return render_template("/member/login.html")

表单验证。

import wtforms
from wtforms.validators import Email, Length, EqualTo, InputRequired
from user import EmailCaptcha, User
from exts import db# Form:主要就是用来验证前端提交的数据是否符合要求
class RegisterForm(wtforms.Form):email = wtforms.StringField(validators=[Email(message="邮箱格式错误!")])captcha = wtforms.StringField(validators=[Length(min=6, max=6, message="验证码格式错误!")])username = wtforms.StringField(validators=[Length(min=3, max=20, message="用户名格式错误!")])password = wtforms.StringField(validators=[Length(min=6, max=20, message="密码格式错误!")])password_confirm = wtforms.StringField(validators=[EqualTo("password", message="两次密码不一致!")])# 自定义验证:# 1. 邮箱是否已经被注册def validate_email(self, field):email = field.datauser = User.query.filter_by(login_name=email).first()if user:raise wtforms.ValidationError(message="该邮箱已经被注册!")# 2. 验证码是否正确def validate_captcha(self, field):captcha = field.dataemail = self.email.datacaptcha_model = EmailCaptcha.query.filter_by(email=email, captcha=captcha).first()if not captcha_model:raise wtforms.ValidationError(message="邮箱或验证码错误!")else:# todo:可以删掉captcha_modeldb.session.delete(captcha_model)db.session.commit()class LoginForm(wtforms.Form):email = wtforms.StringField(validators=[Email(message="邮箱格式错误!")])password = wtforms.StringField(validators=[Length(min=6, max=20, message="密码格式错误!")])
#
#
# class QuestionForm(wtforms.Form):
#     title = wtforms.StringField(validators=[Length(min=3, max=100, message="标题格式错误!")])
#     content = wtforms.StringField(validators=[Length(min=3,message="内容格式错误!")])
#
#
# class AnswerForm(wtforms.Form):
#     content = wtforms.StringField(validators=[Length(min=3, message="内容格式错误!")])
#     question_id = wtforms.IntegerField(validators=[InputRequired(message="必须要传入问题id!")])

8 获取影视资源

apscheduler
测试apscheduler功能。

from apscheduler.schedulers.blocking import BlockingScheduler
import datetimedef aps_test():print(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))scheduler = BlockingScheduler()
scheduler.add_job(func=aps_test,trigger="cron",second="*/5")
scheduler.start()

Flask-APScheduler
可以查看一下此时的app.py和manger.py。

from app import app, db, schedulerdef main():app.run(host="0.0.0.0", use_reloader=True)  # 改为False可以只打印一遍def create_all():from user import Userwith app.app_context():db.create_all()def aps_test():import datetimeprint(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))if __name__ == '__main__':app.apscheduler.add_job(func=aps_test, trigger="cron", second="*/5", id="aps_test")scheduler.start()# create_all()try:import syssys.exit(main())except Exception as e:import  tracebacktraceback.print_exc()
from flask import Flask, session, g
from controller.index import index_page
from controller.member import member_page
from flask_apscheduler import APScheduler
import configs
from user import User
from exts import db, mail# 初始化实例
app = Flask(__name__)
# 加载配置文件
app.config.from_object(configs)
# 增加session会话保护(任意字符串,用来对session进行加密)
app.secret_key = "day3"# 调度
scheduler = APScheduler()
scheduler.init_app(app)# db绑定app
db.init_app(app)
mail.init_app(app)
# 注册蓝图
app.register_blueprint(index_page, url_prefix="/")
app.register_blueprint(member_page, url_prefix="/member")'''
模板函数
'''from libs import UrlManagerapp.add_template_global(UrlManager.buildUrl, 'buildUrl')
app.add_template_global(UrlManager.buildStaticUrl, 'buildStaticUrl')@app.before_request
def my_before_request():user_id = session.get("user_id")if user_id:user = User.query.get(user_id)setattr(g, "user", user)else:setattr(g, "user", None)@app.context_processor
def my_context_processor():return {"user": g.user}@app.errorhandler(404)
def error_404(e):return "404 not found"

8.1 影视表设计

下载爬虫相关库。

pip install --upgrade beautifulsoup4
pip install requests
pip install xlwt

需要注意
chrome_G5TWQ6Iixe.png
使用Navicat进行数据库的导入。

flask-sqlacodegen ‘mysql+mysqldb://root:root@127.0.0.1:3306/moviecat?charset=utf8’ --table movie --outfile “user1.py” --flask

# -*- coding: utf-8 -*-
import sys
import re  # 正则表达式,进行文字匹配
from bs4 import BeautifulSoup  # (网页解析,获取数据)
import urllib.request, urllib.error  # 制定URL,获取网页数据,urllib.request urllib.error
import xlwt  # 进行Excel操作
import sqlite3  # 进行sqlite数据库操作
def main():baseurl = "https://movie.douban.com/top250?start="datalist = getdata(baseurl)# savepath = "豆瓣电影top250.xls"dbpath = "movie.db"saveData2DB(datalist, dbpath)findlink = re.compile(r'<a href="(.*?)">')  # 找链接
findImgSrc = re.compile(r'<img.*src="(.*?)"', re.S)  # 图片
findTitle = re.compile(r'<span class="title">(.*)</span>')  # 片名
findRating = re.compile(r'<span class="rating_num" property="v:average">(.*)</span>')  # 评分
findJudge = re.compile(r'<span>(\d*)人评价</span>')  # 评价人数
findInq = re.compile(r'<span class="inq">(.*)</span>')  # 概况
findBd = re.compile(r'<p class="">(.*?)</p>', re.S)  # 简介# 爬取网页
def getdata(baseurl):datalist = []for i in range(0, 10):url = baseurl + str(i * 25)html = askURL(url)# 逐一解析数据soup = BeautifulSoup(html, "html.parser")for item in soup.find_all('div', class_="item"):# print(item)   测试:查看电影item所有信息data = []  # 保存信息item = str(item)link = re.findall(findlink, item)[0]# print(link)#影片链接data.append(link)  # 添加影片链接imgSrc = re.findall(findImgSrc, item)[0]data.append(imgSrc)  # 添加图片titles = re.findall(findTitle, item)if (len(titles) == 2):ctitle = titles[0]  # 添加中国名data.append(ctitle)otitle = titles[1].replace("/", "")  # 去掉无关符号data.append(otitle)  # 添加外国名else:data.append(titles[0])data.append(' ')  # 留空rating = re.findall(findRating, item)[0]data.append(rating)  # 分数judgenum = re.findall(findJudge, item)[0]data.append(judgenum)  # 评价人数inq = re.findall(findInq, item)  # 概述if len(inq) != 0:inq = inq[0].replace("。", "")  # 去掉句号data.append(inq)else:data.append(" ")bd = re.findall(findBd, item)[0]bd = re.sub('<br(\s+)?/>(\s+)?', " ", bd)bd = re.sub('/', " ", bd)data.append(bd.strip())  # 去掉空格datalist.append(data)  # 将所有信息放入datalistreturn datalistdef askURL(url):head = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36 Edg/92.0.902.78"}request = urllib.request.Request(url, headers=head)  # 封装html = ""try:response = urllib.request.urlopen(request)html = response.read().decode('utf-8', errors='ignore')# print(html)except urllib.error.URLError as e:if hasattr(e, "code"):print(e, code)if hasattr(e, "reason"):print(e, reason)return html# 保存数据
def savedata(datalist, savepath):print("save....")book = xlwt.Workbook(encoding="utf-8", style_compression=0)  # 创建workbook对象sheet = book.add_sheet("豆瓣电影top250", cell_overwrite_ok=True)  # 创建工作表col = ("电影链接", "图片链接", "中文名", "外国名", "评分", "评价人数", "概况", "相关信息")for i in range(0, 8):sheet.write(0, i, col[i])for i in range(0, 250):print("第%d条" % (i + 1))data = datalist[i]for j in range(0, 8):sheet.write(i + 1, j, data[j])book.save(savepath)def saveData2DB(datalist, dbpath):print("loading.................")init_db(dbpath)conn = sqlite3.connect(dbpath)cur = conn.cursor()for data in datalist:for index in range(len(data)):if index == 4 or index == 5:continuedata[index] = '"' + data[index] + '"'sql = '''insert into movie250_2(info_link,pic_link,cname,ename,score,rated,instroduction,info)values(%s)''' % ",".join(data)print(sql)cur.execute(sql)conn.commit()cur.close()conn.close()print("已完成数据库操作")def init_db(dbpath):sql = '''create table movie250_2(id integer primary key autoincrement,info_link text,pic_link text,cname varchar,ename varchar,score numeric,rated numeric,instroduction text,info,text)'''conn = sqlite3.connect(dbpath)cursor = conn.cursor()cursor.execute(sql)conn.commit()conn.close()if __name__ == "__main__":main()print("爬取完毕!")

navicat_WjHHSDwoeQ.png

8.2 前端展示

index.html

{% extends "common/base.html" %}
{% block head2 %}
<ul class="nav navbar-nav navbar-right"><li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"aria-expanded="false">用户<span class="caret"></span></a><ul class="dropdown-menu"><li><a href="#">{{ user.nickname }}</a></li><li><a href="{{ url_for('member_page.logout') }}">退出登录</a></li></ul></li>
</ul>
{% endblock %}
{% block content %}
<div class="row">{% if data %}{% for item in data %}<div class="col-md-2"><div class="thumbnail"><img style="width: 100%;height: 250px" src="{{ item.pic_link | safe}}"><div class="caption"><a href="{{ item.info_link }}" style="overflow: hidden;text-overflow: ellipsis;display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp: 1">{{ item.cname | safe}}</a><p>豆瓣评分:{{ item.score | safe }}</p></div></div></div>{% endfor %}{% endif %}
</div>
<div class="row"><div class="col-md-12"><span class="pagination_page" style="line-height: 84px">共有{{ pages.total_pages }}页 | 每页{{ pages.page_size }}条</span><ul class="pagination pull-right">{% if pages.is_prev == 1 %}<li><a href="/?p={{ pages.current - 1 }}" aria-label="Previous"><span aria-hidden="true">上一页;</span></a></li>{% endif %}{% for idx in  pages.range%}<li {% if pages.current == idx %}class="active"{% endif %}><a href="/?p={{ idx }}">{{ idx }}</a></li>{% endfor %}{% if pages.is_next == 1 %}<li><a href="/?p={{ pages.current + 1 }}" aria-label="Previous"><span aria-hidden="true">下一页</span></a></li>{% endif %}</ul></div>
</div>
{% endblock %}

index.py

from flask import Blueprint, render_template, g, redirect, url_for, request
from user import Movie
import mathindex_page = Blueprint("index_page", __name__)@index_page.route("/")
def index():if g.user:req = request.valuespage = 1if 'p' in req and req['p']:page = int(req['p'])query = Movie.querypage_size = 30total_count = query.count()total_pages = math.ceil(total_count / page_size)total_pages = total_pages if total_pages > 0 else 1is_prev = 0 if page <= 1 else 1is_next = 0 if page >= total_pages else 1pages = {'page_size':page_size,'total_count':total_count,'total_pages':total_pages,'range':range(1,total_pages+1),'is_prev':is_prev,'is_next':is_next,'current':page}offset = (page - 1) * pages['page_size']limit = page * pages['page_size']list_movie = query[offset:limit]return render_template("/index.html", data=list_movie, pages=pages)else:return redirect(url_for("member_page.login"))@index_page.route("info")
def info():req = request.valuesreturn render_template("info.html")

chrome_zQnuKpFebp.png
chrome_VQLvZGniNP.png

9 部署

nginx+uwsgi+flask
使用如下命令进行启动。

uwsgi --http-socket :5000 --wsgi-file manger.py --callable app

还可以加进程和线程数提高并发能力

uwsgi --http-socket :5000 --wsgi-file manger.py --callable app --processes 4 --threads 2

写配置文件

[uwsgi]
chdir=/home/WF/ubuntuFlask/moviecat
http=0.0.0.0:5000
socket=/tmp/logs/movie.sock
module=manger
callable=app
master=true
processes=4
pidfile=/tmp/logs/movie.pid
daemonize=/tmp/logs/movie.log

启动

uwsgi --ini uwsgi.ini

关闭

uwsgi --stop uwsgi.ini

重启

uwsgi --reload uwsgi.ini

下载ngnix
https://blog.csdn.net/weixin_42973884/article/details/126251718

sudo apt-get update
sudo apt-get install nginx
ngnix # 启动
service nginx stop # 停止
service nginx reload # 重启

chrome_YO8sTLv7mB.png
https://blog.csdn.net/weixin_39759781/article/details/118303445

cd /etc/nginx

PotPlayerMini64_yrN1hi1C9K.png
半夜三点了还没配好,我真的是服了,留个坑后面补。



相关文章:

  • 《C++ primer plus》第15章:友元、异常和其他(4)
  • Android开发环境搭建
  • CS61B 2021spring HW0
  • 高阶数据结构 位图的介绍
  • 【时间复杂度和空间复杂度】
  • Linux产生死锁的必要条件和常见的锁种类
  • Python与Matlab混合编程案例
  • 17 | 如何做好面试复盘?将经验提升为能力
  • layui框架学习(1:布局)
  • Ubuntu安装wordpress
  • 【Linux】POSIX信号量
  • 【云原生】Prometheus 监控系统的初步了解与系统搭建
  • stack、queue、priority_queue
  • 高通平台开发系列讲解(GPS篇)gpsONE 系统架构
  • Lab 3: Midterm Review
  • C#手动操作DataGridView之------使用各种数据源填充表格实例
  • Python map() 使用方法及示例
  • 【Leetcode刷题】141、环形链表
  • 前同事居然因为 Pycharm 的这个功能,即使离职三年也依然经常被请去喝茶~
  • 量化选股——基于多因子模型的量化策略(第1部分—因子测算策略构建)
  • 【SpringCloud】Nacos集群搭建
  • 从源码解析代理模式
  • goto语句——“C”
  • 行为型模式-状态模式
  • C++学习/温习:新型源码学编程(一)
  • gcc中预定义的宏__GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__
  • 【图卷积网络】02-谱域图卷积介绍
  • 分享148个ASP源码,总有一款适合您
  • 2023.1.25,周三【图神经网络 学习记录9】图网络的分类,异构图---注意力机制网络:节点级别的attention,语义级别的attention
  • Jetpack架构组件库:Room
  • kaggle竞赛 | 计算机视觉 | Doodle Recognition Challenge
  • 盖子的c++小课堂——第十三讲:二维数组
  • 打工人必知必会(二)——劳动合同解除
  • 数据结构 第三章 栈和队列(栈)
  • 大年初二、初三—— 牛客网刷题经验分享~
  • 利用Windows系统服务进行权限提升
  • 2021 XV6 8:locks
  • 排列的时候如何避免重复?
  • 机器学习【西瓜书/南瓜书】--- 第四章决策树
  • ffmpeg无损裁剪、合并视频
  • 《C++ primer plus》第15章:友元、异常和其他(3)
  • 3.7-2动态规划--图像压缩(举例子和写代码)
  • Java基础练习题(十二)
  • VBA提高篇_07 Goto跳转 / Exit退出 /VBA错误处理
  • 栈与队列总结
  • 最详细、最仔细、最清晰的几道python习题及答案(建议收藏哦)
  • Java基础练习题(十一)
  • 流批一体计算引擎-7-[Flink]的DataStream连接器
  • c++函数(2)
  • RabbitMQ-客户端源码之AMQChannel
  • 学习记录673@项目管理之进度管理案例
  • 【23】C语言 | 初阶结构体
  • k8s单机版使用本地存储local-path-provisioner
  • 【Git】Git 的基本使用
  • 【MySQL】第十二部分 子查询
  • WPF的APP生命周期以及全局异常捕获
  • C++初阶:vector类
  • 2022年度总结——2022我在CSDN的那些事暨2023我的目标展望:Pursue freedom Realize self-worth
  • 自动驾驶环境感知——视觉传感器技术
  • 机器学习中软投票和硬投票的不同含义和理解
  • 3.1(完结)Linux扫盲笔记
  • 冯诺依曼体系结构及操作系统(OS)的简单认识
  • 返回值的理解
  • Linux常见命令 25 - RPM包安装、升级、卸载、查询、校验、提取
  • 【Typescript学习】使用 React 和 TypeScript 构建web应用(三)所有组件
  • 【VisualBasicApplication】Excel编程
  • Linux系统之网络客户端工具
  • uniapp组件传参方式梳理
  • 手把手教你如何在项目中使用阿里字体图标IconFont
  • C语言函数调用详解
  • 离散系统的数字PID控制仿真-3
  • Day11 AOP介绍
  • 本质安全设备标准(IEC60079-11)的理解(三)
  • Let’s Encrypt SSL 证书的申请与使用
  • Linux——动态库
  • leetcode刷题记录总结-3. 哈希表
  • linux基本功系列之-rpm命令实战
  • 时序数据处理中的拟合问题
  • 3小时精通opencv(五) 利用TrackBar进行颜色检测
  • 数学建模学习笔记(9)多元线性回归分析(非常详细)
  • Python爬虫教你爬取视频内容
  • 数据库02_函数依赖,数据库范式,SQL语句关键字,数据库新技术---软考高级系统架构师009
  • 如何好好说话-第12章 理清楚问题就是答案
  • Java链表OJ题
  • 前端布局神器display:flex
  • Jetpack架构组件库:Hilt
  • Java基础语法——运算符与表达式
  • 安装mysql 5.7.24
  • 一周学习总结(2022.1.25)
  • CSS基础学习
  • Linux文件系统(IO缓冲区+磁盘+软硬链接)
  • 【servlet篇】HTTP协议相关知识点
  • Java---微服务---RabbitMQ入门与应用
  • 7.3 矩阵范数
  • JMeter测试redis性能
  • 【设计模式】结构型模式·组合模式
  • 第十三届蓝桥杯省赛 Java A 组 I 题、Python A 组 I 题、Python B 组 J 题——最优清零方案(AC)
  • 41.Isaac教程--使用DOPE进行3D物体姿态估计
  • 【Linux】gdb调试器的使用
  • 互联网摸鱼日报(2023-01-26)
  • python语法 dot函数
  • Docker 基础 - 3
  • 如何使用Maven构建Java项目?Maven的使用详细解读
  • RISC-V Assembler Modifiers
  • VMware虚拟机无法向宿主机拖放文件
  • Mybatis-Plus 多记录操作与逻辑删除
  • 【Python语言基础】——Python 迭代器
  • [Python]调用pytdx的代码示例
  • 【Linux】目录权限和默认权限
  • APT之木马静态免杀
  • Python装饰器使用方法详解
  • SpringBoot+Vue项目在线视频教育平台
  • 利用Golang可选参数实现可选模式
  • 游戏启动器:LaunchBox Premium with Big Box v13.1
  • CSS权威指南(十)浮动
  • RESTful的意义及其使用规则
  • SpringMVC总结
  • Android MVVM的实现
  • 0、Spring工程构建Spring快速入门Spring配置文件详解注入Sprint相关API
  • PostGIS:ST_AREA面积计算
  • 厚积薄发打卡Day115:Debug设计模式<简单工厂、工厂方法、抽象工厂>
  • 【MySQL进阶】MySQL视图详解
  • kubernetes资源对象应用类(二)
  • 线程控制--Linux
  • 测试篇(三):测试用例的万能公式、对水杯和登录页面设计测试用例、测试用例的设计方法
  • 面试屡次碰壁后,我是如何调整最终拿下一线大厂offer的?
  • 在甲骨文云容器实例(Container Instances)上部署Oracle Linux 8 Desktop加强版(包括Minio,ssh登录等)
  • 重学python
  • Java 方法
  • 分享142个ASP源码,总有一款适合您
  • 树型结构——二叉数
  • 2-SAT
  • 8. 好客租房-WebSocket与即时通讯系统[项目必需]
  • Linux 命令(249)—— unset 命令(builtin)
  • 【1】初识Linux
  • 数据结构---堆
  • python元组
  • 【My Electronic Notes系列——直流稳压电源】
  • 有关Android的TextView组件的几个问题
  • Spring核心模块解析—BeanDifinition。
  • JavaEE多线程-定时器
  • C++编译之(4)-进阶-cmake设置install及package配置
  • 【每日一道智力题】之坤坤猜生日(面试高频)
  • 斐波那契数列的--------5种算法(又称“兔子数列”)
  • Java基础 IO
  • Extractor.app学习
  • 深入学习Vue.js(十四)同构渲染
  • Spring笔记上(基于注解开发)
  • 定位 position属性 相对定位 绝对定位 固定定位 定位下的居中 多个定位元素重叠时 补充
  • NLP | 打造一个‘OpenAI智能’机器人,只需要五分钟
  • 好的质量+数量 = 健康的创作者生态
  • 设计一个70W在线人数的弹幕系统
  • JavaWeb | 揭开SQL注入问题的神秘面纱
  • 【编程入门】开源记事本(微信小程序版)
  • 2022年复盘:越走越偏
  • C语言深度解剖-关键字(1)
  • 千峰学习【Ajax】总结
  • 【设计模式】结构型模式·享元模式
  • Redis实现好友关注 | 黑马点评
  • Ubuntu 20.04 下 部署 SoftEther
  • Python OS 文件目录方法 os.walk()
  • 《Buildozer打包实战指南》第七节 打包资源文件
  • 关于非授权访问的逻辑漏洞挖掘
  • 数据结构-树
  • JavaWeb项目中添加live2d模型
  • VBA提高篇_05日期时间函数
  • HackTheBox Stocker API滥用,CVE-2020-24815获取用户shell,目录遍历提权
  • 正则表达式(转载)
  • 【Android】开发一个简单时钟应用每天看时间起床
  • 常见DEM数据汇总
  • 如何设计一个 70w 在线人数的弹幕系统
  • “华为杯”研究生数学建模竞赛2005年-【华为杯】D题:仓库容量有限条件下的随机存贮管理(附获奖论文)
  • 3000字英文随笔(挽救下语感)
  • MS-Model【3】:Medical Transformer
  • 2023第五届中国眼博会,北京眼睛健康展,北京护眼仪展
  • 【JavaEE初阶】第六节.多线程 (基础篇 )线程安全问题(下篇)
  • 好客租房-09_学习MongoDB并完善通讯系统
  • 提权漏洞和域渗透历史漏洞整理
  • OCR文字识别基础
  • 辗转相除以及辗转相减法
  • 【Linux】多线程同步与互斥
  • 【HBase入门】5. 常用 Shell 操作(2)
  • 构造函数的4种使用方式总结
  • 如何取消PDF文件的保护设置?
  • 第二章 物理层
  • JAVA中static、final、static final的区别
  • 行为型模式-命令模式
  • 在线工具轻松设计电商直通车主图,无需下载
  • 水面漂浮物垃圾识别检测系统 YOlOv7
  • 【蓝桥云课】位运算
  • 2023-1-24 刷题情况
  • Java面试题,mysql相关基础问题(全是自己的总结,如有不对,敬请斧正)
  • flask框架全解
  • 机器视觉_HALCON_HDevelop用户指南_1.HDevelop介绍
  • C 语言零基础入门教程(九)
  • 机器学习(七):Azure机器学习模型搭建实验
  • JavaScript总结
  • 90. 注意力分数及代码实现
  • 从技术角度看Android大系统的构成
  • 如何设计一个70W在线人数的弹幕系统文章分析
  • TPH-YOLOv5
  • 前缀树 字典树 TrieTree的学习与模拟实现
  • vue2升级vue3:vue3真的需要vuex或者Pinia吗?hooks全有了
  • 如何好好说话第11章 攀登抽象之梯
  • 模型压缩(model compression)
  • 如何安装双系统与多系统(带你快速了解)
  • JAVA基础知识08集合基础
  • java-List
  • 超级详解洛谷P4011 孤岛营救问题(bfs超难题)(保证看懂)
  • Linux- 系统随你玩之--文本处理三剑客-带头一哥-awk
  • [JavaEE]线程池
  • java选择结构与switch case语句
  • MySQL 安装包下载
  • 小动画制作时需要的知识点
  • STM32+python产生三角波
  • 【刷题大本营】二叉树进阶oj题(动图讲解,附代码及题目链接)
  • 【手写 Promise 源码】第二篇 - Promise 功能介绍与特性分析
  • RAID不同类型之间的区别
  • 机器学习(六):模型评估
  • spring boot前后端交互之数据格式转换
  • Java多线程案例之阻塞队列
  • 5-6中央处理器-多处理器系统硬件多线程
  • FME进阶视频教程: FME常用转换器之坐标系操作类,讲解在FME中如何操作矢量数据的坐标系
  • LeetCode(Array)1431. Kids With the Greatest Number of Candies
  • matplotlib嵌套南海子图
  • 91.使用注意力机制的seq2seq以及代码实现
  • 目录生成测试
  • 函数的认识
  • 笔试题-2023-华为-数字芯片【纯净题目版】
  • ROS学习寄录之知识学习
  • 传参的理解
  • 网狐大联盟非联盟成员无法创建房间解决-暂时不可创建当前游戏,请选择其他游戏!
  • MyBatisPlus入门简介
  • 对JDBC驱动注册--DriverManager.registerDriver和Class.forName(driverClass)的理解
  • 【老卫搞机】136期:华为开发者联盟社区2022年度战码先锋2期开源贡献之星
  • JVM快速入门学习笔记(四)
  • 第一章 概述
  • 【大数据管理】Java实现字典树TireTree
  • 第24章 Microsoft.Data.SqlClient中间件数据库生成
  • Mybatis 基本使用案例
  • 通过实例了解uprobe及其对性能的影响
  • linux基本功系列之wc命令实战
  • [GYCTF2020]EasyThinking (ThinkPHP V6.0.0)
  • [Linux]进程地址空间
  • 2023年最新Python常见编程面试题(1)精选30个题目附答案
  • pythpon基础:创建文件索引升级版
  • 【Python语言基础】——Python 继承
  • 24. 面向对象的思想
  • 【蓝桥杯-筑基篇】基础数学思维与技巧(1)
  • MyBatis的入门
  • Linux中的权限问题
  • leetcode72 编辑距离
  • Vue3【1.v-if 和 v-show 、2.动态组件、 3.网页的渲染 、4.v-for】
  • 高等数学(第七版)同济大学 习题12-8 个人解答
  • 计算机存储系统
  • 目标检测知识蒸馏---以SSD为例【附代码】
  • 【Kotlin】扩展函数 ③ ( 定义扩展文件 | 重命名扩展函数 | Kotlin 标准库扩展函数 )
  • 图论(入门版)
  • Linux存活指令和具体使用方法
  • ★ 我的世界各类奇葩武器实现!(命令方块1.13+)
  • 基于ImageAI的图像识别
  • 【论文阅读】吴恩达分享的论文阅读方法
  • DlhSoft Gantt Chart Light Library 4.3.47 Crack
  • Docker 解决 `denied: requested access to the resource is denied`
  • ROS学习寄录之环境搭建
  • 想要学会二叉树?树的概念与结构是必须要掌握的!快进来看看吧
  • MySQL事务的四大特性以及并发事务问题
  • SpringBoot-过滤器的使用(在访问页面时过滤掉未登录的用户使其不能访问相应页面)
  • ricequant量化的基础是什么?
  • 条款2:理解auto型别推导
  • Linux|奇怪的知识---CPU温度监控
  • 笔试题-2023-杰理科技-数字IC设计【纯净题目版】
  • 离线用户基于内容召回集
  • GPU虚拟化(留坑)
  • spingboot如何接受前端请求
  • python列表用法
  • 2023起点上,一段迷茫的自我倾诉
  • 数学小抄: 李群李代数再回顾 [SLAM十四讲]
  • Vuex里面四个map方法(mapState、mapGetters、mapActions、mapMutation)
  • CSS之浮动以及清除浮动的几种方式
  • 27. 作用域
  • Windows CMD命令大全
  • Python流程控制语句之循环语句
  • 好客租房-13.WebMagic
  • Springboot+java师生交流答疑作业系统
  • 基于Android的高校疫情防控信息系统的设计与实现
  • 通过Moonbeam的Connected Contracts互连合约从Axelar转移Token至Centrifuge
  • 77、TensoRF: Tensorial Radiance Fields
  • 基于Android的动漫之家系统的设计与实现
  • 【C++】深浅拷贝
  • Springboot整合Redis
  • 基于代理 Dao 实现 CRUD 操作
  • Java线程池(超详细)
  • ESP32设备驱动-8x8LED点阵驱动(基于Max7219+SPI)
  • Python-Flask-2023.1.24-Review
  • HTML学习
  • mysql之explain(性能分析)
  • C语言基础知识(38)
  • go 语言 string 类型思考
  • AxMath使用教程(持续更新中)
  • /proc/meminfo的理解vmtouch使用介绍内存碎片整理
  • 行为型模式-模板方法模式
  • WordPress整站源码安装说明(搬家换域名/服务器)的安装步骤
  • 最小化最大值+拓扑排序要点+概率
  • 十大经典排序算法(动态演示+代码)-选择排序与插入排序
  • 好客租房-12.ES接入java
  • 【Linux】Linux调试器——gdb使用
  • 5-5中央处理器-指令流水线
  • HTML基本常用标签
  • java+ssm网上书店图书销售评价系统
  • 【数据结构】详谈复杂度
  • Python函数(函数定义、函数调用)用法详解
  • Python基础学习 -- 常用模块
  • k8s安装nfs设置pv pvc并部署mysql
  • BERT模型结构可视化与模块维度转换剖析
  • 【LeetCode】计算右侧小于当前元素的个数 [H](归并排序)
  • 【每日一道智力题】三个火枪手(快来看人生哲理)
  • SaaS是什么,目前主流的国内SAAS平台提供商有哪些?
  • Opencv项目实战:19 手势控制鼠标
  • 2023 年第一弹, Flutter 3.7 发布啦,快来看看有什么新特性
  • 3.5动态规划--凸多边形的最优三角剖分
  • (python)selenium工具的安装及其使用
  • 对多线程中线程池的理解
  • 深度学习流行的框架有哪些?分别有什么特点
  • C++初阶--多态
  • Leetcode:46. 全排列、47. 全排列 II(C++)
  • LeetCode13罗马数字转整数
  • CE训练教程进阶,步骤 9: 注入++
  • 【21】C语言 | 几个经典数组练习题
  • VMWare 移动Linux CentOS 7虚拟机后连不上网怎么办
  • 【Ubuntu】Nacos 2.1 单机安装
  • LeetCode 2520. 统计能整除数字的位数
  • “深度学习”学习日记。与学习有关的技巧--Bacth Normalization
  • Ubuntu下为可执行文件和脚本文件(.sh)生成桌面快捷方式
  • 【c语言进阶】结构体最常用知识点大全
  • 30. PyQuery: 基于HTML的CSS选择器
  • 初出茅庐——索引和文档的基本操作
  • C++:类中const修饰的成员函数
  • AtCoder Beginner Contest 285 题解
  • 2023年springcloud面试之Eureka(第二部分)
  • 为 TDesignBlazor 添加暗黑模式
  • DFS(六) N皇后 II
  • Linux中的工具使用【vim的存活级】
  • JavaScript 所见所得文本编辑器 Froala Editor 4.0.17Crack
  • Allegro如何自动做差分对内等长操作指导
  • 洛谷-P2114 [NOI2014] 起床困难综合症
  • 【学习笔记】[AGC023E] Inversions
  • JDBC连接池多线程通过CountDownLatch实现线程并发执行
  • ISIS简介、NSAP与NET地址、Router-Id转换成NET地址
  • 【GIS】高分辨率遥感影像智能解译
  • C语言基础 — ( C语言库函数<stdio.h>——C标准的内容)
  • AI算法(三)plt基础
  • final的一个重要用途-宏变量和未初始化问题
  • C++空间命名
  • 快速排序的实现和优化~
  • macOS Ventura 13.2 (22D49) 正式版发布,ISO、IPSW、PKG 下载
  • MS Access数据库多数据源JDBC查询
  • 十大经典排序算法(动态演示+代码)-堆排序
  • Python3 round() 函数
  • 信息论复习—连续信源、信道及容量
  • RadSystems Studio 8.1.8 Crack
  • 【自然语言处理】情感分析(一):基于 NLTK 的 Naive Bayes 实现
  • 【MySQL】第十一部分 SELECT的执行过程
  • 【目标跟踪】------deepsort
  • 2023牛客寒假算法集训营3
  • 基于Springboot vue前后端分离在线培训考试系统源码
  • MyBatis基本使用及XML配置
  • Java数组
  • [数据结构基础]排序算法第一弹 -- 直接插入排序和希尔排序
  • 鱼雷的发射角设置
  • 深度学习数据标注_Lableme
  • JavaWeb语法八:网络原理初识
  • 基于STM32的FreeRTOS开发(1)----FreeRTOS简介
  • 搭建本地Maven仓库
  • 算法:树状数组详解(c++实现 求解动态数组区间和问题)
  • 《深入浅出计算机组成原理》学习笔记 Day10
  • day 19 暴力枚举
  • 尚医通-手机登录-判断用户登录状态-用户网关整合(三十)
  • 使用Vue 简化 用户查询/添加功能
  • emoji 符号大全,给各位程序员增加一些奇怪的知识点
  • Mysql入门技能树-数据类型
  • Eclipse导入python项目
  • 简明Java讲义 2:数据类型和运算符
  • 【JavaWeb】JavaScript基础语法(下)
  • 56. 合并区间 738.单调递增的数字
  • 数据库和SQL概述
  • 力扣刷题记录——645. 错误的集合、657. 机器人能否返回原点、674. 最长连续递增序列
  • AtCoder Regular Contest 149
  • 常用的负载均衡算法
  • 恶意代码分析实战 14 反虚拟机技术
  • Mine Goose Duck 0.2版本发布
  • 离线用户召回定时更新
  • MP-4可燃气体传感器介绍
  • 【设计模式】结构型模式·外观模式
  • C C++实现两矩阵相乘--模拟法
  • 服务器配置定时脚本 crontab + Python;centos6或centos 7或centos8 实现定时执行 python 脚本
  • git 操作整理
  • ESP32设备驱动-TSL2561亮度传感器驱动
  • SOLID原则总结
  • 机器学习笔记之深度玻尔兹曼机(二)深度玻尔兹曼机的预训练过程
  • [Android开发基础1] 五大常用界面布局
  • JavaEE day4 初识HTML+总结3
  • 【C#】WPF实现经典纸牌游戏,适合新手入门
  • LA@determinant@行列式@Vandermonde行列式
  • python爬虫学习笔记-mysql数据库介绍下载安装
  • Linux使用YUM源安装Docker
  • Prometheus学习整理-Prometheus-operator
  • Python(for和while)循环嵌套及用法
  • Elasticsearch:Elasticsearch percolate 查询
  • mysql之索引
  • 【Linux】文件权限
  • MySQL内外连接
  • 04_iic子系统
  • IPV4地址详解
  • 矩阵理论复习(六)
  • AX7A200教程(4): DDR3的读写fifo仿真
  • 2023牛寒2--Tokitsukaze and Three Integers
  • [ 华为云 ] 云计算中Region、VPC、AZ 是什么,他们又是什么关系,应该如何抉择
  • 【电动车】基于多目标优化遗传算法NSGAII的峰谷分时电价引导下的电动汽车充电负荷优化研究(Matlab代码实现)
  • 20230125英语学习
  • Linux常见命令 8 - 其他文件搜索命令 locate, which, whereis, grep
  • 前端艺术之毛玻璃-倾斜-日历
  • Java基础 Stream流方法引用异常文件
  • TCP/IP IP地址概念与应用
  • 手把手教你写一个极简版Netty
  • Tkinter的Checkbutton控件
  • 汇编语言学习 下
  • 二叉树基础oj练习
  • fpga实操训练(系统开发和硬件接口)
  • 审批工作流—ccflow
  • ThreadLocal详解
  • Java大数值与浮点数计算
  • cmake 05 使用库
  • 浏览器使用本地硬盘上的JS文档
  • Python基础学习七
  • Java IO流之字符流详解
  • 二叉树专题汇总
  • 多个盒子排列规则(视觉格式化模型) 多个盒子的排列 页面布局
  • Linux下动静态库的打包与使用C C++
  • ubuntu 22.04学习笔记
  • 2023年网络安全比赛--中间件渗透测试中职组(超详细)
  • Python初学者看过来啊,老油条来复习
  • 单绞机控制算法模型(Simulink仿真)
  • 十二、创建和管理表
  • MySQL HA(High Availability) 数据库高可用工具Orchestrator安装
  • 通信原理简明教程 | 基本概念
  • 【头歌】单链表的排序操作
  • Mysql入门技能树-使用数据库
  • Java线程池
  • 恶意代码分析实战 1 静态分析基础技术
  • 恶意代码分析实战 7 WinDbg
  • Vue-Router详解
  • PHP 实例 - AJAX 实时搜索
  • 【MySQL】存储引擎
  • 《MLB美职棒大联盟》:年度最佳教练奖·棒球1号位
  • 19、Javaweb案例-登录功能
  • 【Git :分布式版本控制工具】
  • jvm面试题汇总
  • 电商项目之同一笔单多次收款成功
  • 零基础学JavaWeb开发(二十二)之 springmvc入门到精通(2)
  • Issues with peer dependencies found
  • CSS 艺术之心形-彩虹-加载动画
  • Python---自动生成二维码
  • Java集合常见面试题(四)
  • input 实现回车失焦,考虑输入法的情况
  • 高等数学【合集2】
  • 雅睿生物在创业板IPO终止:安信证券为保荐人,曾计划募资7.5亿元
  • 【操作系统】—— Windows常用快捷键(带你快速了解)
  • 基于Andriod的智慧校园卡系统的设计与实现
  • (18)go-micro微服务ELK介绍
  • OSG三维渲染引擎编程学习之二十八:“第三章:OSG场景组织” 之 “3.10 Switch开关节点”
  • 动态站点地图提交百度收录
  • 【价格型需求响应】基于Logistic函数的负荷转移率模型需求响应研究(Matlab代码实现)
  • javascript中Math.random()产生随机数进行随机点名
  • Hyperbolic geometry (双曲几何简介)
  • 【Leetcode每日一题】34.在排序数组中查找元素的第一个和最后一个位置|二分求下标
  • 【JavaEE】如何开始基础的Servlet编程(基于Tomcat服务器)
  • 【SpringCloud20】SpringCloud Alibaba Seata处理分布式事务
  • MODBUS总线的学习笔记
  • OSG三维渲染引擎编程学习之二十七:“第三章:OSG场景组织” 之 “3.9 AutoTransform自动对齐节点”
  • 最实用的 Docker 知识(一)
  • Leetcode:78. 子集、90. 子集 II(C++)
  • 1月23日Linux c编程之Makefile
  • UPS BP650CH实现nas自动关机
  • MySQL —— 库操作
  • ❤️如何实现所谓的“关键字传参”--理论+易懂版⭐
  • 【JavaEE】认识线程Thread类及常用方法线程状态
  • Shell语法
  • MP-2平面烟雾气体传感器介绍
  • springboot中restful风格请求的使用
  • 【19】C语言 | 三子棋
  • 【每日一题Day97】LC1828统计一个圆中点的数目 | 模拟
  • 议论文书写总结
  • Day869.索引(下) -MySQL实战
  • 离线召回与排序介绍
  • 【Ajax】防抖和节流
  • CMAKE
  • 【面试克星】【公式少代码少话多】Vins-Mono预积分相关知识点总结与概述
  • C语言基础知识(36)
  • Python实现一个简易的CLI翻译程序