Streamlit 光速搭建并部署你的主页
简介
点赞 + 关注 + 收藏 = 学会了
只用 Python
也能做出很漂亮的网站?Streamlit
说可以。
Streamlit
官方介绍:能在几分钟内把 Python
脚本变成可分享的网站。只需使用纯 Python
,无需前端经验。甚至,你只需要懂 markdown
,然后按照一定规则去做也能搞个网页出来。它还支持免费部署,感动到落泪。
安装
首先你的电脑需要有 python
环境。没有的话可以到 python
官网下载。安装步骤可以按这篇文章 《Python 快速入门篇》。
有 python
环境后,使用下面这条命令就可以安装 streamlit
。
pip install streamlit
安装 streamlit
成功后可以使用下面这条命令看看能不能运行起来。
streamlit hello
然后在浏览器打开 http://192.168.31.83:8502
,能看到这个界面证明 streamlit
真的装好了。
运行
装好 streamlit
后,找个创建一个文件夹,然后创建一个 python
文件。
然后运行指定py页面文件。
streamlit run xxx.py
比如我这里创建一个 streamlit-demo1
的文件夹,表示这个项目叫 streamlit-demo1
。然后再创建一个 page1.py
文件。
接下来使用终端进入 streamlit-demo1
目录运行下面这条命令。
streamlit run page1.py
之后终端会提示你打开对应的地址,我这里提示我打开 http://localhost:8501
看到下图这个页面就是成功了。
基础用法
接下来试试 streamlit
基础用法,其实跟 HTML
的难度差不多的,而且 streamlit
还提供了一些默认的样式,省去很多写 CSS
的工作。
在使用 streamlit
之前需要先引入它。
import streamlit as st
之后才能调用 streamlit
提供的方法。
段落 write
段落就是 HTML
里的 <p>
元素,在 streamlit
里使用 st.write('内容')
的方式去书写。
import streamlit as st
st.write('雷猴!')
标题 title
使用 st.title()
可以设置标题内容。
st.title('雷猴')
相比起 st.write()
,使用 st.title()
出来的效果字号会更大,而且字体也加粗了。
使用 markdown
streamlit
是支持使用 markdown
语法来写页面内容的,只需使用单引号或者双引号的方式将内容包起来,并且使用 markdown
的语法进行书写,页面就会出现对应样式的内容。
import streamlit as st
"# 1级标题"
"## 2级标题"
"### 3级标题"
"#### 4级标题"
"##### 5级标题"
"###### 6级标题"
"""
```python
print('雷猴')
"""
`markdown` 的语法不是本文的重点,这里就不过多介绍了。
图片 image
--------
渲染图片可以使用 `st.image()` 方法,也可以使用 `markdown` 的语法。
`st.image(图片地址, [图片宽度])` ,其中图片宽度不是必填项。
![08.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/13e01deaa8584569b03593bff5e33836~tplv-k3u1fbpfcp-jj-mark:3024:0:0:0:q75.awebp#?w=1057&h=651&s=116250&e=jpg&b=fcfafa)
import streamlit as st
st.image('./dog.jpg', width=400)
我在项目里放了一张狗的图片,使用 `st.image` 渲染它,并将宽度设置成 400。
表格
--
`streamlit` 有静态表格和可交互表格。表格在数据分析里属于常用组件,所以 `streamlit` 的表格也支持 `pandas` 的 `DataFrame` 。
### 静态表格 table
静态表格使用 `st.table()` 渲染,出来的效果就是 `HTML` 的 `<table>`。
`st.table()` 支持传入字典、`pandas.DataFrame` 等数据。
![09.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1f2e5ba51d1144349cac7e7d92d9722f~tplv-k3u1fbpfcp-jj-mark:3024:0:0:0:q75.awebp#?w=941&h=413&s=12907&e=png&b=ffffff)
import streamlit as st
import pandas as pd
st.write('dict')
字典
st.table(
data={
"姓名": ['雷猴', '鲨鱼辣椒'],
"年龄": [18, 22]
}
)
DataFrame
df = pd.DataFrame(
{
"姓名": ['雷猴', '鲨鱼辣椒'],
"年龄": [18, 22],
}
)
st.write('DataFrame')
st.table(df)
### 可交互表格 dataframe
可交互表格使用 `st.dataframe()` 方法创建,和 `st.table()` 不同,`st.dataframe()` 创建出来的表格支持按列排序、搜索、导出等功能。
![10.gif](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d12b1f5142c547febf8f6d702bb227fe~tplv-k3u1fbpfcp-jj-mark:3024:0:0:0:q75.awebp#?w=315&h=359&s=229322&e=gif&f=147&b=ffffff)
import streamlit as st
import pandas as pd
st.write('dict')
字典
st.dataframe(
data={
"姓名": ['雷猴', '鲨鱼辣椒'],
"年龄": [18, 22]
}
)
DataFrame
df = pd.DataFrame(
{
"姓名": ['雷猴', '鲨鱼辣椒'],
"年龄": [18, 22],
}
)
st.write('DataFrame')
st.dataframe(df)
分隔线 divider
-----------
分隔线就是 `HTML` 里的 `<hr>` 。在 `streamlit` 里使用 `st.divider()` 方法绘制分隔线。
![11.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d556a29a62884203a9664f1c3538f76a~tplv-k3u1fbpfcp-jj-mark:3024:0:0:0:q75.awebp#?w=941&h=169&s=2584&e=png&b=ffffff)
import streamlit as st
st.divider()
变量 variable
-----------
接下来要介绍的组件在交互上会越来越丰富,所以在此先引入一个“变量”的东西。
使用 `streamlit` 写页面也支持 `python` 的变量。变量的主要作用是存值。
![12.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e7c7aabaae114bffb5f56788d4782e2a~tplv-k3u1fbpfcp-jj-mark:3024:0:0:0:q75.awebp#?w=719&h=149&s=2690&e=png&b=ffffff)
import streamlit as st
a = 10
b = 20
st.write(a * b)
条件判断 if
-------
条件判断使用 `if`。也可以配合 `elif` 和 `else` 一起使用。
![13.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c790ff7fbd674d1f986bc14fc7c8c7ce~tplv-k3u1fbpfcp-jj-mark:3024:0:0:0:q75.awebp#?w=500&h=124&s=2621&e=png&b=ffffff)
import streamlit as st
a = 11
if a % 2 == 0:
st.write(f'{a}是偶数')
else:
st.write(f'{a}是奇数')
循环 for
------
循环(遍历)可以使用 for,语法就是 `python` 的语法。
![14.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b1d05395590149fc99a8ea249f623fb2~tplv-k3u1fbpfcp-jj-mark:3024:0:0:0:q75.awebp#?w=500&h=275&s=3516&e=png&b=ffffff)
import streamlit as st
for a in range(1, 10, 2):
st.write(a)
输入框 text\_input
---------------
知道怎么声明变量后,可以使用一个变量接收输入框的内容。
输入框又可以设置不同的类型,比如普通的文本输入框、密码输入框。
### 普通输入框
输入框使用 `st.text_input()` 渲染。
![15.gif](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b109e398cafd438cb1b185153dd7f0e0~tplv-k3u1fbpfcp-jj-mark:3024:0:0:0:q75.awebp#?w=493&h=297&s=60293&e=gif&f=35&b=ffffff)
name = st.text_input('请输入你的名字:')
if name:
st.write(f'你好,{name}')
`st.text_input()` 括号里的内容会变成输入框的提示内容。在这个例子中,将 `st.text_input()` 接收到的值赋给变量 `name` 。然后再通过一个 `if` 判断 `name` 有没有内容,如果有内容就向页面打印这个内容。
### 密码
如果要使用密码框,可以给 `st.text_input()` 加多个类型 `type="password"`。
![16.gif](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d0a0ae9097984d2985223b12380ade11~tplv-k3u1fbpfcp-jj-mark:3024:0:0:0:q75.awebp#?w=493&h=297&s=151372&e=gif&f=71&b=ffffff)
import streamlit as st
pwd = st.text_input('密码是多少?', type='password')
数字输入框 number\_input
-------------------
数字输入框需要使用 `number_input`,这个可能和你想象中有点不一样,一开始我也以为使用 `st.text_input(type="number")` ,失算了。
![17.gif](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b4164dae24134bed8f283fc2c72293c2~tplv-k3u1fbpfcp-jj-mark:3024:0:0:0:q75.awebp#?w=493&h=297&s=237127&e=gif&f=144&b=ffffff)
import streamlit as st
age = st.number_input('年龄:')
st.write(f'你输入的年龄是{age}岁')
众所周知,正常表达年龄是不带小数位的,所以我们可以设置 `st.number_input()` 的步长为1,参数名叫 `step`。
省略部分代码
st.number_input('年龄:', step=1)
这个步长可以根据你的需求来设置,设置完后,输入框右侧的加减号每点击一次就根据你设置的步长相应的增加或者减少。
还有一点,人年龄不可能是负数,通常也不会大于200。可以通过 `min_value` 和 `max_value` 设置最小值和最大值。同时还可以通过 `value` 设置默认值。
st.number_input('年龄:', value=20, min_value=0, max_value=200, step=1)
多行文本框 text\_area
----------------
创建多行文本框使用的是 `st.text_area()`,用法和 `st.text_input()` 差不多。
![18.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/8ad42d2d427a4a5985a1b5c85f21ca6a~tplv-k3u1fbpfcp-jj-mark:3024:0:0:0:q75.awebp#?w=637&h=276&s=4470&e=png&b=ffffff)
import streamlit as st
paragraph = st.text_area("多行内容:")
复选框 checkbox
------------
很多应用在登录之前需要用户同意某些协议才能使用,如果你网站也需要这个功能的话可以使用复选框 `st.checkbox()` 让用户去勾选。
![19.gif](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c3a490a06c6f4113948f21f6b5c41e15~tplv-k3u1fbpfcp-jj-mark:3024:0:0:0:q75.awebp#?w=616&h=372&s=96155&e=gif&f=56&b=ffffff)
import streamlit as st
checked = st.checkbox("同意以上条款")
if checked:
st.write("同意")
else:
st.write("不同意")
单选按钮 radio
----------
使用 `st.radio()` 可以制作单选按钮,比如让用户选择性别的时候就能派上用场。
![20.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6d1a9312c3694d91b9b533d139d41f92~tplv-k3u1fbpfcp-jj-mark:3024:0:0:0:q75.awebp#?w=637&h=213&s=7240&e=png&b=ffffff)
import streamlit as st
res = st.radio(
"给我的文章点个赞吧",
["点赞", "点多几篇"]
)
单选按钮也可以使用一个变量来接收结果。
它还支持设置默认值,使用 `index` 参数即可。`index` 的默认值是0,也就是选中下标为 0 的那项。可以根据你的需求自定义设置。
import streamlit as st
res = st.radio(
"给我的文章点个赞吧",
["点赞", "点多几篇"],
index=1
)
单选下拉框 selectbox
---------------
使用 `st.selectbox()` 可以创建单选下拉框。
用法是:
st.selectbox(
"提示语",
["选项1", "选项2"]
)
![21.gif](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6831ab1dd1954ad093f077a27da4d462~tplv-k3u1fbpfcp-jj-mark:3024:0:0:0:q75.awebp#?w=615&h=392&s=364287&e=gif&f=106&b=ffffff)
import streamlit as st
article = st.selectbox(
"你喜欢哪篇文章?",
[
"《『Python爬虫』极简入门》",
"《『SD』零代码AI绘画:光影字》",
"《『SD』Stable Diffusion WebUI 安装插件(以汉化为例)》",
"《NumPy入个门吧》"
]
)
st.write(f"你喜欢{article}")
多选下拉框 multiselect
-----------------
使用 `st.multiselect()` 可以创建多选下拉框,用法和 `st.selectbox()` 一样。
![22.gif](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6ef38930488048f183b6ff6ae9720d8d~tplv-k3u1fbpfcp-jj-mark:3024:0:0:0:q75.awebp#?w=615&h=392&s=332413&e=gif&f=95&b=ffffff)
import streamlit as st
article_list = st.multiselect("你喜欢哪篇文章?",
[
"《『Python爬虫』极简入门》",
"《『SD』零代码AI绘画:光影字》",
"《『SD』Stable Diffusion WebUI 安装插件(以汉化为例)》",
"《NumPy入个门吧》"
]
)
for article in article_list:
st.write(f"你喜欢{article}")
`st.multiselect()` 返回的结果是一个列表,可以使用 `for` 循环输出。
滑块 slider
---------
可以使用 `st.slider()` 创建滑块元素。它接收的参数和 `st.number_input()` 差不多,也是可以设置提示语、默认值、最大值、最小值以及步长。
![23.gif](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/8294ff48df304bb7ba512a74ced81413~tplv-k3u1fbpfcp-jj-mark:3024:0:0:0:q75.awebp#?w=615&h=266&s=182908&e=gif&f=120&b=ffffff)
import streamlit as st
height = st.slider("粉丝量", value=170, min_value=100, max_value=230, step=1)
st.write(f"你的粉丝量是{height}")
按钮 button
---------
使用 `st.button()` 创建按钮。它接收一个字符串作为按钮文本,可以将点击结果赋值给一个变量。
![24.gif](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ab9224e421fd41bcb3bfe3f0c5d2abb5~tplv-k3u1fbpfcp-jj-mark:3024:0:0:0:q75.awebp#?w=615&h=266&s=67605&e=gif&f=42&b=ffffff)
import streamlit as st
submitted = st.button("关注")
if submitted:
st.write(f"用户点击关注啦啦啦啦啦")
文件上传 file\_uploader
-------------------
`python` 擅长做数据分析,有时候可能需要上传一个 `csv` 之类的文件分析一下。
在 `streamlit` 中可以使用 `st.file_uploader()` 创建一个文件上传元素。
![25.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/fc50af38a8bb417ca3a3c6b4b45ab5b9~tplv-k3u1fbpfcp-jj-mark:3024:0:0:0:q75.awebp#?w=637&h=310&s=12661&e=png&b=ffffff)
import streamlit as st
uploaded_file = st.file_uploader("上传文件", type=["csv", "json"])
if uploaded_file:
st.write(f"你上传的文件是{uploaded_file.name}")
`st.file_uploader()` 第一个参数是提示文本,然后可以使用 `type` 属性限制用户上传的文件格式。
接收到的文件可以赋值给一个变量,这个变量接收到文件后可以通过 `.name` 属性查看文件名。
侧边栏 sidebar
-----------
使用 `st.sidebar()` 可以给网页弄个侧边栏。
![26.gif](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b81de490cf0a45bb9202bfb32cf4901f~tplv-k3u1fbpfcp-jj-mark:3024:0:0:0:q75.awebp#?w=805&h=266&s=242278&e=gif&f=141&b=fefefe)
import streamlit as st
res = ''
with st.sidebar:
res = st.text_input('搜索:')
st.write(f'页面内容,看看搜索了啥:{res}')
多列布局 columns
------------
按照前面学到的内容写页面的话,所有元素都是从上往下布局的。如果你想一个页面有多列布局,可以使用 `st.columns()` 方法。
![27.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/5cddc56aa52d47149c1651c70768bd60~tplv-k3u1fbpfcp-jj-mark:3024:0:0:0:q75.awebp#?w=900&h=198&s=4484&e=png&b=ffffff)
import streamlit as st
col1, col2, col3 = st.columns(3)
with col1:
st.write('第1列')
with col2:
st.write('第2列')
with col3:
st.write('第3列')
代码结构和页面对应起来,很直观,我就不过多讲解了。
在使用 `st.columns` 时,默认每列的宽度都是一样的。如果你希望每列宽度占比不一样的话可以这样写。
![28.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/20377bb255fb4b16b162fe306d4c4843~tplv-k3u1fbpfcp-jj-mark:3024:0:0:0:q75.awebp#?w=900&h=200&s=4490&e=png&b=ffffff)
import streamlit as st
多列布局(不同比例)
col1, col2, col3 = st.columns([1, 2, 3])
with col1:
st.write('第1列')
with col2:
st.write('第2列')
with col3:
st.write('第3列')
此时 `st.columns()` 括号里传入的就不是数字(列数),而是一个数值型列表,这个列表元素个数表示列数,元素的数字表示每列占比。
选项卡 tabs
--------
使用 `st.tabs()` 可以创建选项卡组件。
![29.gif](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a03dba8219234a8aa56082ed3f044c50~tplv-k3u1fbpfcp-jj-mark:3024:0:0:0:q75.awebp#?w=805&h=266&s=131058&e=gif&f=103&b=ffffff)
import streamlit as st
选项卡
tab1, tab2, tab3 = st.tabs(['点赞', '关注', '收藏'])
with tab1:
st.write('快点赞吧')
with tab2:
st.write('关注一下啦')
with tab3:
st.write('收藏就是学会了')
折叠展开组件 expander
---------------
使用 `st.expander()` 可以创建折叠展开组件。
![30.gif](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1291c6211ef845dcb49bc3b1a4a43e51~tplv-k3u1fbpfcp-jj-mark:3024:0:0:0:q75.awebp#?w=805&h=362&s=130282&e=gif&f=90&b=ffffff)
import streamlit as st
with st.expander('更多信息'):
st.title('雷猴')
st.write('鲨鱼辣椒')
st.write('蝎子莱莱')
图表
--
`streamlit` 支持很多类型的图表,本文先介绍一下如何绘制折线图。其他图表迟点单独开一篇文章吹吹水。
画折线图用的是 `st.line_chart()` 方法。
![31.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e753e1c16597454a98f3877d20040810~tplv-k3u1fbpfcp-jj-mark:3024:0:0:0:q75.awebp#?w=1043&h=492&s=65240&e=png&b=ffffff)
import streamlit as st
import numpy as np
st.line_chart(np.random.randn(10, 4))
这里借助 `numpy` 生成一个随机的数组。`np.random.randn` 的用法是 `np.random.randn(行数, 列数)` 。`numpy` 使用方法可以查看 [《NumPy入个门吧》](https://juejin.cn/post/7338422591518261263 "https://juejin.cn/post/7338422591518261263")。
多页面
---
网站通常由多个页面组成,在 `streamlit` 中想创建多个页面很简单。
1. 在根目录创建主页入口。
2. 在根目录创建 `pages` 文件夹(一定是 `pages` 这个名字,不能是其他名)。
![32.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/dc7704c973974ca79eeeec210ad0a525~tplv-k3u1fbpfcp-jj-mark:3024:0:0:0:q75.awebp#?w=203&h=144&s=6050&e=png&b=181818)
你看我这个目录结构,然后在每个文件里输入点内容。
打开浏览器看效果:
![33.gif](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0cc7e8fcf0b049dc932b5f2f514fff70~tplv-k3u1fbpfcp-jj-mark:3024:0:0:0:q75.awebp#?w=1108&h=528&s=315753&e=gif&f=137&b=fefefe)
部署
==
我们可以按照 [`Streamlit` 官方文档](https://link.juejin.cn/?target=https%3A%2F%2Fdocs.streamlit.io%2Fstreamlit-community-cloud%2Fdeploy-your-app "https://docs.streamlit.io/streamlit-community-cloud/deploy-your-app")说的那样部署。
打开 [share.streamlit.io/,](https://link.juejin.cn/?target=https%3A%2F%2Fshare.streamlit.io%2F%25EF%25BC%258C "https://share.streamlit.io/%EF%BC%8C")
未注册过的工友需要注册一下账号,然后根据提示填写好账号信息。
![34.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a852a1176660416a9d569676abaf1ebd~tplv-k3u1fbpfcp-jj-mark:3024:0:0:0:q75.awebp#?w=1536&h=1179&s=255463&e=jpg&b=fefefe)
在部署之前还需要将你的代码传到你的 `github` 仓库上。这一步应该所有程序员都要掌握的,本文就不讲解了。
把代码传上 `github` 仓库后,回到 [share.streamlit.io/](https://link.juejin.cn/?target=https%3A%2F%2Fshare.streamlit.io%2F "https://share.streamlit.io/") 就可以创建自己的 `streamlit` 应用了。
![35.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b023c84ad3464150ace0d9664cec4bbc~tplv-k3u1fbpfcp-jj-mark:3024:0:0:0:q75.awebp#?w=1134&h=802&s=35261&e=png&b=fef7f3)
然后根据提示填写好你的网站资料。
![36.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/634fdfa361944d22ab63455e868ec6c8~tplv-k3u1fbpfcp-jj-mark:3024:0:0:0:q75.awebp#?w=959&h=910&s=37763&e=png&b=fefefe)
* Repository:选择你刚上传的 `streamlit` 项目的仓库。
* Branch:分支。
* Main file path:你的 `streamlit` 项目的主页入口文件。
* App URL (Optional):二级域名
填好资料后点击“Deploy!”按钮,稍等片刻后就部署好了。
![37.gif](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/fc6124b3ce45478ca6a91a16405d70ac~tplv-k3u1fbpfcp-jj-mark:3024:0:0:0:q75.awebp#?w=384&h=308&s=23332&e=gif&f=7&b=ffffff)
这是我部署好的主页,你们可以瞧瞧:[zhuren.streamlit.app/](https://link.juejin.cn/?target=https%3A%2F%2Fzhuren.streamlit.app%2F "https://zhuren.streamlit.app/")
* * *
还没完!还没完!`streamlit` 还有很多功能本文没讲到的,比如会话、各种各样的图表。这些留到下一篇再讲。
**点赞 + 关注 + 收藏 = 学会了**
![640 (5).gif](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e493fa8da2564f00945399529a709f63~tplv-k3u1fbpfcp-jj-mark:3024:0:0:0:q75.awebp#?w=200&h=206&s=839969&e=gif&f=183&b=979aa2)