简介
点赞 + 关注 + 收藏 = 学会了
只用 Python
也能做出很漂亮的网站?Streamlit
说可以。

Streamlit
官方介绍:能在几分钟内把 Python
脚本变成可分享的网站。只需使用纯 Python
,无需前端经验。甚至,你只需要懂 markdown
,然后按照一定规则去做也能搞个网页出来。它还支持免费部署,感动到落泪。
安装
首先你的电脑需要有 python
环境。没有的话可以到 python
官网下载。安装步骤可以按这篇文章 《Python 快速入门篇》。
有 python
环境后,使用下面这条命令就可以安装 streamlit
。
bash
pip install streamlit
安装 streamlit
成功后可以使用下面这条命令看看能不能运行起来。
streamlit hello
然后在浏览器打开 http://192.168.31.83:8502
,能看到这个界面证明 streamlit
真的装好了。

运行
装好 streamlit
后,找个创建一个文件夹,然后创建一个 python
文件。
然后运行指定py页面文件。
bash
streamlit run xxx.py
比如我这里创建一个 streamlit-demo1
的文件夹,表示这个项目叫 streamlit-demo1
。然后再创建一个 page1.py
文件。

接下来使用终端进入 streamlit-demo1
目录运行下面这条命令。
arduino
streamlit run page1.py
之后终端会提示你打开对应的地址,我这里提示我打开 http://localhost:8501

看到下图这个页面就是成功了。

基础用法
接下来试试 streamlit
基础用法,其实跟 HTML
的难度差不多的,而且 streamlit
还提供了一些默认的样式,省去很多写 CSS
的工作。
在使用 streamlit
之前需要先引入它。
python
import streamlit as st
之后才能调用 streamlit
提供的方法。
段落 write
段落就是 HTML
里的 <p>
元素,在 streamlit
里使用 st.write('内容')
的方式去书写。

python
import streamlit as st
st.write('雷猴!')
标题 title
使用 st.title()
可以设置标题内容。

python
st.title('雷猴')
相比起 st.write()
,使用 st.title()
出来的效果字号会更大,而且字体也加粗了。
使用 markdown
streamlit
是支持使用 markdown
语法来写页面内容的,只需使用单引号或者双引号的方式将内容包起来,并且使用 markdown
的语法进行书写,页面就会出现对应样式的内容。

python
import streamlit as st
"# 1级标题"
"## 2级标题"
"### 3级标题"
"#### 4级标题"
"##### 5级标题"
"###### 6级标题"
"""
```python
print('雷猴')
```
"""
markdown
的语法不是本文的重点,这里就不过多介绍了。
图片 image
渲染图片可以使用 st.image()
方法,也可以使用 markdown
的语法。
st.image(图片地址, [图片宽度])
,其中图片宽度不是必填项。

python
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
等数据。

python
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()
创建出来的表格支持按列排序、搜索、导出等功能。

python
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()
方法绘制分隔线。

python
import streamlit as st
st.divider()
变量 variable
接下来要介绍的组件在交互上会越来越丰富,所以在此先引入一个"变量"的东西。
使用 streamlit
写页面也支持 python
的变量。变量的主要作用是存值。

python
import streamlit as st
a = 10
b = 20
st.write(a * b)
条件判断 if
条件判断使用 if
。也可以配合 elif
和 else
一起使用。

python
import streamlit as st
a = 11
if a % 2 == 0:
st.write(f'{a}是偶数')
else:
st.write(f'{a}是奇数')
循环 for
循环(遍历)可以使用 for,语法就是 python
的语法。

python
import streamlit as st
for a in range(1, 10, 2):
st.write(a)
输入框 text_input
知道怎么声明变量后,可以使用一个变量接收输入框的内容。
输入框又可以设置不同的类型,比如普通的文本输入框、密码输入框。
普通输入框
输入框使用 st.text_input()
渲染。

python
name = st.text_input('请输入你的名字:')
if name:
st.write(f'你好,{name}')
st.text_input()
括号里的内容会变成输入框的提示内容。在这个例子中,将 st.text_input()
接收到的值赋给变量 name
。然后再通过一个 if
判断 name
有没有内容,如果有内容就向页面打印这个内容。
密码
如果要使用密码框,可以给 st.text_input()
加多个类型 type="password"
。

python
import streamlit as st
pwd = st.text_input('密码是多少?', type='password')
数字输入框 number_input
数字输入框需要使用 number_input
,这个可能和你想象中有点不一样,一开始我也以为使用 st.text_input(type="number")
,失算了。

python
import streamlit as st
age = st.number_input('年龄:')
st.write(f'你输入的年龄是{age}岁')
众所周知,正常表达年龄是不带小数位的,所以我们可以设置 st.number_input()
的步长为1,参数名叫 step
。
python
# 省略部分代码
st.number_input('年龄:', step=1)
这个步长可以根据你的需求来设置,设置完后,输入框右侧的加减号每点击一次就根据你设置的步长相应的增加或者减少。
还有一点,人年龄不可能是负数,通常也不会大于200。可以通过 min_value
和 max_value
设置最小值和最大值。同时还可以通过 value
设置默认值。
python
st.number_input('年龄:', value=20, min_value=0, max_value=200, step=1)
多行文本框 text_area
创建多行文本框使用的是 st.text_area()
,用法和 st.text_input()
差不多。

python
import streamlit as st
paragraph = st.text_area("多行内容:")
复选框 checkbox
很多应用在登录之前需要用户同意某些协议才能使用,如果你网站也需要这个功能的话可以使用复选框 st.checkbox()
让用户去勾选。

python
import streamlit as st
checked = st.checkbox("同意以上条款")
if checked:
st.write("同意")
else:
st.write("不同意")
单选按钮 radio
使用 st.radio()
可以制作单选按钮,比如让用户选择性别的时候就能派上用场。

python
import streamlit as st
res = st.radio(
"给我的文章点个赞吧",
["点赞", "点多几篇"]
)
单选按钮也可以使用一个变量来接收结果。
它还支持设置默认值,使用 index
参数即可。index
的默认值是0,也就是选中下标为 0 的那项。可以根据你的需求自定义设置。
python
import streamlit as st
res = st.radio(
"给我的文章点个赞吧",
["点赞", "点多几篇"],
index=1
)
单选下拉框 selectbox
使用 st.selectbox()
可以创建单选下拉框。
用法是:
arduino
st.selectbox(
"提示语",
["选项1", "选项2"]
)

python
import streamlit as st
article = st.selectbox(
"你喜欢哪篇文章?",
[
"《『Python爬虫』极简入门》",
"《『SD』零代码AI绘画:光影字》",
"《『SD』Stable Diffusion WebUI 安装插件(以汉化为例)》",
"《NumPy入个门吧》"
]
)
st.write(f"你喜欢{article}")
多选下拉框 multiselect
使用 st.multiselect()
可以创建多选下拉框,用法和 st.selectbox()
一样。

python
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()
差不多,也是可以设置提示语、默认值、最大值、最小值以及步长。

python
import streamlit as st
height = st.slider("粉丝量", value=170, min_value=100, max_value=230, step=1)
st.write(f"你的粉丝量是{height}")
按钮 button
使用 st.button()
创建按钮。它接收一个字符串作为按钮文本,可以将点击结果赋值给一个变量。

python
import streamlit as st
submitted = st.button("关注")
if submitted:
st.write(f"用户点击关注啦啦啦啦啦")
文件上传 file_uploader
python
擅长做数据分析,有时候可能需要上传一个 csv
之类的文件分析一下。
在 streamlit
中可以使用 st.file_uploader()
创建一个文件上传元素。

python
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()
可以给网页弄个侧边栏。

python
import streamlit as st
res = ''
with st.sidebar:
res = st.text_input('搜索:')
st.write(f'页面内容,看看搜索了啥:{res}')
多列布局 columns
按照前面学到的内容写页面的话,所有元素都是从上往下布局的。如果你想一个页面有多列布局,可以使用 st.columns()
方法。

python
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
时,默认每列的宽度都是一样的。如果你希望每列宽度占比不一样的话可以这样写。

python
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()
可以创建选项卡组件。

python
import streamlit as st
# 选项卡
tab1, tab2, tab3 = st.tabs(['点赞', '关注', '收藏'])
with tab1:
st.write('快点赞吧')
with tab2:
st.write('关注一下啦')
with tab3:
st.write('收藏就是学会了')
折叠展开组件 expander
使用 st.expander()
可以创建折叠展开组件。

python
import streamlit as st
with st.expander('更多信息'):
st.title('雷猴')
st.write('鲨鱼辣椒')
st.write('蝎子莱莱')
图表
streamlit
支持很多类型的图表,本文先介绍一下如何绘制折线图。其他图表迟点单独开一篇文章吹吹水。
画折线图用的是 st.line_chart()
方法。

python
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入个门吧》。
多页面
网站通常由多个页面组成,在 streamlit
中想创建多个页面很简单。
- 在根目录创建主页入口。
- 在根目录创建
pages
文件夹(一定是pages
这个名字,不能是其他名)。

你看我这个目录结构,然后在每个文件里输入点内容。
打开浏览器看效果:

部署
我们可以按照 Streamlit
官方文档说的那样部署。
打开 share.streamlit.io/,未注册过的工友需要注...

在部署之前还需要将你的代码传到你的 github
仓库上。这一步应该所有程序员都要掌握的,本文就不讲解了。
把代码传上 github
仓库后,回到 share.streamlit.io/ 就可以创建自己的 streamlit
应用了。

然后根据提示填写好你的网站资料。

- Repository:选择你刚上传的
streamlit
项目的仓库。 - Branch:分支。
- Main file path:你的
streamlit
项目的主页入口文件。 - App URL (Optional):二级域名
填好资料后点击"Deploy!"按钮,稍等片刻后就部署好了。

这是我部署好的主页,你们可以瞧瞧:zhuren.streamlit.app/
还没完!还没完!streamlit
还有很多功能本文没讲到的,比如会话、各种各样的图表。这些留到下一篇再讲。
点赞 + 关注 + 收藏 = 学会了
