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

1.项目需求分析javascript

立项:Javis&&taisen(三个月所有,先模拟出一个玩具,硬件须要周期长一些)html

想法 --- 需求分析:
    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.数据采集 xmlyjava

首先,咱们须要采集数据,存在法律风险,须要带上出处和做者这个东西,不然极可能出现赔偿问题web

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

起名字无所谓的.mongodb

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

 

建立完后端,须要在前端同步开发json

在前端中,新建一个appflask

清除原来的内容,写一个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
自动登陆

 核心问题:

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

查文档,看视频.

相关文章
相关标签/搜索