• 巨蟒python全栈开发flask9 项目开始1


    1.项目需求分析

    立项:Javis&&taisen(三个月全部,先模拟出一个玩具,硬件需要周期长一些)

    想法 --- 需求分析:
        1.通过玩具与孩子实时进行沟通
        2.希望玩具的知识渊博
        3.希望玩具最好能代替我陪伴孩子
        4.给孩子播放幼教内容 儿歌 睡前故事 国学 
        5.自扩散 - 幼儿社交圈    
    
    需求分析:
        4.给孩子播放幼教内容 儿歌 睡前故事 国学 
        - 数据采集(爬虫)
        - 获取本地资源
        - 家长可以控制玩具播放的内容
            - 控制端 App
        2019年4月19日:
            1.喜马拉雅听 采集数据
            2.存放数据目录结构
            3.数据存放在MongoDB中
            4.在App中展示资源:
                通过/content_list接口获取资源
            
            5.播放幼教内容在App端播放
                plus.audio.createPlayer(URL_PATH).play()
            
            6.家长可以控制玩具播放的内容
                
    
        
        1.通过玩具与孩子实时进行沟通
        - 对玩具发起消息 
            - 手机 App
        - 基于通讯录的IM功能 IM:即时通讯
            - WebSocket
        
        2.希望玩具的知识渊博
        - 问题库 百科
            - 问答机器人 Tuling
        
        3.希望玩具最好能代替我陪伴孩子
        - 聊天库
            - 问答机器人 Tuling
            
        5.自扩散 - 幼儿社交圈
        - 玩具与玩具之间对话
        - 玩具需要具有通讯录的功能
            - 基于通讯录的IM功能 IM:即时通讯
                - WebSocket
        
        App的功能?
        1.用户管理
            - 注册登录
            - 用户信息
                - 通讯录
                - 绑定玩具
                
        2.管理玩具
            - 绑定玩具
            - 控制玩具通讯录
            - 帮助玩具建立社交圈
            
        3.内容审核
            - App看到内容
            - App听内容
            - App给玩具发过去 - 遥控器(只要有网就行)
            
        4.与玩具通讯功能 - App通讯录
            - App聊天界面
            - 语音消息发送
                - 录音
                - 播放录音
        
        玩具的功能?由于玩具硬件开发周期非常长,自己模拟WebToy玩具
        1.播放幼教内容
            - 点播 语音指令
            - 遥控 App发送音乐给玩具 {music:"小毛驴.mp3"}
            - WebToy - audio
            
        2.播放语音消息 - 通讯
            - 收取消息 实时
                - WebSocket
            - WebToy - audio 
    
        3.发送语音消息
            - 录音
            - 发送?
            - App
            - 玩具
            - 问答机器人
            
        4.语音指令
            - 录音
            - 上传
            - NLP 自然语言处理
            - 我要听
            - 发消息给xxxx

    注意:没有谁一看到项目,马上就有思路了,都是一步一步来的,不要慌,一点一点来

    2.数据采集 xmly

    首先,我们需要采集数据,存在法律风险,需要带上出处和作者这个东西,否则很可能出现赔偿问题

    音频可能没有太大影响,但是视频是视觉上的,就存在风险了

    起名字无所谓的.

    yinwangba//12//eightapp//13king//14tuxingsun//15chunsheng//16laopobing//17vista//18javis

     

    创建完后端,需要在前端同步开发

    在前端中,新建一个app

    清除原来的内容,写一个md代码块,进行得到下面的内容:

    我们想要采集的内容爬爬内容:"幼教类网站"=>"幼教网"

    上边的名词难度有点高

    亲宝网,"贝瓦儿歌"

     "喜马拉雅"

    不入虎穴焉得虎子,舍不得孩子套不着狼(鞋子)

    动态class是最难爬取的

    请求头里边有请求地址

    上边显示请求的URL和请求的方式GET

    上边显示的是响应应用类型:

    下图显示的是普通请求方式:

    用户代理,在请求头里边:见下图

    我们需要用get请求进行访问,

     得到下面的结果,响应的是200,也就是可以响应

     在打印一下里边的内容,结果是空的

    反爬请求方式1:校验当前的用户是否为浏览器访问

    下面,我们开始模拟一下:

    这个时候,我们爬取的内容,见上图

    反爬的机制1就是"动态class"随时可能变化

     下面我们通过json,变成字典:

    rest是一种开发方式,一种标准:类似于下图的一种标准的格式

    下面,我们需要通过for循环,拿取里边的内容:也就是先拿名字:

     下面我们除了需要名字,还需要播放的链接地址:

    我们需要存储起来,防止网址变更.

     我们下面,验证的结果就是流:

    也就是不需要请求头的.

    下面我们需要开始写入某个内容:
    运行之后的到的结果:

    右击,打开文件的位置:

    不要以为别人好像很简单做成了某件事情,别人可能花了你所不知道的更多的时间,进行处理这个问题.

     有可能链接可能变了

    上边写的方式是单线程的,但是会慢一些,但是无所谓了,现在能用就行.

    下面新建两个文件夹:一个存图片,一个存音乐

    我们再见一个settings.py进行数据库的配置,优选mongodb,简单粗暴

     最终版程序:

    papaxiao.py

    # Author: studybrother sun
    import os
    import time
    import requests
    from uuid import uuid4
    from settings import MONGODB,MUSIC_PATH,COVER_PATH
    xmly_url="https://www.ximalaya.com/revision/play/album?albumId=424529&pageNum=1&sort=1&pageSize=30"
    # 424529指的是专题ID
    header={
        "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36"
    }
    def papaxiao(tar):
        res = requests.get(xmly_url, headers=header)
        music_list=[]# 新建一个空列表music的
        for audio_info in res.json().get("data").get("tracksAudioPlay"):
            print(audio_info.get("trackName"), audio_info.get("src"))
            music = requests.get(audio_info.get("src"))  # 音乐
            cover = requests.get("http:" + audio_info.get("trackCoverPath"))  # 图片
            filename = uuid4()  # 保证每个名字都不一样
    
            cover_file = os.path.join(COVER_PATH, f"{filename}.jpg")  # 拼接路径
            music_file = os.path.join(MUSIC_PATH, f"{filename}.mp3")  # 拼接路径
    
            with open(music_file, "wb")as f:
                f.write(music.content)
            with open(cover_file, "wb")as f:
                f.write(cover.content)
            music_info = {
                "music": f"{filename}.mp3",
                "cover": f"{filename}.jpg",
                "title": audio_info.get("trackName"),  # 展示的内容
                "ZJ": audio_info.get("albumName"),  # 专辑名字需要拿出来,防止被告
                "class": tar
                # "class": "儿歌分类"
            }
            music_list.append(music_info) #
            time.sleep(0.12)#防止无限爬取,我们需要防止屏蔽
        # 将music_info插入数据库,30次
        MONGODB.content.insert_many(music_list)
    papaxiao("儿歌")

    settings.py

    # Author: studybrother sun
    from pymongo import MongoClient
    mc=MongoClient("127.0.0.1",27017)
    MONGODB=mc["Taisen_J"]
    
    #目录配置
    MUSIC_PATH="Music"
    COVER_PATH="Cover"

    目录结构:

    还有,我们需要开启mongodb

    最终得到的结果:

    注意,反爬机制会很全面的,特别是这种大的网站

    播放次数.点播次数&&推荐次数,这种算法.

    我们采集完内容,我们应该怎样操作?

    3.App内容列表&&App播放歌曲

     

    我们需要将数据库,里边的内容,变成列表返回这些内容:

    我们需要写一个视图函数进行返回,

    新建一个manager.py和一个文件夹,serv

    主要用C#的一种架构方式写的:

    下面我们再写一个content内容蓝图

    只支持"POST"的方式,是复写而不是追加,原因是源码中进行了覆盖methods

    面对一个美丽的前端小姐姐,我们该如何处理?

    我们需要,在前端中导入上边的内容,

    # Author: studybrother sun
    from flask import Blueprint,jsonify
    from settings import MONGODB,RET
    
    content=Blueprint("content",__name__)
    @content.route("/content_list",methods=["POST"])
    def content_list():  #写一个视图函数,在上边导入mongodb
        res=list(MONGODB.content.find())     #这是一个生成器,需要转换成一个列表
        for index,con in enumerate(res):
            res[index]["_id"]=str(con.get("_id"))   # 需要修改格式和_id
    
        RET["code"]=0
        RET["msg"]="查询内容列表"
        RET["data"]=res
    
        return jsonify(RET)

    我们写了揽入需要在manager.py里边先注册一下:

    下面,我们需要在Hbuilder前端里边写一个内容,开始拿我们的请求内容:

     清空前端index.html里边的内容,然后md代码块,

    先运行项目:Hbuilder,这个时候我们可以得到一个干净的项目,也就是什么都没有

    注意,建立连接的过程会比较慢,这很正常,多长时间几次就可以连接上了

    再加上mat代码块,底部多了一个

    然后输入代码块在body里边:

    新建一个home.html页面,清空改成md

    再在home里边加上mhe

    先写一个mbo,再在里边写一个msl轮播图

    再写一个mg九宫格

    我们再写一个mlis代码块,选择第三个

    这个时候,我们需要在index.html里边的初始化进行修改

    先删除上边的第30行,

     

    这个时候,我们再进行保存处理

    再次得到下面熟悉的界面:

    但是标题已经发生了改变,我们自己起的名字"泰森_贾"

    将后边的数字,都改成4,就变成了九宫格

    也就是说一共屏幕上有12个格,每个占4个,就显示3个标签

    下面,我们需要对"幸福","木屋","CBD"等进行替换成歌曲

    也就是说,我们加载完home页面之后,需要对服务器发起一个请求,

     写一个mpl

    下面,我们发起一个post请求

     

    注意,这个后端,需要开启后端的服务,

    现在,前端,我们保存一次就会运行一次.

     我们想将li包裹的里边的东西进行处理:

    也就是说,我们要将下图中红框的位置删除:

    代码,见下图:

    很明显,我们这样操作会出错,显示下图中的语法错误:

    接下来,我们应该如何操作?
    下面,我们要创建标签,

     

    这个时候可以把上边的结构表删除了

    也就是下图中,红框的内容:

    我们需要执行的位置,见下图:

    上图是执行的位置,我们可以判断的是,这个js不是按照从上到下执行的

    写代码块fori,得到下图的内容

    我们将Things修改成data.data,也就是数据的长度

     我们先运行起后端程序manager.py,在保存也就是运行home.html,得到下面的结果:

    我们再处理下面的内容:

    注意,要把内容,写对,内容可能会出来的慢一些,不要着急

     

    修改p标签为ZJ

    上边表示可以加载出歌名来.

    保存也就是运行,得到下面的结果:

    思考,可不可以直接那里边的图片:也就是

    img.src=content.cover;

    访问的结果,我们需要的是一个流,进行处理

    下面我们需要再创建一个接口进行处理:

    下面,我们需要注册一个蓝图,进行处理,

    保存上图的内容,这个时候,应该可以加载出图片了.

     

    这个地方爬虫写错了一个字母,导致后边出现的歌名全部一样:

    就是因为爬虫中写错了一个字母,导致了这个音乐列表中的名字和图片都出现的不正确,现在上边就显示正常了

    下面,我们想要播放列表中的音乐,我们该如何处理?

    点击事件,我们想要,点击a标签就可以播放音乐

    下面,我们再创建一个player页面:

    在清空,写入代码块:md

    在body里边写mhe,选择带箭头的,原因是"这是一个子集"

     

    将title里边写上标题,

    下面我们再写一个mbo代码块,

    下面我们再在home.html里编写,打开页面,写mop代码块,打开页面

    我们需要将上图中的styles去掉,保存也就是运行:

    这个时候,机器可能的比较慢

    点击任意一首歌曲,都会跳转到player.html界面

    下面,我们还需要传递一个参数,进行处理.

    下面,我们将执行的参数进行传递:

    也就是传递到player.html,这个时候player.html就可以接收了

    这个时候,我们可以得到上边的内容,其中webview里边可以包含传递过来的参数content,也就是data.data

    这个时候再次保存,就可以,点击歌曲里边,可以看到结果了,但是这个时候,电脑可能会卡一下,注意一下

    这样就可以根据点击进去的歌名,显示标题的样式了

    下面,再写一个mro

    这个时候,我们想要再在下图写一个图片:

    下面,我们再加上一个id=cover

    因为是传递过来的,我们需要修改的位置,见下图:

    我们看到所占的页面是有点大的,下面处理一下:

    我们需要在这里改变大小,并且居中

    距离顶部一定的距离,改成圆形

    下面,我们再写一个按钮

    如何进行播放,这个时候,我们需要查一下文档,

    选择第二个Audio,也就是音频的录制和播放

    这个时候,我们需要在后端写一个getmusic

    注意,这个时候,我们不在需要注册了,注册的是实例化之后的蓝图,不是函数,记住这一点

    之所以,没有播放的原因是缺少一行代码

    这个时候,我们点击,就可以播放音乐了.

    后端的请求就拿到了MP3

    设置=>声音=>默认通知声音=>选择声音

    现在,我们想要音乐停止,怎么操作?

    4.Player用法

     下面,我们需要加上几个按钮,实现暂停,继续等功能

    mbu代码块功能,选择第一个

    下面我们开始绑定事件:

    dga代码块

    player 并且我们在plusReady里边赋值成了一个新的对象

     下面我们可以用了.

    下面,我们再上边再定义一个公共事件:

    也就是说我们再plusReady里边先设置好值.

    此时的播放是重建的对象,再次播放是从头开始进行播放的.

    上边出错的原因是加上了var

    下面,我们修改一下home里边九宫格所代表的东西:

     MUI自己学习这些功能:

     

    我们需要的是上拉下载:

    国学列表,古诗列表等等.

    5.Websocket遥控器

    需求分析:
        4.给孩子播放幼教内容 儿歌 睡前故事 国学 
        - 数据采集(爬虫)
        - 获取本地资源
        - 家长可以控制玩具播放的内容
            - 控制端 App
        2019年4月19日:
            1.喜马拉雅听 采集数据
            2.存放数据目录结构
            3.数据存放在MongoDB中
            4.在App中展示资源:
                通过/content_list接口获取资源
            
            5.播放幼教内容在App端播放
                plus.audio.createPlayer(URL_PATH).play()
            
            6.家长可以控制玩具播放的内容
                
    
        
        1.通过玩具与孩子实时进行沟通
        - 对玩具发起消息 
            - 手机 App
        - 基于通讯录的IM功能 IM:即时通讯
            - WebSocket
        
        2.希望玩具的知识渊博
        - 问题库 百科
            - 问答机器人 Tuling
        
        3.希望玩具最好能代替我陪伴孩子
        - 聊天库
            - 问答机器人 Tuling
            
        5.自扩散 - 幼儿社交圈
        - 玩具与玩具之间对话
        - 玩具需要具有通讯录的功能
            - 基于通讯录的IM功能 IM:即时通讯
                - WebSocket
        
        App的功能?
        1.用户管理
            - 注册登录
            - 用户信息
                - 通讯录
                - 绑定玩具
                
        2.管理玩具
            - 绑定玩具
            - 控制玩具通讯录
            - 帮助玩具建立社交圈
            
        3.内容审核
            - App看到内容
            - App听内容
            - App给玩具发过去 - 遥控器
            
        4.与玩具通讯功能 - App通讯录
            - App聊天界面
            - 语音消息发送
                - 录音
                - 播放录音
        
        玩具的功能?由于玩具硬件开发周期非常长,自己模拟WebToy玩具
        1.播放幼教内容
            - 点播 语音指令
            - 遥控 App发送音乐给玩具 {music:"小毛驴.mp3"}
            - WebToy - audio
            
        2.播放语音消息 - 通讯
            - 收取消息 实时
                - WebSocket
            - WebToy - audio 
    
        3.发送语音消息
            - 录音
            - 发送?
            - App
            - 玩具
            - 问答机器人
            
        4.语音指令
            - 录音
            - 上传
            - NLP 自然语言处理
            - 我要听
            - 发消息给xxxx

     下面进行模拟一个web进行处理:

     

    下面需要再创建一个html文件:,注意,现在我们模拟的是web页面,不写前后端分离了

     江老师传授的播放方式:

    音乐的名字   可以直接copy采集下来的数据名称用上边的命令进行处理

    下面我们再写一个发送按钮:

    在组件中看一下颜色:

    下面,我们需要再次写一个事件

     

    我们先写一些数字,看能不能发送成功:

    下面,我们需要在服务端新建一个ws_serv.py开启一个通讯服务

    下面,我们需要基于flask,写一个websocket服务

     两套服务,写在同一套代码里边:一个开ws_serv.py,另一个专门开manager.py

    刚才江老师的方式也是一种get请求方式

    我以为你是个暖男,结果你只支持get请求:

    先安装好这个包,再处理:

    ws_serv.py

    import json
    
    from flask import Flask,request
    ws_serv=Flask(__name__)
    
    from geventwebsocket.websocket import WebSocket
    from gevent.pywsgi import WSGIServer      #替换werkzurg
    from geventwebsocket.handler import WebSocketHandler      #处理wsgi带的请求头的信息
    
    user_socket_dict={}
    @ws_serv.route("/app/<app_id>")
    def app(app_id):
        user_socket=request.environ.get("wsgi.websocket")
        if user_socket:
            user_socket_dict[app_id]=user_socket
        print(len(user_socket_dict),user_socket_dict)
        while True:
            msg=user_socket.receive()
            msg_dict=json.loads(msg)
            #msg{to_user:toy01,music: getmusic/25d3c036-4b1f-4f4b-827a-fc4ddc50286f.mp3 }
            print(msg_dict)
    if __name__ == '__main__':
    http_serv=WSGIServer(("0.0.0.0",9528),app,handler_class=WebSocketHandler)
    http_serv.serve_forever()
     

    下面,我们看一下,能不能拿出值来

    运行上边的ws_serv.py程序,这个时候就会阻塞住

    这个时候,我们随便点击一首歌,点击发送

     

    报错,不能传递两个参数

    错误的原因是上边的app写错了,应该是ws_serv

     

    这个时候运行,再次点击进入一首歌,点击"发送",然后我们再后端就可以收到信息了

    下面我们看一下,能不能发送这个字典:

    我们再次方式会报一堆错误:

    思考,我们应该如何处理?我们应该先转成字符串在进行处理,也就是json转换成字符串:

    上边报错的原因是,我把点好写成了冒号上边是改正过来的信息

     

    再次修改:

    再次发送,得到下面发送的结果:

    为了保证不出错,注意放的位置

    为了不出错,我们可以有两种方式,防止内容:下图是放置好的方式,目的就是,放好了防止出错,JavaScript是异步代码,防止线程过快等问题

    下面,我们需要接收代码:

    下面是ws_serv.py的代码

    # Author: studybrother sun
    import json
    
    from flask import Flask,request
    ws_serv=Flask(__name__)
    
    from geventwebsocket.websocket import WebSocket
    from gevent.pywsgi import WSGIServer      #替换werkzurg
    from geventwebsocket.handler import WebSocketHandler      #处理wsgi带的请求头的信息
    
    user_socket_dict={}
    @ws_serv.route("/app/<app_id>")
    def app(app_id):
        user_socket=request.environ.get("wsgi.websocket")
        if user_socket:
            user_socket_dict[app_id]=user_socket
        print(len(user_socket_dict),user_socket_dict)
        while True:
            msg=user_socket.receive()
            msg_dict=json.loads(msg)
            #msg{to_user:toy01,music: getmusic/25d3c036-4b1f-4f4b-827a-fc4ddc50286f.mp3 }
            print(msg_dict)
    
    @ws_serv.route("/toy/<toy_id>")
    def toy(toy_id):
        user_socket=request.environ.get("wsgi.websocket")
        if user_socket:
            user_socket_dict[toy_id]=user_socket
        print(len(user_socket_dict),user_socket_dict)
        while True:
            msg=user_socket.receive()
            msg_dict=json.loads(msg)
            #msg{to_user:toy01,music: getmusic/25d3c036-4b1f-4f4b-827a-fc4ddc50286f.mp3 }
            print(msg_dict)
    
    if __name__ == '__main__':
        http_serv=WSGIServer(("0.0.0.0",9528),ws_serv,handler_class=WebSocketHandler)
        http_serv.serve_forever()

    下面是WebToy.html代码:

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta http-equiv="content-Type" charset="UTF-8">
        <meta http-equiv="x-ua-compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width" ,initial-scale="1">
        <!--上边这个表示手机版的调整尺寸-->
        <!--上述2个meta标签"必须"放在最前面,任何其他内容都必须跟随其后-->
        <title>Title</title>
    </head>
    <body>
        <audio controls autoplay id="player"></audio>
        <!--我们通过id进行控制-->
    </body>
    <script type="application/javascript">
        var ws=new WebSocket("ws://192.168.14.133:9528/toy/toy01");
        //这样写的原因是toy有很多种,不得不这样写
        ws.onmessage=function (eventMessage) {
            msg=JSON.parse(eventMessage.data)   //字符串转换成object
            document.getElementById("player").src="http://192.168.14.133:9527/getmusic"+msg.music;//大前提是需要发送消息
        }//这个时候能够接收消息
    </script>
    </html>

    目录结构:

    因为这个涉及到web录音,我们需要用到火狐浏览器,重启一下ws_serv.py文件

     用火狐浏览器访问,注意这个访问的端口是服务器的端口"9527"

    报错原因,是我们没有放值

    这个时候,就没有问题了

    如果,我们访问的是9528,得到下面的结果:

    正确访问地址之后,ws_serv得到下面的结果:

    另一个,点击发送歌曲的时候,就连接上了,第一个是火狐浏览器输入地址,就能访问,第二个是app点击发送得到的结果:

     

    修改成下面的内容:

    再次运行ws_serv.py,运行火狐

    下图就是我们的单聊:

    也就是遥控器功能.给服务器前端节省一些资源

    在火狐上一直出不来的原因就是少写了一个/

    写完之后,运行manager.py和ws_serv.py,运行前端程序,在浏览器上输入网址:(192.168.14.133:9527),在模拟器上打开歌曲,点击发送,这个时候,浏览器就可以接收到音乐了,可以进行播放了.

    6.可以进行的一些拓展

    1.立项 - 名字随意 - 最好有意义
    2.Index + Home + Player
    3.图文列表通过JS document.createElement Item
    4.Player 播放内容 实现暂停继续
    5.App遥控玩具 - Websocket 单聊技术
    
    扩展任务:        
    6.自动登录 + 注册
    {
        _id:"",
        username:"",
        password:"MD5",
        nickname:"",
        gender: 1 / 2,
        avatar: 1==girl.jpg / 2==boy.jpg,
        bind_toy : [],
        firend_list:[]
    }
    
    reg.html
    gender 单选框
    password MD5
    
    login.html
    自动登录

     核心问题:

    先研究好这些逻辑的问题再说.

    查文档,看视频.

  • 相关阅读:
    类操作工具类
    让你的Git水平更上一层楼的10个小贴士
    android camera(四):camera 驱动 GT2005
    android camera(三):camera V4L2 FIMC
    android camera(二):摄像头工作原理、s5PV310 摄像头接口(CAMIF)
    android camera(一):camera模组CMM介绍
    MTK Android Driver知识大全
    makefile 进阶
    RGB Bayer Color分析
    8.3 MPI
  • 原文地址:https://www.cnblogs.com/studybrother/p/10738632.html
Copyright © 2020-2023  润新知