当前位置: 首页>移动开发>正文

Python

Scrapy


Python,第1张
Python,第2张

环境要求

scrapy 使用2.5.1, scrapy-redis 使用0.7.2

pip uninstall scrapy    #卸载
pip install scrapy==2.5.1    # 安装指定版本

scrapy version # 提示2.5.1表示版本正确

降低OpenSSL版本

scrapy version --verbose   

pip uninstall cyptography
pip install cryptography==36.0.2

创建项目

scrapy startproject 项目名称  #创建项目

cd 项目名称
scrapy genspider 爬虫名字  网站域名   #生成spider

Hong-笔记

1. 创建爬虫项目
    和以前的python不一样, scrapy不能直接创建python文件, 需要在命令行内, 使用指令创建项目
    命令:
        scrapy startproject scrapy_baidu_091
    创建的项目需要注意:
        项目名字不允许使用数字开头, 不能包含中文

2, 创建爬虫文件
    注意:
        创建爬虫文件, 需要在spiders文件夹中去创建爬虫文件
    scrapy genspider 爬虫文件的名字 要爬取的网页
    进入到spider文件夹内, 然后cmd执行命令
    如: scrapy genspider baidu www.baidu.com
        一般不会写http, 直接写域名
    scrapy genspider tc https://bj.58.com/sou/?key=%E5%89%8D%E7%AB%AF%E5%BC%80%E5%8F%91&classpolicy=jianzhi_B

3, 运行爬虫代码
    scrapy crawl 爬虫的名字
    如: scrapy crawl baidu

项目介绍

Python,第3张
  • allowed_domains 数组,可以是多个网站, 逗号隔开, 用来屏蔽你爬取的网页上一些广告等功能
  • start_urls 爬虫的起始url, 也可以是多个, 逗号隔开

settings.py

  • USER_AGENT
    全局配置User-Agent, 以后的每一次请求, 都会带这个配置
USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 Edg/116.0.1938.76"
  • ROBOTSTXT_OBEY 关闭rebot协议
ROBOTSTXT_OBEY = False
  • CONCURRENT_REQUESTS
    并发请求数, 默认是异步的, 如果请求服务器过多, 会提示429, 请求过多, 这时可以调整CONCURRENT_REQUESTS的值, 一般不动
CONCURRENT_REQUESTS = 32
  • DOWNLOAD_DELAY 访问的延迟, 访问第一个请求之后, 访问第二个请求时, 停1s, 访问第三个请求时, 再停1s,访问第四个请求, 继续停1s....
DOWNLOAD_DELAY = 1

Flask Web框架

中文文档: 欢迎来到 Flask 的世界 — Flask 中文文档 (2.1.2) (dormousehole.readthedocs.io)

库安装到真实环境

pip install flask==2.2.3

Flask 基于Python的Web开发的"微"框架
Flask 依赖三个库
Jinja2 模版引擎{% %} 模版: 静态html+模版语言{% %}
Werkzeug WSGI工具集

Flask的框架流程:

Python,第4张

Python创建虚拟环境

#安装虚拟环境
pip install virtualenv virtualenvwrapper-win

#查看虚拟环境
workon

#创建新的虚拟环境
mkvirtualenv flask2env

#删除虚拟环境
rmvirtualenv flask2env

#进入虚拟环境
workon flask2env

第一个Flask项目创建

workon flask2env

#查看当前有那些库
pip list
#安装flask库
pip install flask==2.2.3

#查看自己安装的依赖包有那些
pip freeze
使用IDE创建Flask项目
Python,第5张

Python,第6张
第一次使用IDE创建Flask项目出现的问题:

1, 新创建的Flask项目, 启动提示: ImportError: cannot import name 'url_quote' from 'werkzeug.urls'
解决:
这个错误是因为你的Werkzeug库版本可能过高,而你的Flask项目使用的是旧的Werkzeug API

pip install Werkzeug==0.16.1

2, 之后又出现了新错误
TypeError: LocalProxy.init() got an unexpected keyword argument 'unbound_message'
解决:
这个错误可能是由于你的 Flask 版本与 Werkzeug 版本不兼容导致的。在 Flask 2.0.0 版本中,移除了对 unbound_message 参数的使用,但在旧版本的 Flask 中,这个参数可能仍在使用。

pip install --upgrade Flask

解决Pycharm启动后, 端口IP修改无效问题

第一种方式:


Python,第7张

第二种方式:


Python,第8张

Python,第9张

Flask - route路由

路由参数
路由:
  将从客户端发送过来的请求分发到指定的函数上

路由通过装饰器对应视图函数, 并且可以接受参数, 多以我们只需要在视图函数上使用装饰器即可

语法
  #基础路由
  @app.route("rule")
  def hello():
      return "Hello"
  
  #传参路由
  @app.route("rule/<id>")
  def hello(id):
      return "Hello %s" % id

写法
      <converter:variable_name>
      convert: 参数类型
                    string 接受任何没有斜杠"/"的文件(默认)
                    int  整形
                    float 浮点形
                    path  接受路径, 可接收斜线"/"
                    uuid  只接受UUID字符串, 唯一码, 一种生成规则
                    any   可以同时指定多种路径, 进行绑定

请求方式
        默认支持GET, HEAD, OPTIONS, 如果想支持某一请求方式, 需手动添加
    @app.route("/rule", methods=['GET','POST'])
      def hello():
              return 'hello'
    method可以指定的方法有:
                            GET, POST,HEAD,PUT,DELETE

Flask里的全局对象 --- Request

服务器再接受到客户端请求后, 会自动创建Request对象
由Flask框架创建, Request对象不可修改
属性
url 完整请求地址
base_url 去掉Get参数的url
host_url 只有主机和端口号的url
path 路由中的路径
method 请求方法
remote_addr 请求的客户端地址
args Get请求参数
form POST请求参数
files 文件上传
headers 请求头
cookies 请求中的cookies
user_agent 用户代理, 包括浏览器和操作系统信息

ImmutableMultiDict(类字典对象)类型:
类似字典的数据结构,与字典的区别,可以存在相同的键, 类字典对象特点就是: 允许有重复的key
args和form都是ImmutableMultiDict的对象
ImmutableMultiDict中数据获取方式:
dict['uname"] 或 dict.get('uname')
获取指定key对应的所有值:
dict.getlist("uname")

args 和from的区别

args:
- get请求参数的包装, args是一个ImmutableMultiDict对象, 类字典结构对象
- 数据存储也是key-value
- 外层是列表, 列表的元素是元祖, 元祖中左边是key, 右边是value
form:
- 存储结构跟args一致
- 默认是接收post参数
- 还可以接收PUT, PATCH参数

from flask import Blueprint,request


@blue.route('/request/',methods=['GET','POST'])
def get_request():
    pass
    print(request.method) # 获取Flask框架中的request对象, 注意需要先import
    '''
    这个request是ImmutableMultiDict类字典对象, 特点是允许有多个重复的key
    '''
    print(request.args)
    print(request.args['name'],request.args['age'])# 如果没有这个key, 会报错!
    print(request.args.get('name')) #即使没有这个key也不会报错
    print(request.args.getlist('name'))#如果有多个name的key, 应该用 getlist, 不然只会返回一个值
    return 'hello'

Flask里的全局对象 --- Response

Response: 服务器返回给客户端的数据
1, 直接返回字符串, 可以返回文本内容, 状态码
2, render_template 渲染模版, 将模版转换成字符串
3, 返回json
4, 自定义响应对象
4.1 使用make_response(data,code)
- data 返回的数据内容
- code 状态码
4.2 使用Response对象

重定向
redirect("http:www.baidu.com")
redirect("/getreponse")


@blue.route('/response/',methods=['POST'])
def get_response():
    pass

    return 'response ok'  #返回字符串
    return render_template('index.html',name="张三",age="历史") #模版渲染并传参给模版引擎
    data = {'name':'张三','age':'李四'}
    return data  #返回json数据
    return jsonify(data)  #返回序列化json数据

    #返回自定义的response对象
    html = render_template('index.html',name="张三",age="历史")
    print(html,type(html))
    res = make_response(html,200)
    return res

    #不使用make_response方法, 自定义response对象
    res = Response(html)
    return res



Cookies的作用
Python,第10张

Flask里的全局对象 --- Session

Session:
服务器端会话技术, 依赖于cookies
特点:
    - 服务端的会话技术
    - 所有数据都存储在服务器中
    - 默认存储在内存中
    - 存储结构也是key-value形势, 键值对
    - session是离不开cookies的

Flask中的session是全局对象, 类似于之前的request对象

常用操作:
     设置session
        session['key'] ='value'
     获取session
        session.get(key,default=None) 根据建获取获取值
      删除session
          session.pop(key)  删除某一个值
          session.clear()  清楚所有

cookies和session的区别:
cookies: 
    1, 在浏览器中存储
    2, 安全性较低
    3, 可以减轻服务器的压力

session:
    1, 在服务器存储
    2, 安全性高
    3, 对服务器要求高
    4, 依赖cookies

模型相关包安装

#安装flask-sqlalchemy (用于ORM) 
pip install flask-sqlalchemy -i https://pypi.douban.com/simple

#安装flask-migrate(用于数据迁移)
pip install flask-migrate  -i https://pypi.douban.com/simple

#安装pymysql (Mysql驱动)
pip install pymysql  -i https://pypi.douban.com/simple

Flask的ORM

Flask 使用Python自带的ORM: SQLAlchemy
针对于Flask的支持, 安装插件 flask-sqlalchemy
pip install flask-sqlalchemy

连接SQLite
SQLite连接的URI:
      DB_URI = sqlite:////sqlite3.db

连接Mysql
USERNAME='root'
PASSWORD='root'
HOSTNAME='localhost'
PORT='3306'
DATABASE='db'

格式:
mysql+pymysql://USERNAME:PASSWORD@HOSTNAME:PORT/DATABASE

配置URL
DB_URI = 'mysql+pymysql://{}:{}@{}:{}/{}'.format(
      USERNAME,PASSWORD,HOSTNAME,PORT,DATABASE
)

在Flask里使用ORM
链接数据需要指定配置:
  app.config['SQLALCHEMY_DATABASE_URI'] = DB_URI   #配置连接数据库的路径
app.config['SQLALCHEMY_TRACK_MODIFICATIONS']=False  #禁止对象追踪修改

SQLite数据库连接不需要额外驱动, 也不需要用户名和密码

#再Flask项目中的使用
db = SQLAlchemy()
db.init_app(app)

创建模型

class Person(db.Model):
    __tablename__='person'
    id = db.Column(db.Integer,primary_key=True)
    name = db.Column(db.String(16),unique=True)

#模型Model: 就是一个类
#必须继承db.Model, 才是一个模型类, 不然就是一个普通的类
class User(db.Model):
    #表名
    __tablename__='tb_user'
    #定义表字段
    id = db.Column(db.Integer, primary_key=True,autoincrement=True)
    name = db.Column(db.String(30), unique=True,index=True)
    age = db.Column(db.Integer,default=1)
    sex = db.Column(db.Boolean,default=True)



'''
db.Column: 字段
db.Integer: 整数
primary_key=True 主键
autoincrement=True 自动递增
db.String(30)  varchar(30) 可变字符串
unique=True 唯一约束
index=True  普通索引
'''


字段类型
      Integer
      Float
      String

常用约束:
      primary_key
    autoincrement
    unique
    default
代码控制数据库简单操作
代码控制数据库简单操作:
    创建数据库,表
      db.create_all()
  删除表:
      db.drop_all()
  在事务中处理, 数据插入
      db.session.add(object)
      db.session.commit()
   获取所有数据
      Person.query.all()

数据迁移

安装
      pip install flask-migrate
初始化
    使用app和db进行migrate对象初始化
        from flask_migrate import Migrate
        migrate = Migrate()
        migrate.init_app(app=app,db=db)

数据迁移命令:
    再cm或Terminal先进入到项目目录:
    然后输入命令:
          flask db init   创建迁移文件夹migrates, 只调用一次
           flask db migrate  生成迁移文件
           flask db upgrade  执行迁移文件的升级
          flask db downgrade 执行迁移文件的降级


模型相关实例查看demo8

数据迁移的详细步骤:
1, 安装好数据迁移的包  flask-sqlalchemy和flask-migrate
2, 在exts.py中初始化Migrate和SQLAlchemy
3, 在models中定义好模型
4, 在views.py中一定要导入models模块
       from .models import *
5, 配置好数据库(sqlite或者mysql)
6, 执行数据迁移命令:
    a, 在cmd或者Terminal进入项目目录(app.py所在目录)
    b, 然后输入命令:
            flask db init  创建迁移文件夹migrates, 只调用一次
            flask db migrate  生成迁移文件
            flask db upgrade  执行迁移文件中的升级
            flask db downgrade  执行迁移文件中的降级
7, 使用Navicat查看数据库内容


对数据库的操作

.exts.py

第三方的插件都在这里, 比如连接数据库, 或者数据迁移的插件

from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate

db = SQLAlchemy()
migrate = Migrate()

def init_exts(app):
    db.init_app(app=app)
    migrate.init_app(app=app,db=db)



models.py

对数据库的定义都在models.py

from .exts import db

#类 --> 表
# 类属性 --> 表字段
# 对象 --> 表里的一条数据

class User(db.Model):
    __tablename__='tb_user'
    id = db.Column(db.Integer, primary_key=True,autoincrement=True)
    name = db.Column(db.String(30), unique=True,index=True)
    age = db.Column(db.Integer,default=1)


views.py

操作数据库

#一定要导入model, 不然model.py不会执行
from . models import *


#表操作
#数据的操作在这里, 表结构的更改, 在models.py里, 然后进行数据迁移

#增: 添加数据
@blue.route('/useradd/')
def user_add():
    #添加单条数据
    u = User()
    u.name = 'ikun'
    u.age = 24
    # db.session.add(u);  #将u对象添加到session中
    # db.session.commit(); #同步到数据库中



    #添加多条数据
    users = [];
    for i in range(10,30):
        u = User();
        u.name = '蔡徐坤' + str(i)
        u.age = i;
        users.append(u)

    try:
        db.session.add_all(users)
        db.session.commit(); #事务提交
    except Exception as e:
        db.session.rollback()  #回滚
        db.session.flush()  #清空缓存
        return "批量添加数据失败" + str(e);
    return "批量添加数据成功";

@blue.route('/userdel/')
def user_del():
    u = User.query.first();#查询第一条数据
    db.session.delete(u)
    db.session.commit();

    return '删除成功'

@blue.route('/userupdate/')
def user_update():
    u = User.query.first();#查询第一条数据
    u.name = '蔡徐坤-修改'
    u.age = 1000
    #直接修改, 提交就行了
    db.session.commit();

    return '修改成功'


补充

查询数据
    过滤器
        filter()   把过滤器添加到原查询上, 返回一个新查询
        filter_by() 把等值过滤器添加到原查询上, 返回一个新查询
        
        limit() 使用指定的值限制原查询返回的结果数量, 返回一个新查询
         offset()  偏移原查询返回的结果, 返回一个新查询
         order_by()  根据指定条件对原查询结果进行排序, 返回一个新查询
         group_by()  根据指定条件对原查询结果进行分组, 返回一个新查询

    常用查询
          all()  以列表形式返回查询的所有结构, 返回列表
          first() 返回查询的第一个结构, 如果没有结果, 则返回None
          first_or_404()  返回查询的第一个结果, 如果没有, 则终止请求, 返回404错误响应
          get()   返回指定主键对应的行, 如果没有对应的行, 则返回None
          get_or_404()   返回指定主键对应的行, 如果没有找到指定的主键, 则终止请求,返回404错误响应
          count()  返回查询结果的数量
          paginate()  返回一个Paginate对象, 它包含指定范围内的结果

          查询属性
                  contains
                  startswith
                  endswith
                  in_
                  __gt__
                  __ge__
                  __lt__
                  __le__
          逻辑运算
                   与  and_
                         filter(and_(条件),条件...)
                    或 or_
                         filter(or_(条件),条件...)
                   非  not_
                         filter(not_(条件),条件...)

实例:
  查询:
     persons = Person.query.all()# 获取所有
     persons = Person.query.filter(Person.age>22)

     # filter功能比filter_by强大
      persons = Person.query.filter(Person,age==22) # filter(类,属性==值)
       persons = Person.query.filter_by(age=22) # filter_by(属性=值)

       persons = Person.query.filter(Person.age.__lt__(22)) #<
       persons = Person.query.filter(Person.age.__le__(22)) # <=
       persons = Person.query.filter(Person.age.__gt__(22)) # >
       persons = Person.query.filter(Person.age.__ge__(22)) # >=

       persons = Person.query.filter(Person.age.startswith('宝')) # 开头匹 
       persons = Person.query.filter(Person.age.endswith('宝')) # 结尾匹配 
       persons = Person.query.filter(Person.age.contains('宝')) # 包含 
       persons = Person.query.filter(Person.age.in_([11,12,22])) # in_

       persons = Person.query.filter(Person.age>=20,Person.age<30) # and
       persons = Person.query.filter(and_(Person.age>=20, Person.age<30)) # and_
        persons = Person.query.filter(or_(Person.age>=30, Person.age<20)) # or
        persons = Person.query.filter(not_(Person.age<30)) # not_

   排序:
        persons = Person.query.order_by('age') # 升序 
        persons = Person.query.order_by(desc('age')) # 降序
   分页:
        persons = Person.query.limit(5) #取前5个
        persons = Person,query.offset(5) #跳过前5个
       
      # 获取页码page和每页数量num
       page = int(request.args.get('page'))
       per_page = int(request.args.get('per_page'))

       # 手动做分页
       persons = Person.query.offset((page-1)  * per_page).limit(per_page)
 
       # 使用paginate做分页
       persons = Person.query.paginate(page=page,per_page=per_page,error_out=False).items

    paginate对象的属性:
        items:返回当前页的内容列表
        has_next:是否还有下一页
        has_prev: 是否还有上一页
        next(error_out=False): 返回下一页的Pagination对象
        prev(error_out=False): 返回上一页的Pagination对象
        page: 当前页的页码(从1开始)
        pages: 总页数
        per_page: 每页显示的数量
        prev_num: 上一页页码数
        next_num: 下一页页码数
        query: 返回创建该Pagination对象的查询对象
        total: 查询返回的记录总数
实例:
普通sql查询, 参考项目10
#查询
@blue.route('/userget/')
def user_get():
    #all()  返回所有的数据, 列表形式
    users = User.query.all()
    print(users)
    print(list(users)) #转换成列表形式
    #User.query是一条sql语句, 类型是<class 'flask_sqlalchemy.query.Query'>一个查询对象
    print(User.query,type(User.query))

    print('----------------------')
    #filter(): 过滤, 得到查询集, 类似SQL中的where, 与get()不一样, get()得到的是数据, filter()得到的是数据集
    users = User.query.filter()
    print(users,type(users))
    # users.filter(); #可以继续filter查询

    print('----------------------')
    #get()  查询对应主键的数据对象
    user = User.query.get(12);
    # user = User.query.get_or_404(12);
    print(user,type(user)) #返回User对象 <class 'App.models.User'>

    '''
    filter()   类似SQL中的where
    filter_by()  用于等值操作的过滤
    '''
    print('----------------------')
    users = User.query.filter(User.age==20)
    print(users)
    print(list(users))
    #使用filter_by
    users = User.query.filter_by(age=20)
    # users = User.query.filter_by(age>20)  #不能使用范围的, 只能使用等值的, 非等值的使用filter()
    print(list(users))

    print('----------------------')
    #first()   第一条数据
    #last()  最后一条数据
    user = User.query.first()
    # user = User.query.filter_by(age = 8888).first_or_404()  #第一条数据不存在, 抛出404错误

    print('----------------------')
    users = User.query.filter();
    print(users.count())

    print('----------------------')
    #limit(): 前几条
    #offset(): 跳过前几条
    users = User.query.offset(3).limit(4); #跳过前三条, 取之后的第四条数据
    print(list(users))

    print('----------------------')
    users = User.query.order_by('age') #升序
    print(list(users))
    #降序 需要导包
    from sqlalchemy import desc
    users = User.query.order_by(desc('age'))
    print(list(users))

    print('----------------------')
    #逻辑运算, and_, or_, not_(取反)
    users = User.query.filter(User.age>20, User.age<25) #年龄20 - 25
    #使用前 导包
    from sqlalchemy import and_,or_,not_
    users = User.query.filter(and_(User.age>20,User.age<25))
    users = User.query.filter(or_(User.age>25,User.age<20))
    users = User.query.filter(not_(or_(User.age>25,User.age<20)))
    users = User.query.filter(not_(User.age>25))
    print(list(users))

    print('----------------------')
    #查询属性
    #contain('')  模糊查找sql的like
    users = User.query.filter(User.name.contains('蔡'))
    print(list(users))
    #in_
    users = User.query.filter(User.age.in_( [10,20,30,40,50,60] ))
    print(list(users))

    print('----------------------')
    #startswith()
    users = User.query.filter(User.name.startswith( ['蔡'] ))
    print(list(users))
    users = User.query.filter(User.name.endswith( ['坤']))
    print(list(users))

    print('----------------------')
    #__gt__: 大于
    #__ge__: 大于等于
    users = User.query.filter(User.age.__gt__(20))
    print('大于20的:',list(users))

    return 'success'




分页:参考项目10

1, 手动翻页
offset().limit()
数据, 1,2,3,4,5....
页码: page = 1
每页数量: per_page=5
1-5 offset().limit(5)
6-10 offset(5).limit(5)
11-15 offset(10).limit(5)
16-20 offset(15).limit(5)
...
page=n offset( (page-1) * per_page).limit(per_page)

2, paginate对象

@blue.route('/paginate/')
def get_paginate():
    #页码, 默认显示第一页
    page = request.args.get('page',1)
    #per_page, 每页显示的数据
    per_page = request.args.get('per_page',5);
    print(page,type(page))
    print(per_page,type(per_page))# 5 <class 'int'>

    page = int(page)
    per_page = int(per_page)

    #paginate()
    p = User.query.paginate(page=page, per_page=per_page,error_out=False)
    '''
    返回的paginate对象属性
        paginate对象的属性:
        items:返回当前页的内容列表
        has_next:是否还有下一页
        has_prev: 是否还有上一页
        next(error_out=False): 返回下一页的Pagination对象
        prev(error_out=False): 返回上一页的Pagination对象
        page: 当前页的页码(从1开始)
        pages: 总页数
        per_page: 每页显示的数量
        prev_num: 上一页页码数
        next_num: 下一页页码数
        query: 返回创建该Pagination对象的查询对象   没有这个属性了
        total: 查询返回的记录总数
    '''
    print(p.items)
    print(p.has_next)
    print(p.has_prev)
    print(p.next(error_out=False).items);
    print(p.prev(error_out=False).items);

    print(p.page)#返回当前的页码
    print(p.pages)
    print(p.per_page)
    print(p.prev_num)
    print(p.next_num)

    print('-------------------')
    # print(p.query)  #没有这个属性了
    print(p.total)
    return render_template('book_index.html',p=p)

Flask 进阶

什么是钩子(中间件Middleware)
钩子或叫钩子函数,是指在执行函数和目标函数之间挂载的函数,框架开发者给调用方提供一个point-挂载点是一种AOP切面编程思想
常用的钩子函数
before_first_request:处理第一次请求之前执行
before_request:在每次请求之前执行,通常使用这个钩子函数预处理一些变量,实现反爬等after_request:涟册一个函数,如果没有未处理的异常抛出,在每次请求之后运行teardown_appcontext: 当APP上下文被移除之后执行的函数,可以进行数据库的提交或者回滚

类似于拦截器, 在架构的各个模块请求中间, 多加了一个方法, 进行拦截, 方便开发人员处理


Python,第11张

Flask内置对象

g:
    global全局对象
    g对象是专门用来保存用户的数据的
    g对象在一次请求中的所有的代码的地方,都是可以使用的突破变量存储位置限制,为数据传递添加了新的方式,比如我们在before_request产生一个数据在后面需要使用,可以保存在g对象中,在其他视图函数中就可以使用这个数据

request:
    请求对象,可以获取客户端提交过来的所有请求信息

session:
    会话技术,服务端会话技术的接口

current app:
    app的配置信息,app对象获取,current app
    使用获取当前app需要注意,一定要在程序初始化完成之后

修改外部目录的方式

如果想要修改templates模板目录或static静态目录,可以自己配置

 在settings.py文件中添加BASE DIR:
        import os
        BASE DIR = os.path.dirname(os.path,dirname(os.path.abspath( file_)))

在__init__.py文件中添加static路径和templates路径:
        static_path = os.path.join(settings.BASE DIR,'static'
        template_path = os.path.join(settings.BASE DIR,'templates')
        app = Flask(_name , static_folder=static_path,template folder=template path)

在views.py文件中访问模板:
        @blue.route('/hello/')
        def hello():
                return render template('hello.html')

在模板中使用静态资源:
        <link rel="stylesheet" href="[[ url for('static', filename='css/hello.css') ])">

Flask-RestFul请求

fields进行定义
marshal with进行使用
        特性
                显示我们设计的数据结构
                默认返回的数据如果在预定义结构中不存在,数据会被自动过滤
                如果返回的数据在预定义的结构中存在,数据会正常返回
                如果返回的数据比预定义结构中的字段少,预定义的字段会呈现一个默认值


定义字段输出
        使用字典进行定义
        常用都是基本类型:string,Integer
                #格式化字段
                user fields = {
                        'msg': fields.String,
                        'status': fields.Integer,
                        'data': fields.String(attribute='private_data'),
                        'default_data' : fields.String(default='1')
                }
         定义好的格式通过装饰器进行使用
                @marshal with(需要返回的数据格式), return返回字典就ok了



卸载Centos7的python

yum remove python
试了试不管用 不过python2和3可以共存, 就没管

安装python 3.11.5

#下载python源码 ,可以用get, 也可以离线下载, 网址如下
#准备需要的依赖
yum install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel libffi-devel

上述这些linux基础依赖, 必须都安装好,不然会出现很多问题, 比如下载不下来pip依赖, 启动时候提示缺少类库之类的问题

离线安装Linux yum类库

如果需要离线安装yum的类库, 可以尝试如下方式

#从有网络的本地电脑下载
yum install --downloadonly --downloaddir=./下载文件夹名称 zlib-devel bzip2-devel 
openssl-devel ncurses-devel  epel-release gcc gcc-c++ 
#拷贝到离线服务器上安装
rpm -Uvh ./*.rpm --nodeps --force
#验证某些依赖是否安装成功
 rpm -qa|grep 软件包名
-------------------------------------------------------------------
#准备好openssl, 否则pip无法下载依赖, 用国内镜像也不行
wget https://www.openssl.org/source/openssl-1.1.1n.tar.gz --no-check-certificate 下载openssl1.1.1
tar -zxf openssl-1.1.1n.tar.gz 解压
cd openssl-1.1.1n
./Configure --prefix=/usr/local/openssl 设置安装目录 可以自定义 但是要记住,后面会用到
make -j && make install 编译并安装
--------------------------------------------------------------------
wget https://www.python.org/ftp/python/3.11.5/Python-3.11.5.tgz
tar -xvf Python-3.11.5.tgz
cd Python-3.11.5
#注意路径对应, openssl的路径是上边安装的路径
./configure --prefix=/data/python/install  --with-openssl=/usr/local/openssl --with-openssl-rpath=auto
#注意不要有 prefix不要有空格
make && make install
--------------------------------------------------------
#这时候就安装完了, 创建软连接
ln -s /data/python/install/bin/python3 /usr/bin/python3
ln -s /data/python/install/bin/pip3 /usr/bin/pip3

发布Flask项目

    1. 到本地项目上, 生成需要的依赖
pip3 freeze >requirements.txt
    1. 上传项目到服务器
    1. 安装虚拟环境
# 安装虚拟环境
pip3 install virtualenv
pip3 install virtualenv -i https://mirrors.aliyun.com/pypi/simple/
# 创建虚拟环境 ENV
#可能执行这个失败, 找到安装的路径, 创建软连接即可
cd  /data/python/install/bin/
ln -s  /data/python/install/bin/virtualenv  /usr/bin/virtualenv 
cd /data/work/env/
virtualenv ai
virtualenv ENV
# 切换到虚拟环境所在的目录
cd ENV
# 启用虚拟环境
source ./bin/activate
# 安装依赖清单里的库
pip3 install -r requirements.txt
# 列出当前虚拟环境所安装的依赖库
pip3 list
    1. 启动Flask 应用
python3 start.py

将python服务, 设置为系统自启动

# 这样的命令在ssh终端退出后,python进程也会被杀掉
python xxx.py &
#创建系统服务
vim /usr/lib/systemd/system/robot.service

rebot.service内容如下
ExecStart为服务启动时执行的命令,不能用相对路径, 一定要全路径。
这里也可以将命令写到任意的.sh文件中,这里写.sh文件的全路径也是可以的。

[Unit]
Description=robot
After=network.target
[Service]
Type=forking
ExecStart=/usr/local/python3/bin/ENV/bin/python /usr/local/python3/bin/ENV/p3.py &
PrivateTmp=true
[Install]
WantedBy=multi-user.target

启动服务

systemctl enable robot
systemctl start robot

https://www.xamrdz.com/mobile/45c1994361.html

相关文章: