Python-Streamlit-教程笔记-全-

Python Streamlit 教程笔记(全)

001:Streamlit 介绍 🚀

在本节课中,我们将要学习什么是 Streamlit,以及它为何是数据科学和机器学习领域快速构建 Web 应用的强大工具。

什么是 Streamlit?

在开始实际的 Streamlit 开发之前,理解 Streamlit 是什么至关重要。Streamlit 是一个 Python 框架,用于快速开发 Web 应用程序,特别是针对数据科学、机器学习和人工智能领域。

从定义中我们可以理解两点核心信息:它是一个 Python 框架,并且用于 Web 应用程序开发

为什么选择 Streamlit?

Python 中还有其他允许我们开发 Web 应用的框架,那么为什么选择 Streamlit 呢?让我们来看看它的主要优势。

以下是 Streamlit 的几个关键优势:

  • 兼容主流库:它与所有主流的 Python 库兼容,如 SciPyKerasNumPyPandasTensorFlow 等。
  • 开发速度快:它能极大提升我们的开发速度。当我们开始用 Streamlit 开发 Web 应用时,它的高效性会令人惊喜。
  • 安全可靠:它提供了安全可靠的 Web 应用开发体验,开发者无需过度担忧应用的安全性。
  • 无需前端代码:开发者无需编写 HTMLCSSJavaScript 代码,因为 Streamlit 允许我们纯粹使用 Python 脚本来开发前端界面。这是 Streamlit 的一个主要优势,意味着你不需要学习 HTML、CSS、JavaScript 等其他前端开发语言。
  • 易于部署:在 Streamlit 中开发的应用程序非常容易部署到平台如 GitHubHeroku

总结

本节课中,我们一起学习了 Streamlit 的基本概念。我们了解到 Streamlit 是一个用于快速构建数据科学类 Web 应用的 Python 框架,并探讨了其兼容性强、开发高效、安全且无需编写传统前端代码等核心优势。

希望你已经理解了 Streamlit 的介绍。在下一个教程中,我们将准备其开发环境并开始编写代码。我们下个教程再见。

002:搭建 Streamlit 开发环境 🛠️

在本节课中,我们将学习如何为 Streamlit 开发搭建一个完整的编程环境。我们将安装必要的软件、配置开发工具,并准备好第一个项目。

概述

要开始使用 Streamlit 开发 Web 应用程序,首先需要一个集成开发环境(IDE)和 Python 环境。本节将指导你完成 Visual Studio Code 的安装、Python 扩展的配置、项目文件夹的创建以及 Streamlit 库的安装。


安装 Visual Studio Code

首先,你需要一个用于 Streamlit 开发的 IDE。本教程将使用 Visual Studio Code。Visual Studio Code 是开发 Web 应用程序的优秀工具。

如果你已经安装了 Visual Studio Code,可以跳过本部分。如果尚未安装,请按照以下步骤操作:

  1. 访问 Visual Studio Code 官方网站:https://code.visualstudio.com/
  2. 根据你的操作系统(Windows、Mac 或 Linux)选择相应的下载选项。
  3. 下载完成后,双击安装程序,按照提示点击“下一步”完成安装。

安装完成后,你将看到类似下图的界面。


安装 Python 扩展

上一节我们安装了 IDE,本节中我们来看看如何为其添加 Python 支持。在 Visual Studio Code 中,你需要安装 Python 扩展来获得代码高亮、调试、智能提示等功能。

以下是安装步骤:

  1. 点击左侧活动栏的“扩展”图标(或使用快捷键 Ctrl+Shift+X)。
  2. 在搜索框中输入“Python”并按下回车。
  3. 在搜索结果中找到由 Microsoft 发布的“Python”扩展,点击“安装”按钮。

这个扩展对于 Python 开发非常有帮助,提供了链接、调试、代码提示等诸多功能。


创建项目文件夹

安装好 Python 扩展后,我们需要创建一个文件夹来存放所有的项目文件。

操作步骤如下:

  1. 点击左侧活动栏的“资源管理器”图标(或使用快捷键 Ctrl+Shift+E)。
  2. 点击“打开文件夹”按钮。
  3. 浏览到你希望创建项目的目录(例如“文档”或“桌面”)。
  4. 点击“新建文件夹”按钮,创建一个新文件夹,可以将其命名为 streamlit_dev
  5. 选择这个新文件夹并点击“选择文件夹”。系统可能会询问你是否信任该文件夹的作者,选择“是”。

现在,你的项目文件夹已经在 Visual Studio Code 中成功打开。


创建 Python 文件

环境准备就绪后,我们可以在项目中创建第一个 Python 文件。

以下是创建方法:

  1. 在资源管理器中,将鼠标悬停在你的项目文件夹名称上,会出现几个图标。
  2. 点击“新建文件”图标。
  3. 为文件命名,并确保以 .py 作为扩展名。例如,可以命名为 main.py,然后按下回车。

现在,你就可以在这个文件中开始编写 Streamlit 应用程序代码了。


安装 Streamlit 库

最后一步是安装 Streamlit 框架本身。我们将使用 Python 的包管理工具 pip 来完成安装。

以下是安装步骤:

  1. 在 Visual Studio Code 中,打开终端。你可以通过菜单栏选择“终端”->“新建终端”,或使用快捷键 Ctrl+`
  2. 在终端中,输入以下命令并按下回车:
    pip install streamlit
    
  3. 等待安装完成。如果之前已经安装过,终端会显示“Requirement already satisfied”。

安装完成后,你的 Streamlit 开发环境就全部配置好了。


总结

本节课中,我们一起学习了搭建 Streamlit 开发环境的完整流程。我们安装了 Visual Studio Code 作为 IDE,配置了必要的 Python 扩展,创建了项目文件夹和 Python 文件,并最终通过 pip 安装了 Streamlit 库。现在,你的开发环境已经准备就绪,在下一节课中,我们将开始使用 Streamlit 框架进行真正的 Web 应用开发。

003:Streamlit 基础文本元素 🎯

在本节课中,我们将开始使用 Streamlit 进行实际的 Web 应用开发。我们将学习如何导入 Streamlit 库、运行一个应用,并创建基础的文本元素,如标题、页眉、子标题和普通文本。

导入与运行 Streamlit 应用

首先,我们需要导入 Streamlit 库。大多数程序员习惯使用 st 作为别名,但本教程将使用 s 作为别名。

import streamlit as s

导入后,保存文件。但请注意,运行 Streamlit 应用的方式与运行普通 Python 脚本不同。你不能直接点击 IDE 中的“运行”按钮。

以下是运行 Streamlit 应用的正确方法:

  1. 打开终端。
  2. 输入命令 streamlit run,后跟你的 Python 文件名。
  3. 例如,如果文件名为 main.py,则命令为:streamlit run main.py

执行此命令后,终端会显示一个本地 URL(通常是 http://localhost:8501)和一个网络 URL。在浏览器中打开本地 URL,即可看到你的 Streamlit 应用。

为了便于开发,你可以将代码编辑器(如 VS Code)和浏览器窗口并排排列。在 Windows 系统中,你可以按住 Windows 键并使用方向键来调整窗口位置。

创建基础文本元素

成功运行应用后,我们就可以开始添加内容了。Streamlit 提供了几个简单的函数来创建文本元素。

添加标题

使用 s.title() 函数可以创建一个主标题。它接受一个字符串参数作为标题内容。

s.title("Hi, I am a Streamlit Web App")

保存文件后,浏览器中的页面会自动刷新,显示出你创建的大标题。

添加页眉与子标题

除了主标题,你还可以添加页眉和子标题,它们通常用于组织章节或次要标题。

  • 页眉:使用 s.header() 函数。
  • 子标题:使用 s.subheader() 函数。

以下是示例代码:

s.header("I am a header")
s.subheader("Hi, I am your subheader")

页眉和子标题在字体大小和样式上略有区别,子标题通常比页眉更小、颜色更浅。

添加普通文本

如果你需要添加段落式的普通文本,可以使用 s.text() 函数。这个函数类似于 HTML 中的 <p>(段落)标签。

s.text("Hi, I am text function and programmers use me in place of paragraph tag.")

s.text() 函数会以等宽字体显示文本,适合展示代码片段或简单的说明文字。

总结

本节课我们一起学习了 Streamlit 应用开发的起点。我们掌握了如何正确导入库并使用 streamlit run 命令来启动应用。接着,我们探索了四个基础的文本元素函数:s.title()s.header()s.subheader()s.text()。通过这些函数,我们能够快速地为 Web 应用添加不同层级的标题和说明文字,整个过程完全使用 Python 代码完成,无需接触前端 HTML/CSS。

在下一节教程中,我们将继续探讨 Streamlit 的其他功能和方法,为应用添加更多交互性和丰富的组件。

004:Streamlit 的更多文本元素

在本节课中,我们将学习 Streamlit 中用于处理文本的几个重要函数,包括 st.markdownst.captionst.latexst.jsonst.code。这些函数能帮助你为应用添加格式丰富的文本、数学公式、结构化数据和代码片段。

使用 Markdown 格式化文本

上一节我们介绍了基本的文本输出,本节中我们来看看如何使用 st.markdown 函数来应用 Markdown 语法,从而在应用中实现加粗、斜体、标题、列表、链接等多种富文本效果。

其基本语法是:

st.markdown("你的Markdown文本")

例如,要显示加粗的“Hello”和普通的“World”:

st.markdown("**Hello** World")

要显示斜体的“World”:

st.markdown("*World*")

以下是常用的 Markdown 语法示例列表:

  • 标题:使用 # 符号,例如 # 一级标题
  • 加粗文本:使用两个星号 ** 包裹文本,例如 **加粗**
  • 斜体文本:使用一个星号 * 包裹文本,例如 *斜体*
  • 代码块:使用三个反引号 ``` 包裹代码。
  • 有序列表:使用数字和点,例如 1. 第一项
  • 无序列表:使用短横线 - 或星号 *,例如 - 项目
  • 水平线:使用三个短横线 ---
  • 链接:使用 [链接文本](网址) 格式,例如 [Google](https://www.google.com)
  • 图片:使用 ![替代文本](图片地址) 格式。

你可以通过专门的 Markdown 指南网站查看更多详细语法。

添加标题和说明文字

除了主内容,我们经常需要添加一些辅助性文字。st.caption 函数用于显示小号的说明文字,通常用于图注或补充说明。

st.caption("这是一条说明文字")

嵌入数学公式

如果你的应用涉及数学或科学计算,可以使用 st.latex 函数来渲染 LaTeX 格式的数学公式。这需要在字符串前加上 r 将其标记为原始字符串,以防止转义字符被误解。

例如,显示一个 2x2 矩阵:

st.latex(r"""
\begin{pmatrix}
a & b \\
c & d
\end{pmatrix}
""")

互联网上有丰富的 LaTeX 语法资源,你可以查找并复制所需的公式代码。

展示 JSON 数据

在数据科学应用中,经常需要清晰展示 JSON 格式的数据结构。st.json 函数可以美观地渲染 JSON 对象,并支持折叠展开,便于查看。

import json
data = {"a": [1, 2, 3], "b": [4, 5, 6]}
st.json(data)

高亮显示代码

最后,st.code 函数允许你在应用中嵌入并高亮显示代码片段。这对于展示算法、示例代码或配置非常有用。你可以通过 language 参数指定编程语言以获得正确的语法高亮。

显示一段 Python 代码:

code = '''
def hello():
    print("Hello World")
    return 0
'''
st.code(code, language='python')

本节课中我们一起学习了 Streamlit 中五个强大的文本处理函数:st.markdown 用于富文本格式化,st.caption 用于添加说明,st.latex 用于渲染数学公式,st.json 用于展示结构化数据,以及 st.code 用于高亮显示代码。灵活运用这些函数,可以极大地增强你应用的表达力和专业性。

005:Streamlit显示元素

在本节课中,我们将要学习Streamlit中的几个核心显示元素:st.write()函数、st.metric()函数、st.table()函数和st.dataframe()函数。这些函数是构建交互式应用界面的基础。

🛠️ st.write():Streamlit的瑞士军刀

上一节我们介绍了Streamlit的基本布局,本节中我们来看看一个功能强大的通用函数——st.write()。这个函数是Streamlit的“瑞士军刀”,因为它允许我们实现多种功能。

st.write()函数的基本语法如下:

st.write(content)

它不仅能输出纯文本,还允许我们为文本添加不同的样式。例如,我们可以用它来渲染Markdown、JSON数据或代码。

以下是st.write()函数的一些常见用法:

  • 渲染Markdown:通过在文本前添加#等符号,可以将其渲染为Markdown标题。
    st.write(‘## 这是一个H2标题‘)
    
  • 输出JSON:可以直接传入Python字典,它会以格式化的JSON形式显示。
  • 显示代码:可以传入代码字符串,它会以代码块的形式高亮显示。

你可以通过查阅Streamlit官方文档来探索st.write()函数的更多玩法。

📊 st.metric():显示指标与变化

接下来,我们讨论st.metric()函数。这个函数主要用于展示一个关键指标及其变化值,常用于仪表板中显示如温度、速度、销售额等数据。

st.metric()函数接受三个重要参数:

st.metric(label, value, delta)
  • label:指标的标签,例如“风速”。
  • value:指标的值,例如“120”。
  • delta:指标值的变化量,例如“-1.4”。正值显示为绿色上升箭头,负值显示为红色下降箭头。

例如,要显示风速及其变化,可以这样写:

st.metric(label=“风速”, value=“120 m s⁻¹”, delta=“-1.4 m s⁻¹”)

注意:为了在字符串中正确显示上标(如s⁻¹),你可能需要在VS Code中安装名为“Fast Unicode Math Characters”的扩展,并使用特定快捷键(如输入^后按Tab键)来生成上标格式。

运行后,你会看到一个清晰的指标卡片,其中变化值-1.4会以红色和向下箭头显示,直观地表明了下降趋势。

📈 st.table()st.dataframe():展示表格数据

现在,让我们探讨用于展示表格数据的两个函数:st.table()st.dataframe()。在开始之前,我们需要先创建一个数据表格。这里我们使用Pandas库来生成一个简单的DataFrame。

首先,确保已安装Pandas库:

pip install pandas

然后在代码中导入并创建DataFrame:

import pandas as pd
import streamlit as st

![](https://github.com/OpenDocCN/cs-notes-pt1-zh/raw/master/docs/py-stlt-tut/img/0ef371f9a194089f3d8a8a962d2dd399_20.png)

![](https://github.com/OpenDocCN/cs-notes-pt1-zh/raw/master/docs/py-stlt-tut/img/0ef371f9a194089f3d8a8a962d2dd399_21.png)

data = {
    ‘column1‘: [1, 2, 3, 4, 5, 6, 7],
    ‘column2‘: [11, 12, 13, 14, 15, 16, 17]
}
df = pd.DataFrame(data)

使用 st.table() 显示静态表格

st.table()函数用于显示一个静态的、样式美观的表格。它直接将数据渲染为HTML表格,不支持交互。

st.table(df)

运行后,你会看到一个格式整洁的表格,清晰地列出了所有数据和索引。

使用 st.dataframe() 显示交互式表格

st.dataframe()函数则用于显示一个交互式的数据框。这是它与st.table()的主要区别。

st.dataframe(df)

运行后,显示的表格在列标题处会有一个排序图标。点击该图标,你可以对该列数据进行升序或降序排序。这种交互功能使得数据探索变得更加方便。

总结一下st.table()适合展示最终的、无需交互的静态表格;而st.dataframe()适合展示需要用户进行排序、筛选等交互操作的数据。

🎯 课程总结

本节课中我们一起学习了Streamlit的四个核心显示元素:

  1. st.write():作为多功能函数,可以输出文本、Markdown、JSON和代码。
  2. st.metric():用于突出显示一个关键指标及其变化趋势,非常适合数据仪表板。
  3. st.table():用于渲染静态的、美观的数据表格。
  4. st.dataframe():用于渲染交互式数据框,支持列排序等功能。

掌握这些基本的显示元素,是构建Streamlit应用界面的第一步。在接下来的教程中,我们将探索更多有趣的组件。

006:Streamlit媒体组件

在本节课中,我们将学习如何在你的Streamlit网络应用中嵌入音频、图片和不同类型的视频。嵌入这些媒体元素是增强应用交互性和吸引力的重要方式。

概述

Streamlit提供了简单直观的函数来处理媒体文件。我们将学习使用 st.image()st.audio()st.video() 这三个核心函数,分别用于嵌入图片、音频和视频。这些函数封装了复杂的HTML和JavaScript代码,让开发者能够通过一行Python代码实现丰富的媒体展示功能。

嵌入图片

上一节我们介绍了课程概述,本节中我们来看看如何嵌入图片。使用 st.image() 函数可以轻松地在应用中显示图片。

以下是 st.image() 函数的基本用法和参数:

st.image(image, caption=None, width=None, use_column_width=None, clamp=False, channels=“RGB”, output_format=“auto”)
  • image: 要显示的图片。可以是图片路径(字符串)、类似文件的对象、或表示图片的numpy数组。
  • caption: 图片下方的标题文字。
  • width: 指定图片的显示宽度(像素)。例如 width=680
  • use_column_width: 如果设置为 True,图片宽度将自动调整为列宽。
  • channels: 颜色通道,默认为 “RGB”。如果图片是 “BGR” 格式则需要指定。
  • output_format: 输出格式,如 “JPEG”“PNG”“auto”

让我们通过一个例子来实践。假设我们有一个名为 image.jpg 的图片文件。

import streamlit as st

# 嵌入一张图片
st.image(‘image.jpg’)

运行上述代码后,图片就会显示在应用中。我们可以为图片添加标题和调整宽度,使展示效果更好。

import streamlit as st

# 嵌入一张带有标题和指定宽度的图片
st.image(‘image.jpg’, caption=‘这是一张示例图片’, width=680)

嵌入音频

学会了嵌入图片后,接下来我们看看如何为应用添加声音。使用 st.audio() 函数可以嵌入音频文件。

以下是 st.audio() 函数的基本用法:

st.audio(data, format=“audio/wav”, start_time=0)
  • data: 音频数据。可以是文件路径(字符串)、类似文件的对象、字节或numpy数组。
  • format: 音频文件的格式,如 “audio/mp3”“audio/wav”。Streamlit会根据文件扩展名自动推断,但也可以手动指定。
  • start_time: 从音频的第几秒开始播放(默认从0秒开始)。

假设我们有一个名为 audio.mp3 的音频文件,嵌入方法非常简单。

import streamlit as st

# 嵌入一个音频文件
st.audio(‘audio.mp3’)

运行后,页面上会出现一个音频播放器。用户可以播放、暂停、调整音量、下载音频,甚至可以调整播放速度。

嵌入视频

最后,我们来学习如何嵌入视频,这是展示动态内容最直接的方式。使用 st.video() 函数可以嵌入视频文件。

以下是 st.video() 函数的基本用法:

st.video(data, format=“video/mp4”, start_time=0)
  • data: 视频数据。可以是文件路径(字符串)、类似文件的对象、字节或numpy数组。
  • format: 视频文件的格式,如 “video/mp4”“video/webm”。通常会自动推断。
  • start_time: 从视频的第几秒开始播放。

假设我们有一个名为 video.mp4 的视频文件。

import streamlit as st

# 嵌入一个视频文件
st.video(‘video.mp4’)

嵌入后,应用中将显示一个功能完整的视频播放器。用户可以进行播放、全屏、画中画、下载、调速等操作,体验与主流视频网站一致。

总结

本节课中我们一起学习了Streamlit中三个强大的媒体组件。我们掌握了如何使用 st.image() 嵌入并自定义图片,使用 st.audio() 添加音频播放功能,以及使用 st.video() 嵌入交互式视频。这些组件极大地简化了在Web应用中集成多媒体内容的过程,只需几行代码即可实现专业的效果。掌握它们,能让你的Streamlit应用更加生动和富有表现力。

008:Streamlit 基础交互组件 🎛️

在本节课中,我们将学习 Streamlit 中的一些基础交互组件。这些组件能让你的网页应用与用户进行互动,是构建动态应用的核心。

我们将从复选框开始,然后逐一学习单选按钮按钮下拉选择框多选下拉框。每个组件都有其独特的属性和用途,我们将通过简单的代码示例来理解它们的工作原理。


复选框 ✅

首先,我们来看看复选框。复选框允许用户在两种状态(选中/未选中)之间切换。

在 Streamlit 中,我们使用 st.checkbox 来创建复选框。它有几个重要的参数:

  • label:复选框旁边显示的标签文本。
  • value:复选框的默认状态,True 为选中,False 为未选中。
  • on_change:当复选框状态改变时触发的回调函数。
  • key:为复选框分配一个唯一的标识符,用于在会话状态中访问它。

以下是创建和使用复选框的代码示例:

import streamlit as st

# 创建一个复选框,默认未选中
cb_state = st.checkbox('这是一个复选框', value=False)

# 根据复选框的状态显示不同内容
if cb_state:
    st.write('你好!')
else:
    pass  # 什么都不做

运行上面的代码,你会看到一个复选框。勾选它,页面会显示“你好!”;取消勾选,文字消失。

使用回调函数和会话状态

我们可以为复选框添加一个回调函数,并在函数内部通过 key 访问其状态。

import streamlit as st

# 定义回调函数
def change():
    # 通过 key 访问复选框的当前值
    current_state = st.session_state.my_checker
    print(f"复选框状态已改变为:{current_state}")

![](https://github.com/OpenDocCN/cs-notes-pt1-zh/raw/master/docs/py-stlt-tut/img/795160f2c71b7ef41e7282933ac2ec83_5.png)

![](https://github.com/OpenDocCN/cs-notes-pt1-zh/raw/master/docs/py-stlt-tut/img/795160f2c71b7ef41e7282933ac2ec83_6.png)

# 创建带 key 和回调函数的复选框
st.checkbox('带回调的复选框',
            value=True,
            on_change=change, # 状态改变时调用 change 函数
            key='my_checker')

每当用户点击这个复选框,控制台就会打印出其最新的状态。


单选按钮 🔘

上一节我们介绍了复选框,它适合二元选择。本节中我们来看看单选按钮,它允许用户从一组互斥的选项中选择一个。

使用 st.radio 创建单选按钮。其核心参数是 label(问题或标题)和 options(一个包含所有选项的列表或元组)。

以下是创建单选按钮的示例:

import streamlit as st

# 创建一个单选按钮
radio_choice = st.radio(
    '你住在哪个国家?', # 标签/问题
    options=('美国', '英国', '加拿大') # 选项元组
)

# 显示用户的选择
st.write(f'你选择了:{radio_choice}')

页面上会出现一个问题“你住在哪个国家?”,下面有三个选项。用户只能选择其中一个,被选中的选项会通过 st.write 显示出来。


按钮 🖱️

任何网页应用都离不开按钮。按钮用于触发一个特定的动作。

在 Streamlit 中,我们使用 st.button 创建按钮。最重要的参数是 label(按钮上显示的文本)和 on_click(点击按钮时触发的回调函数)。

以下是按钮的示例:

import streamlit as st

# 定义按钮点击的回调函数
def button_clicked():
    print('按钮被点击了!')

# 创建一个按钮
st.button('点击我',
          on_click=button_clicked) # 点击时调用 button_clicked 函数

点击这个按钮,控制台会输出“按钮被点击了!”。注意:在 Streamlit 中,任何交互组件(如按钮、下拉框)被操作后,整个脚本都会从上到下重新运行一次。这有时会导致非预期的输出,我们将在后续关于表单的教程中解决这个问题。


下拉选择框 📥

接下来,我们学习下拉选择框。它允许用户从一个下拉列表中选择一个选项,比单选按钮更节省空间。

使用 st.selectbox 创建下拉选择框。它同样需要 labeloptions 参数。

以下是创建下拉选择框的示例:

import streamlit as st

# 创建一个下拉选择框
car = st.selectbox(
    '你最喜欢的汽车品牌是?',
    options=('奥迪', '宝马', '法拉利')
)

# 显示选择结果
st.write(f'你最喜欢的汽车是:{car}')

运行后,页面上会出现一个下拉菜单,默认显示第一个选项“奥迪”。点击下拉箭头,可以选择“宝马”或“法拉利”,选择结果会实时显示在下方。


多选下拉框 📦

最后,我们来看看多选下拉框。它与普通下拉框类似,但允许用户同时选择多个选项。

使用 st.multiselect 创建多选下拉框。参数 labeloptions 是必需的。

以下是多选下拉框的示例:

import streamlit as st

![](https://github.com/OpenDocCN/cs-notes-pt1-zh/raw/master/docs/py-stlt-tut/img/795160f2c71b7ef41e7282933ac2ec83_19.png)

# 创建一个多选下拉框
brands = st.multiselect(
    '你最喜欢的科技品牌是?(可多选)',
    options=('微软', '苹果', '亚马逊', '甲骨文')
)

# 显示所有被选中的选项
st.write(f'你选择的品牌有:{brands}')

页面上会出现一个下拉框,点击后可以勾选多个品牌。所有被选中的品牌会以一个列表的形式显示在下方。你可以通过每个选项旁边的“×”图标来取消选择。


本节课中我们一起学习了 Streamlit 的五个基础交互组件:复选框单选按钮按钮下拉选择框多选下拉框。我们了解了它们的基本用法、关键参数(如 label, options, on_change, on_click, key),并通过代码示例看到了它们如何工作。

掌握这些组件是构建交互式 Streamlit 应用的第一步。请尝试修改代码中的参数,例如更改标签、选项或回调函数的内容,以加深理解。在下一节课中,我们将学习如何使用表单来更好地组织这些交互组件,并解决组件交互导致整个应用重运行的问题。

009:Streamlit文件上传器组件

在本教程中,我们将学习如何使用Streamlit框架向你的Web应用程序上传文件。我们将涵盖上传单个文件(如图像、视频)以及上传多个文件的方法。

准备工作 🛠️

首先,我们需要启动一个Streamlit应用程序。在终端中运行以下命令:

streamlit run app.py

这将打开一个新的本地服务器。我们将从一个干净的Web应用界面开始,只保留一个标题。

import streamlit as st

st.title('文件上传演示')
st.markdown('---')

上传单个文件 📤

上一节我们设置了基础应用界面,本节中我们来看看如何使用st.file_uploader组件上传单个文件。

以下是上传单个图像文件的核心步骤:

  1. 使用st.file_uploader创建一个文件上传器。
  2. 通过label参数设置上传器的提示文字。
  3. 通过type参数限制可上传的文件类型(扩展名)。
  4. 检查文件是否成功上传(不为None)。
  5. 使用st.image显示上传的图像。

对应的核心代码如下:

# 创建文件上传器,限制为PNG和JPG格式的图像
uploaded_image = st.file_uploader(
    label='请上传一张图片',
    type=['png', 'jpg', 'jpeg']
)

# 检查文件是否已上传
if uploaded_image is not None:
    # 显示上传的图片
    st.image(uploaded_image)

运行此代码后,网页上会出现一个上传区域。你可以通过“浏览文件”按钮选择图片,图片上传后会立即显示在页面上。移除已选文件,图片也会随之消失。

上传其他类型文件 🎬

学会了上传图片后,我们可以用同样的方法上传其他类型的文件,例如视频。

只需修改type参数和对应的显示函数即可。以下是上传MP4视频文件的代码:

# 创建文件上传器,限制为MP4格式的视频
uploaded_video = st.file_uploader(
    label='请上传一个视频',
    type='mp4'  # 单个类型可以直接用字符串
)

![](https://github.com/OpenDocCN/cs-notes-pt1-zh/raw/master/docs/py-stlt-tut/img/ff9accb04cc771219a0bcc1315668a38_13.png)

if uploaded_video is not None:
    # 显示上传的视频
    st.video(uploaded_video)

注意:上传视频时,必须使用st.video()来显示,使用st.image()会导致错误。

上传多个文件 📂

有时我们需要一次性上传多个文件。st.file_uploader组件也支持这个功能。

要实现多文件上传,只需在st.file_uploader中设置accept_multiple_files=True参数。上传后,我们会得到一个文件列表,然后通过循环来处理每一个文件。

以下是上传并显示多张图片的完整代码:

# 创建支持多文件上传的组件
uploaded_images = st.file_uploader(
    label='请上传多张图片',
    type=['png', 'jpg', 'jpeg'],
    accept_multiple_files=True  # 启用多文件选择
)

# 检查列表是否不为空
if uploaded_images:
    # 遍历列表中的每一张图片
    for image in uploaded_images:
        st.image(image)

运行代码后,在文件选择器中按住Ctrl(Windows/Linux)或Command(Mac)键即可选择多个文件。所有选中的图片会依次显示在网页上。

总结 📝

本节课中我们一起学习了Streamlit文件上传器st.file_uploader的核心用法。

我们掌握了:

  • 上传单个文件:通过type参数指定文件类型,并使用对应的st.imagest.video函数进行显示。
  • 上传多个文件:通过设置accept_multiple_files=True参数,并循环处理返回的文件列表。

这个组件功能强大且灵活,是构建交互式数据上传和内容管理应用的基石。

010:更多交互式组件

在本节课中,我们将继续学习 Streamlit 的交互式组件。我们将重点介绍滑块、文本输入框、文本域、日期输入和时间输入这几个常用组件。通过本课的学习,你将能够为你的应用添加更多与用户交互的方式。

上一节我们介绍了文件上传器,本节中我们来看看其他几种实用的交互组件。

滑块组件 🎚️

滑块是几乎所有 Python 框架中都非常重要的组件。首先,我们来创建一个滑块。

在 Streamlit 中,创建滑块有两种方法:st.sliderst.select_slider。它们之间存在区别。本节我将解释 st.slider 的用法,而 st.select_slider 的工作原理和区别将作为你的课后作业。

以下是创建一个基本滑块的代码:

import streamlit as st

value = st.slider(
    label='这是一个滑块',  # 滑块的标题
    min_value=50,        # 最小值
    max_value=150,       # 最大值
    value=70,            # 默认值
    step=1               # 步长
)
st.write(f'当前滑块的值是:{value}')
  • label:定义了滑块的标题。
  • min_valuemax_value:分别定义了滑块的最小值和最大值,决定了滑块的左右边界。
  • value:定义了滑块的默认初始值。
  • step:定义了滑块移动时的步长。

运行上述代码,你会看到一个滑块。拖动滑块,下方显示的数字会实时变化。滑块组件也支持 on_change 回调函数,用于在值改变时触发特定操作。

理解了滑块的基本用法后,接下来我们看看如何从用户那里获取文本输入。

文本输入组件 📝

从用户处获取输入是应用开发中的常见需求,文本输入框是最常用的组件之一。

Streamlit 提供了两种文本输入组件:st.text_inputst.text_area

  • st.text_input:适用于获取简短的输入,例如标题。
  • st.text_area:适用于获取段落或描述性长文本。

首先,我们来看 st.text_input

import streamlit as st

course_title = st.text_input(
    label='请输入课程标题',
    max_chars=60,          # 最大字符数限制
    value='默认标题'        # 默认文本
)
st.write(f'您输入的标题是:{course_title}')
  • max_chars:可以限制用户输入的最大字符数。输入框下方会显示计数。
  • value:可以设置输入框的默认文本。

用户输入内容后,通常需要按下 Enter 键来提交(应用)输入。

接下来,我们看看用于获取长文本的 st.text_area

import streamlit as st

course_desc = st.text_area(
    label='请输入课程描述',
    height=150             # 设置文本域的高度
)
st.write(f'课程描述:{course_desc}')

st.text_area 的显示区域比 st.text_input 更大。一个关键区别是换行方式:在文本域中,直接按 Enter 键即可换行。若想提交整个文本域的内容,在 Windows/Linux 上需要按住 Ctrl 键再按 Enter,在 Mac 上则是 Cmd + Enter。应用会根据你的操作系统显示相应的提示。

学会了处理文本输入,我们再来看看如何获取日期和时间信息。

日期与时间输入 📅⏰

Streamlit 提供了专门的组件来获取日期和时间输入,这在需要用户选择特定日期或设定时间的场景中非常有用。

首先是日期输入组件 st.date_input

import streamlit as st

reg_date = st.date_input('请选择注册日期')
st.write(f'您选择的注册日期是:{reg_date}')

运行后会显示一个日期选择器。用户可以通过下拉菜单选择年、月、日,也可以使用两侧的箭头快速切换月份。

然后是时间输入组件 st.time_input

import streamlit as st

alarm_time = st.time_input('请设置闹钟时间')
st.write(f'闹钟设定在:{alarm_time}')

这个组件会显示一个时间选择器,默认是当前时间。用户可以方便地选择小时、分钟和秒。这在创建闹钟、计时器等功能时非常实用。

本节课中我们一起学习了 Streamlit 的五个核心交互组件:滑块、文本输入框、文本域、日期选择器和时间选择器。你学会了如何创建它们、配置其基本属性,并理解其适用场景。合理运用这些组件,可以极大地增强你应用的交互性和用户体验。在下一节课中,我们将探索 Streamlit 的更多新功能。

011:带进度条的计时器应用

在本节课中,我们将学习如何在 Streamlit 应用中创建和使用进度条。我们将从一个简单的进度条开始,逐步构建一个功能完整的计时器应用,该应用允许用户设置时间,并使用进度条直观地显示时间的流逝。

概述

进度条是向用户展示任务完成进度的常用UI组件。在 Streamlit 中,我们可以使用 st.progress 轻松创建进度条。本节课,我们将首先演示一个基础进度条,然后将其与时间输入控件结合,创建一个交互式的计时器应用。

创建基础进度条

首先,我们创建一个最简单的进度条。在 Streamlit 中,使用 st.progress 函数即可创建进度条,其进度值是一个介于 0 到 100 之间的整数。

import streamlit as st

progress_bar = st.progress(0)  # 创建一个初始进度为0的进度条

运行上述代码,你将看到一个进度为 0% 的进度条。

接下来,我们让进度条动起来。我们将使用一个循环,在 10 步内将进度从 0% 增加到 100%。为了让进度变化可见,我们使用 time.sleep 函数在每一步之间暂停。

import streamlit as st
import time

progress_bar = st.progress(0)  # 创建进度条

for i in range(10):
    # 计算当前进度百分比。i从0到9,所以需要加1
    progress = (i + 1) * 10
    progress_bar.progress(progress)  # 更新进度条
    time.sleep(1)  # 暂停1秒

运行这段代码,你将看到进度条每隔一秒增加 10%,直到 100%。

构建交互式计时器应用

上一节我们介绍了基础进度条,本节中我们来看看如何将其与用户输入结合,创建一个可以自定义时长的计时器。

添加时间输入控件

我们将使用 st.time_input 让用户选择计时器的时长。为了设置默认值,我们需要使用 datetime.time 对象。

import streamlit as st
from datetime import time as ts  # 导入datetime.time并重命名为ts,避免与time模块冲突

# 创建时间输入控件,默认值为 00:00:00
selected_time = st.time_input("设置计时器", value=ts(0, 0, 0))

处理用户输入并启动进度条

我们需要检查用户是否设置了时间。如果时间仍为默认值(00:00:00),则提示用户设置;否则,开始执行计时功能。

import streamlit as st
from datetime import time as ts
import time

selected_time = st.time_input("设置计时器", value=ts(0, 0, 0))

# 将时间对象转换为字符串,以便比较
if str(selected_time) == "00:00:00":
    st.write("请设置计时器")
else:
    st.write("正在执行计时功能...")
    # 后续将在这里添加进度条逻辑

将时间转换为秒数

time.sleep 函数接受以秒为单位的参数。因此,我们需要一个函数将用户选择的“时:分:秒”格式的时间转换为总秒数。

以下是转换函数:

def time_to_seconds(time_value):
    """
    将 datetime.time 对象转换为总秒数。
    参数:
        time_value (datetime.time): 输入的时间对象。
    返回:
        int: 总秒数。
    """
    # 将时间拆分为小时、分钟、秒
    hours = time_value.hour
    minutes = time_value.minute
    seconds = time_value.second

    # 计算总秒数
    total_seconds = (hours * 3600) + (minutes * 60) + seconds
    return total_seconds

整合进度条与计时器

现在,我们将所有部分整合起来。当用户设置时间后,我们将总时长(秒)平均分成 100 份,每份代表进度条的 1%。在循环中,每完成一份,就暂停相应的时间,并更新进度条。

同时,为了动态显示当前进度百分比,我们将使用 st.empty 创建一个占位符,然后在循环中更新其内容。

import streamlit as st
from datetime import time as ts
import time

def time_to_seconds(time_value):
    hours = time_value.hour
    minutes = time_value.minute
    seconds = time_value.second
    total_seconds = (hours * 3600) + (minutes * 60) + seconds
    return total_seconds

# 用户界面
st.title("⏱️ 带进度条的计时器")

selected_time = st.time_input("设置计时器时长", value=ts(0, 0, 0))

if str(selected_time) == "00:00:00":
    st.info("请在上方设置计时器时长。")
else:
    # 转换时间为秒
    total_seconds = time_to_seconds(selected_time)
    st.write(f"计时器已设置为 {total_seconds} 秒。")

    # 创建进度条和状态文本占位符
    progress_bar = st.progress(0)
    status_text = st.empty()

    # 计算每一步的等待时间(总秒数 / 100步)
    step_duration = total_seconds / 100.0

    # 执行进度更新
    for percent_complete in range(101):  # 从0到100
        progress_bar.progress(percent_complete)  # 更新进度条
        status_text.text(f"{percent_complete}% 已完成")  # 更新状态文本
        time.sleep(step_duration)  # 等待相应时间

    status_text.text("✅ 计时完成!")

运行此应用,选择一个时间(例如 15 秒),进度条将平滑地在指定时间内从 0% 填充到 100%,并实时显示百分比。

总结

本节课中我们一起学习了 Streamlit 中进度条的核心用法。我们首先创建了一个基础的进度条,然后将其与 st.time_input 控件结合,构建了一个交互式的计时器应用。关键步骤包括:

  1. 使用 st.progress 创建和更新进度条。
  2. 使用 st.time_input 获取用户输入的时间。
  3. 编写函数将时间对象转换为秒数。
  4. 使用 st.empty 占位符动态更新文本内容。
  5. 通过循环和 time.sleep 控制进度更新的节奏。

通过这个项目,你掌握了如何将不同的 Streamlit 组件组合起来,创建具有动态反馈的用户界面。

012:Streamlit 表单与列布局

在本节课中,我们将学习 Streamlit 中的两个重要组件:表单列布局。表单组件允许我们在应用中创建交互式表单,例如用户注册或登录界面。列布局组件则能将页面屏幕划分为多个列,以便更灵活地排列和展示不同的控件。我们将结合这两个组件,创建一个完整的用户注册表单。

创建表单的两种方法

Streamlit 提供了两种创建表单的方法。第一种方法是先创建一个表单对象,然后向该对象添加控件。第二种方法是使用 with 语句来定义表单的范围。接下来,我们将详细介绍这两种方法。

方法一:使用表单对象

首先,我们创建一个表单对象,并为其指定一个唯一的键。然后,通过该对象添加控件。

import streamlit as st

st.markdown("<h1>用户注册</h1>", unsafe_allow_html=True)

# 创建表单对象
form1 = st.form(key='form1')

# 在表单对象中添加一个文本输入框
form1.text_input(label="First Name")

# 为表单添加一个提交按钮
form1.form_submit_button(label="提交")

注意:每个表单都必须包含一个提交按钮,否则 Streamlit 会报错。

方法二:使用 with 语句

第二种方法是使用 with 语句。在 with 代码块内定义的所有控件都会自动归属于该表单。

import streamlit as st

st.markdown("<h1>用户注册</h1>", unsafe_allow_html=True)

# 使用 with 语句创建表单
with st.form(key='form2'):
    st.text_input(label="First Name")
    st.form_submit_button(label="提交")

以上两种方法都能成功创建一个包含输入框和提交按钮的基本表单。

使用列布局优化表单

在许多注册表单中,我们经常看到“名”和“姓”并排显示。为了实现这种布局,我们可以使用 Streamlit 的 columns 组件将表单区域分割成多个列。

以下是具体步骤:

  1. 使用 st.columns(num) 创建指定数量的列,该方法会返回一个列对象的列表。
  2. 在对应的列对象上调用控件方法,控件就会显示在该列中。
import streamlit as st

st.markdown("<h1>用户注册</h1>", unsafe_allow_html=True)

with st.form(key='registration_form'):
    # 创建两列
    col1, col2 = st.columns(2)

    # 在第一列中添加“名”输入框
    with col1:
        st.text_input(label="名")

    # 在第二列中添加“姓”输入框
    with col2:
        st.text_input(label="姓")

    # 在列布局下方添加其他输入项
    st.text_input(label="邮箱地址")
    st.text_input(label="密码", type="password")
    st.text_input(label="确认密码", type="password")

    st.form_submit_button(label="注册")

通过以上代码,我们创建了一个布局清晰、包含多个输入字段的用户注册表单。“名”和“姓”并排显示,其他字段则依次排列在下方的完整宽度区域。

总结

本节课中,我们一起学习了 Streamlit 中表单和列布局的使用。我们掌握了创建表单的两种方法,并学会了如何利用 columns 组件将页面分割,从而创建出更美观、更符合常见设计模式的表单界面。在下一节课中,我们将为这个表单添加数据验证和提交处理功能。

013:Streamlit 表单 II 🎛️

在本节课中,我们将继续学习 Streamlit 表单,为其添加更多功能,包括表单布局优化、输入验证以及表单提交后的自动清空。

概述

上一节我们介绍了 Streamlit 表单的基本创建方法。本节中,我们将进一步完善用户注册表单,学习如何居中显示标题、添加日期输入字段、验证用户输入以及控制表单提交后的行为。

居中显示标题

首先,我们注意到“用户注册”标题没有居中。由于我们使用了 st.markdown 来显示标题,因此可以利用 HTML 和 CSS 样式来调整其对齐方式。

以下是实现标题居中的代码:

st.markdown('<h1 style="text-align: center;">用户注册</h1>', unsafe_allow_html=True)

这段代码通过内联 CSS 样式 text-align: center; 将标题文本居中显示。

扩展表单:添加日期输入

现在,让我们回到表单本身。我们需要为用户添加出生日期的输入字段。我们将把日期分为日、月、年三个部分,并使用 st.columns 将它们并排布局。

以下是创建三个并列输入框的步骤:

  1. 首先,使用 st.columns 创建三个等宽的列容器。
  2. 然后,在每个列容器中分别创建一个文本输入框。

具体代码如下:

# 创建三列
col1, col2, col3 = st.columns(3)

# 在第一列中添加“日”输入框
with col1:
    day = st.text_input("日")

# 在第二列中添加“月”输入框
with col2:
    month = st.text_input("月")

# 在第三列中添加“年”输入框
with col3:
    year = st.text_input("年")

通过这种方式,日、月、年三个输入框将水平排列,使表单布局更加紧凑美观。

为表单添加验证功能

接下来,我们需要为表单的提交按钮添加逻辑,以验证用户是否填写了必填字段。

以下是实现输入验证的步骤:

  1. 首先,获取“提交”按钮的状态。当用户点击按钮时,其状态会变为 True
  2. 然后,检查“名”和“姓”输入框是否为空。
  3. 根据检查结果,使用 Streamlit 的内置消息函数向用户提供反馈。

具体代码如下:

# 获取“名”和“姓”的输入值
first_name = st.text_input("名")
last_name = st.text_input("姓")

![](https://github.com/OpenDocCN/cs-notes-pt1-zh/raw/master/docs/py-stlt-tut/img/9139ac30a5db0aaed7c5c96672a83a16_8.png)

![](https://github.com/OpenDocCN/cs-notes-pt1-zh/raw/master/docs/py-stlt-tut/img/9139ac30a5db0aaed7c5c96672a83a16_9.png)

![](https://github.com/OpenDocCN/cs-notes-pt1-zh/raw/master/docs/py-stlt-tut/img/9139ac30a5db0aaed7c5c96672a83a16_10.png)

![](https://github.com/OpenDocCN/cs-notes-pt1-zh/raw/master/docs/py-stlt-tut/img/9139ac30a5db0aaed7c5c96672a83a16_11.png)

# 获取“提交”按钮的状态
submitted = st.form_submit_button("提交")

![](https://github.com/OpenDocCN/cs-notes-pt1-zh/raw/master/docs/py-stlt-tut/img/9139ac30a5db0aaed7c5c96672a83a16_12.png)

if submitted:
    # 检查必填字段是否为空
    if first_name == "" or last_name == "":
        # 如果为空,显示警告信息
        st.warning("请填写以上字段。")
    else:
        # 如果已填写,显示成功信息
        st.success("提交成功!")

这段代码确保了用户在提交表单前必须填写“名”和“姓”字段,否则会收到提示。

表单提交后自动清空

默认情况下,提交表单后,已输入的内容会保留在输入框中。有时,我们希望提交后能自动清空表单,以便进行下一次输入。

Streamlit 的 st.form 组件提供了一个 clear_on_submit 参数来实现此功能。

以下是启用自动清空功能的代码:

# 创建表单,并设置提交后清空内容
with st.form(key='my_form', clear_on_submit=True):
    first_name = st.text_input("名")
    last_name = st.text_input("姓")
    submitted = st.form_submit_button("提交")
    # ... 其余验证逻辑

clear_on_submit 参数设置为 True 后,每当用户点击提交按钮,表单内的所有输入控件都会被重置为空状态。

总结

本节课中我们一起学习了如何增强 Streamlit 表单的功能。我们掌握了使用 CSS 样式居中标题、利用 st.columns 创建多列布局以添加日期字段、通过条件判断实现表单输入验证,以及使用 clear_on_submit 参数在提交后自动清空表单内容。这些技巧能帮助你创建出交互性更强、用户体验更好的数据输入界面。

015:Streamlit 网页图片爬取应用介绍

在本节课中,我们将学习如何使用 Streamlit 构建一个网页图片爬取应用。这个应用允许用户输入关键词,并展示与关键词相关的图片,同时提供图片下载功能。

应用功能概述

我们将要构建的应用界面包含一个图标、一个标题和一个搜索栏。用户可以在搜索栏中输入关键词,例如“cars”,点击搜索按钮后,应用会展示与“cars”相关的图片。每张图片下方都有一个下载按钮,点击该按钮会跳转到该图片的原始下载页面。

应用界面与操作演示

以下是应用界面的示意图。

用户可以在搜索框中输入关键词。

输入关键词并点击搜索后,应用会展示相关的图片。例如,搜索“cars”会得到一系列汽车图片。

每张图片下方都有一个“Download”按钮。点击此按钮,浏览器会跳转到该图片的原始下载页面。在该页面上,用户可以点击“Download for free”等按钮来下载原图。

学习路径指引

上一节我们介绍了应用的整体功能,本节中我们来看看具体的实现目标。如果您想学习如何开发这个应用,请跟随本节的后续教程内容。

我们将在接下来的教程中逐步实现这个应用的所有功能。

本节总结

本节课中我们一起学习了计划构建的 Streamlit 网页图片爬取应用的核心功能:通过关键词搜索图片并实现下载跳转。在下一节教程中,我们将开始动手编写代码。

016:Streamlit 网页爬虫 - 目标网站结构分析 🕸️

在本节课中,我们将开始开发一个基于 Streamlit 的网页爬虫。我们将以 Unsplash 这个真实的网站为目标,学习如何爬取其上的图片并展示在我们的 Streamlit 应用中。首先,理解目标网站的结构至关重要。本节我们将详细分析 Unsplash 网站的 URL 构成和 HTML 结构。

分析目标网站 URL

我们首先从目标网站的 URL 开始。Unsplash 的网址是 unsplash.com

当我们在网站上搜索内容时,URL 会发生变化。例如,搜索关键词 trees 后,URL 变为:

https://unsplash.com/s/photos/trees

观察这个 URL,我们可以发现几个关键部分:

  • s/photos/:这代表了网站的一个筛选器。Unsplash 主要提供三个筛选器:photos(图片)、collections(合集)和 users(用户)。我们主要关注 photos 筛选器。
  • trees:这是我们搜索的关键词。

因此,在我们的应用中,我们将请求用户输入一个关键词,并用它替换 URL 中的 trees 部分。例如,如果用户输入 plants,我们构造的 URL 将是:

https://unsplash.com/s/photos/plants

分析网页 HTML 结构

为了爬取图片,我们需要了解图片在网页 HTML 代码中的位置。以下是分析步骤:

  1. 在浏览器中打开 Unsplash 并搜索一个关键词(如 plants)。
  2. 右键点击页面,选择“检查”或“审查元素”,打开开发者工具。
  3. 我们将从 <body> 标签开始,逐步定位到图片元素。

以下是定位图片的核心路径:

  • 首先,找到包含所有搜索结果行的容器。这个容器通常是一个 <div> 元素,并具有特定的类名。例如,它可能类似于 MorZF
    • 我们将通过这个类名来定位容器。
  • 在这个容器内部,包含了多个代表行的 <div> 元素。每一行又包含多个 <figure> 元素,每个 <figure> 对应一张图片卡片。
    • 我们将在这个容器内搜索所有的 <figure> 标签。
  • 在每个 <figure> 标签内部,我们需要找到实际的图片 <img> 标签。这个 <img> 标签通常也带有一个特定的类名,例如 YVj9w
    • 我们将在每个 <figure> 内搜索具有此类名的 <img> 标签。
  • 最后,在目标 <img> 标签上,有一个名为 srcset 的属性。这个属性的值包含了图片的实际源地址(URL)。
    • 我们将提取 srcset 属性的值来获得图片链接。

核心定位逻辑可以用以下伪代码描述:

# 1. 构建搜索URL
base_url = "https://unsplash.com/s/photos/"
keyword = "用户输入的关键词"
search_url = base_url + keyword

# 2. 获取网页内容并解析
# 3. 定位容器
container = soup.find('div', class_='MorZF') # 类名需根据实际情况调整

# 4. 在容器内定位所有图片卡片
figures = container.find_all('figure')

# 5. 遍历每个卡片,定位图片标签并提取链接
for figure in figures:
    img_tag = figure.find('img', class_='YVj9w') # 类名需根据实际情况调整
    if img_tag and 'srcset' in img_tag.attrs:
        image_url = img_tag['srcset']
        # 处理 image_url 用于显示

总结

本节课中,我们一起学习了如何为网页爬虫项目分析目标网站的结构。我们掌握了以下关键点:

  1. URL 构造:理解了如何根据用户输入的关键词动态生成 Unsplash 的搜索 URL,其模式为 https://unsplash.com/s/photos/{关键词}
  2. HTML 结构分析:通过开发者工具,我们逐步分析了网页的 DOM 结构,找到了从外层容器到具体图片元素的完整路径。
  3. 数据定位策略:确定了通过特定的 HTML 标签(如 <div><figure>)和类名来定位元素,并通过提取 <img> 标签的 srcset 属性来获取图片的真实地址。

下一节,我们将基于本节课的分析,开始动手编写 Streamlit 爬虫应用,实现自动抓取和显示 Unsplash 图片的功能。

017:Streamlit 网页爬虫 - 准备 HTML Soup

概述

在本节课中,我们将开始使用 Streamlit 编写一个网页爬虫应用。我们将学习如何发送网络请求、解析 HTML 内容,并提取网页中的特定元素。


创建项目文件

首先,我们需要创建一个新的 Python 文件。

以下是创建步骤:

  1. 创建一个新文件。
  2. 将其命名为 scrapper.py

导入必要库

编写应用的第一步是导入所需的库。

我们将导入以下库:

  • streamlit:用于构建 Web 应用界面。
  • requests:用于向目标网站发送 HTTP 请求。
  • BeautifulSoup:用于解析 HTML 内容。
import streamlit as st
import requests
from bs4 import BeautifulSoup

构建应用界面

上一节我们导入了必要的库,本节中我们来看看如何构建应用的用户界面。

我们将创建一个包含标题、输入框和提交按钮的简单表单。

# 创建应用标题
st.markdown("""
<h1 style='text-align: center;'>网页爬虫</h1>
""", unsafe_allow_html=True)

![](https://github.com/OpenDocCN/cs-notes-pt1-zh/raw/master/docs/py-stlt-tut/img/256fbc2f7b3cc0046ed07cff1b554401_5.png)

# 创建一个表单,用于接收用户输入
with st.form(key='search_form'):
    # 文本输入框,让用户输入搜索关键词
    keyword = st.text_input('请输入关键词')
    # 提交按钮
    search_submitted = st.form_submit_button('搜索')

发送网络请求与解析 HTML

在用户点击搜索按钮后,我们需要向目标网站发送请求并获取网页内容。

以下是处理逻辑:

  1. 检查搜索按钮是否被点击。
  2. 构建动态 URL,将用户输入的关键词插入到 URL 中。
  3. 使用 requests.get() 方法发送 GET 请求。
  4. 检查请求状态,确保成功获取网页。
  5. 使用 BeautifulSoup 解析返回的 HTML 内容。

if search_submitted:
    # 目标网站的基础URL,其中 `{keyword}` 将被替换为用户输入
    base_url = "https://unsplash.com/s/photos/{keyword}"
    # 格式化URL,插入用户关键词
    target_url = base_url.format(keyword=keyword)
    
    # 发送GET请求
    page = requests.get(target_url)
    # 打印状态码,200表示成功
    print(page.status_code)
    
    # 使用 BeautifulSoup 解析网页内容,指定解析器为 'lxml'
    soup = BeautifulSoup(page.content, 'lxml')

提取目标元素

成功解析 HTML 后,我们就可以查找和提取页面中的特定元素了。

我们将尝试查找所有具有特定 CSS 类名的 <div> 元素,这通常对应着图片的行或列容器。

    # 查找所有 class 为特定值的 div 元素
    rows = soup.find_all('div', class_='特定的类名')
    # 打印找到的元素数量
    print(len(rows))

注意:在实际操作中,你需要使用浏览器开发者工具检查目标网页,找到包含图片列表的容器的正确类名,并替换代码中的 '特定的类名'


总结

本节课中我们一起学习了如何使用 Streamlit 构建一个网页爬虫应用的基础框架。我们完成了以下步骤:

  1. 创建项目文件并导入库。
  2. 构建包含表单的用户界面。
  3. 响应用户操作,发送网络请求到目标网站。
  4. 使用 BeautifulSoup 解析返回的 HTML 内容。
  5. 初步尝试查找页面中的特定元素。

在下一节课中,我们将深入探索如何从这些元素中精确提取图片链接等信息。

018:Streamlit 网页爬虫 - 提取图片URL

概述

在本节课中,我们将继续开发网页爬虫。我们将学习如何从已定位的HTML标签中进一步搜索,并提取出图片的URL信息。

上一节我们成功定位了包含图片的<div>标签。本节中,我们来看看如何深入这些<div>标签,找到其中的<figure><img>标签,并最终获取图片的源地址。

从行中提取图片标签

首先,我们需要遍历之前找到的每一行(row)。在每一行中,通常包含多个<figure>标签,每个<figure>标签内又包含一个<img>标签。

以下是实现这一步骤的代码逻辑:

for row in rows:
    figures = row.find_all('figure')

这段代码对每个row元素使用.find_all('figure')方法,查找其内部所有的<figure>标签,并将结果存储在figures列表中。

限制提取的图片数量

考虑到一个页面可能包含大量图片,为了提升爬虫效率并简化教程,我们决定只提取每一行的前两张图片。

以下是限制循环次数的代码:

for i in range(2):
    figure = figures[i]

这里使用for i in range(2):循环,确保我们只处理figures列表中的前两个元素。

定位图片标签并获取属性

在获取到<figure>标签后,我们需要进一步定位其内部的<img>标签。由于每个<figure>标签内通常只有一个<img>标签,我们可以使用.find()方法。

以下是查找图片标签的代码:

image_tag = figure.find('img', class_='your-class-name')

代码中,figure.find('img', class_='your-class-name')用于在figure元素内查找具有特定类名的<img>标签。类名参数是可选的,但指定它可以使代码更健壮。

提取图片源地址

成功获取<img>标签对象后,我们的目标是提取其srcset属性,该属性包含了图片的URL地址。

以下是提取并打印srcset属性的代码:

print(image_tag.get('srcset'))
print("\n")

image_tag.get('srcset')用于获取标签的srcset属性值。打印一个空行print("\n")是为了让终端输出更清晰易读。

运行爬虫后,你将在终端看到类似以下的长字符串输出,这就是图片的srcset信息:

https://example.com/image1.jpg 1x, https://example.com/image1-2x.jpg 2x

总结

本节课中我们一起学习了网页爬虫开发的深入步骤。我们实现了从行元素中定位<figure>标签,限制处理图片的数量,精确查找到<img>标签,并最终成功提取了包含图片URL的srcset属性。在下一教程中,我们将学习如何解析这个长字符串,从中分离出我们真正需要的图片地址。

019:Streamlit 网页图片爬取与展示

在本节课中,我们将继续开发网页图片爬取应用。我们将学习如何从爬取的原始链接中提取出纯净的图片URL,并使用Streamlit的布局功能,将这些图片以两列的形式优雅地展示在网页上。

上一节我们完成了网页请求和初步的数据提取。本节中,我们来看看如何精确地提取图片链接并进行展示。

提取纯净图片URL

首先,我们需要从爬取到的原始数据中提取出可以直接用于显示图片的URL。观察原始链接,我们发现目标图片地址位于URL中问号 ? 之前的部分。

以下是提取逻辑:

  1. 使用字符串的 split 方法,以问号 ? 为分隔符,将原始URL分割。
  2. 分割后得到的列表的第一个元素,就是纯净的图片地址。

让我们在代码中实现这个逻辑。我们将打印原始链接以进行观察,然后应用分割方法。

# 假设 srcset 是包含原始图片链接的字符串
# 例如: “https://images.unsplash.com/photo-xxx?ixlib=rb-1.2.1...”

# 分割URL
split_list = srcset.split('?')
# 提取纯净的图片URL
pure_image_url = split_list[0]
print(pure_image_url)

运行代码并输入关键词(如“trees”)后,终端将成功输出一系列纯净的图片URL。这证明我们的提取逻辑是正确的。

在Streamlit中展示图片

成功提取URL后,下一步是在Streamlit应用界面上展示这些图片。我们将使用 st.image() 组件。

为了获得更好的布局效果,我们计划将图片分两列显示。这需要用到Streamlit的列布局功能。

以下是创建两列布局并展示图片的步骤:

  1. 使用 st.columns(2) 创建两个列对象。
  2. 在循环遍历图片URL列表时,根据索引的奇偶性,将图片分配到不同的列中显示。

初始实现代码如下:

import streamlit as st

# 假设 img_urls 是包含所有纯净图片URL的列表
col1, col2 = st.columns(2)

for i, img_url in enumerate(img_urls):
    if i % 2 == 0:  # 偶数索引图片放入第一列
        col1.image(img_url)
    else:           # 奇数索引图片放入第二列
        col2.image(img_url)

然而,直接运行上述代码可能会遇到布局问题,图片被限制在输入表单内部。为了解决这个问题,我们需要将布局和图片展示的代码移到表单 st.form 的外部。

优化布局与状态管理

调整代码结构后,图片得以正常显示在两列布局中。但是,当我们尝试搜索一个新的关键词(如“plants”)时,发现页面仍然显示上一次搜索(“trees”)的结果。

这是因为Streamlit会缓存组件的状态。要确保每次搜索都更新内容,我们需要引入一个“占位符”。

以下是解决方案:

  1. 在表单外部,使用 st.empty() 创建一个空的占位符。
  2. 在表单提交、获取到新数据后,对这个占位符进行操作。
  3. 将占位符划分为两列,并在其中填入新的图片内容。

这样,每次提交表单时,都会清空并重新填充占位符的内容,从而实现结果的动态更新。

最终的核心代码结构如下:

import streamlit as st

# 1. 在页面主体创建空占位符
image_placeholder = st.empty()

# 2. 创建输入表单
with st.form("search_form"):
    keyword = st.text_input("输入关键词")
    submitted = st.form_submit_button("搜索")

# 3. 表单提交后执行
if submitted:
    # ... (网页请求与数据提取代码,生成 img_urls 列表) ...

    # 4. 在占位符内创建两列并展示图片
    with image_placeholder.container():
        col1, col2 = st.columns(2)
        for i, img_url in enumerate(img_urls):
            if i % 2 == 0:
                col1.image(img_url)
            else:
                col2.image(img_url)

应用此结构后,无论是搜索“trees”还是“plants”,页面都能正确显示对应的图片,并且布局整洁美观。

本节课中我们一起学习了Streamlit网页图片爬取与展示的核心步骤。我们掌握了从复杂URL中提取纯净图片地址的方法,并学会了使用 st.columns 进行两列布局,以及通过 st.empty() 占位符来管理动态内容更新,从而构建出一个交互式的图片搜索展示应用。

在下一教程中,我们将为每张图片添加下载按钮,并实现点击后跳转到Unsplash官方下载页面的功能。

020:为图片添加下载按钮

在本节课中,我们将为上一节爬取的Unsplash图片添加下载按钮。我们将学习如何为每个图片创建独立的按钮,并解决按钮ID重复的问题,最终实现点击按钮后在新标签页中打开图片的下载页面。

概述

上一节我们成功地从Unsplash网站爬取了图片并显示在Streamlit应用中。本节中,我们来看看如何为每一张图片添加一个下载按钮,让用户能够方便地访问原图下载页面。

为图片列添加按钮

首先,我们需要在显示图片的列中,同时添加一个下载按钮。以下是实现步骤:

  1. 在图片下方,使用 st.button 函数创建一个按钮。
  2. 为按钮定义一个标签,例如“下载”。
  3. 将按钮的状态保存到一个变量中,以便后续判断用户是否点击了它。

初始的按钮创建代码如下:

btn = st.button(“下载”)
if btn:
    print(“按钮被按下”)

我们需要将此代码应用到每一列的图片显示逻辑中。

解决按钮ID重复错误

当我们运行上述代码时,会遇到一个错误:“duplicate widget ID”。这是因为Streamlit要求页面上的每一个小组件(Widget)都必须有一个唯一的键(key)。

为了解决这个问题,我们需要为每个按钮分配一个独一无二的 key 参数。

  1. 首先,使用 enumerate 函数来获取每一行数据的索引。enumerate 函数会返回两个值:索引和实际的数据值。
    for index, row in enumerate(rows):
    
  2. 然后,利用行索引 index 和列索引 i 来构造一个唯一的键。例如,第一行第一列的按钮键可以是 “00”,第一行第二列的按钮键可以是 “01”
    key = str(index) + str(i)
    
  3. 最后,在创建按钮时传入这个 key
    btn = st.button(“下载”, key=key)
    

提取图片下载链接

我们的目标是点击按钮后,在新标签页中打开图片在Unsplash上的下载页面。为此,我们需要从网页结构中提取出每张图片对应的详情页链接。

  1. 通过检查网页元素,我们发现图片被包裹在一个 <figure> 标签内,而该标签内包含一个 <a>(锚)标签。
  2. 这个 <a> 标签的 href(超链接)属性值,例如 /photos/abc123,就是图片详情页的相对路径。
  3. 我们需要在爬取图片 src 的同时,也爬取这个 href 值。
  4. 为了精确地定位到这个 <a> 标签,我们可能需要使用其 class 名称进行筛选,以避免抓取到其他无关的链接。

提取链接的代码逻辑如下:

anchor_tag = figure.find(“a”, class_=“特定的class名”)
image_url = anchor_tag[“href”]

整合功能并打开下载页面

现在,我们已经有了图片详情页的相对路径。接下来需要完成以下步骤:

  1. 将相对路径与Unsplash的域名拼接,形成完整的图片详情页URL。
    base_url = “https://unsplash.com”
    full_download_url = base_url + image_url
    
  2. 导入Python内置的 webbrowser 模块,它可以帮助我们在浏览器中打开新标签页。
    import webbrowser
    
  3. 在按钮的点击事件中,使用 webbrowser.open_new_tab(full_download_url) 来打开拼接好的完整URL。

此外,我们还需要修复一个应用逻辑上的小问题:将图片搜索和显示的逻辑判断条件,从“搜索表单按钮被点击”改为“用户输入的关键词不为空”,这样可以确保应用在各种交互下都能正确响应。

总结

本节课中我们一起学习了如何为Streamlit网页爬虫应用中的图片添加下载功能。我们解决了按钮ID重复的关键问题,学会了从网页中提取更深层的链接信息,并最终实现了点击按钮跳转至图片下载页面的完整流程。通过本节的学习,你的应用交互性得到了进一步增强。在接下来的教程中,我们将探索更多功能来完善这个网页爬虫。

021:页面配置 🛠️

在本教程中,我们将学习如何配置 Streamlit 网页应用的外观,包括修改页面标题、图标、布局等。

概述

st.set_page_config 是 Streamlit 提供的一个核心函数,它允许我们自定义应用页面的基本配置。通过它,我们可以轻松改变页面的标题、图标、布局等属性,使应用更具个性化。

配置页面标题与图标

首先,我们需要了解 st.set_page_config 函数必须放在所有其他 Streamlit 函数或属性的最顶部。

以下是设置页面标题和图标的基本语法:

st.set_page_config(
    page_title="你的页面标题",
    page_icon="🎯"
)
  • page_title:此参数用于设置浏览器标签页上显示的标题。
  • page_icon:此参数用于设置浏览器标签页上显示的图标。你可以使用表情符号(如 🎯)或图标名称。

例如,将标题设置为“网页抓取工具”,图标设置为笑脸表情:

st.set_page_config(
    page_title="网页抓取工具",
    page_icon="😊"
)

运行应用后,你将看到浏览器标签页的标题和图标已更新。

调整页面布局

除了标题和图标,我们还可以通过 layout 参数来调整页面的整体布局。

Streamlit 默认的布局是居中的("centered")。我们可以将其改为宽屏模式("wide"),让内容区域更宽。

以下是设置宽屏布局的代码:

st.set_page_config(
    page_title="网页抓取工具",
    page_icon="😊",
    layout="wide"
)

layout 设置为 "wide" 后,应用的内容区域将占据更多的水平空间。

其他配置选项

st.set_page_config 函数还提供了其他有用的配置选项:

  • initial_sidebar_state:此参数用于设置侧边栏的初始状态(例如 "expanded""collapsed")。当你的应用创建了侧边栏后,可以使用此参数进行控制。
  • menu_items:此参数允许你自定义应用右上角汉堡菜单中的项目。你可以修改“获取帮助”、“报告问题”和“关于”等菜单项的链接和文本。

例如,自定义“关于”菜单项:

st.set_page_config(
    page_title="网页抓取工具",
    page_icon="😊",
    layout="wide",
    menu_items={
        'About': '这是一个由Streamlit构建的网页抓取工具。'
    }
)

总结

本节课我们一起学习了如何使用 st.set_page_config 函数来配置 Streamlit 应用的基本页面属性。

我们掌握了如何:

  1. 使用 page_titlepage_icon 参数自定义页面标题和图标。
  2. 使用 layout 参数在“居中”和“宽屏”布局之间切换。
  3. 了解了 initial_sidebar_statemenu_items 等高级配置选项的用途。

通过合理配置这些选项,你可以让自己的 Streamlit 应用看起来更专业、更符合需求。

022:Streamlit 图像编辑器

概述

在本节课中,我们将学习如何使用 Streamlit 和 Pillow 库创建一个基础的图像编辑器。我们将从设置环境开始,逐步实现一个能够上传图片并显示其基本属性(如尺寸、模式和格式)的 Web 应用。


环境设置与库导入

首先,我们需要创建一个新的 Python 文件并导入必要的库。

创建一个名为 image_editor.py 的新文件。

接下来,导入 Streamlit 和 Pillow 库。Pillow 是 Python 的图像处理库,我们将使用它来操作图像。

import streamlit as st
from PIL import Image

如果尚未安装 Pillow,请在终端中运行以下命令进行安装:

pip install pillow


创建应用标题与界面

上一节我们导入了必要的库,本节中我们来看看如何构建应用的基本界面。

首先,为应用程序创建一个居中的标题。

st.markdown("<h1 style='text-align: center;'>图像编辑器</h1>", unsafe_allow_html=True)

然后,在标题下方添加一条分隔线,使界面更清晰。

st.markdown("---")

运行应用以检查界面是否正常显示。

streamlit run image_editor.py

添加文件上传功能

界面创建好后,我们需要让用户能够上传图片。以下是实现文件上传器的步骤。

我们将使用 st.file_uploader 创建一个文件上传组件,允许用户上传常见格式的图片。

uploaded_file = st.file_uploader("上传你的图片", type=['jpg', 'jpeg', 'png'])


处理上传的图像

文件上传器准备就绪后,我们需要处理用户上传的图像。以下是使用 Pillow 打开并检查图像属性的方法。

首先,检查用户是否已成功上传文件。如果已上传,则使用 Pillow 的 Image.open() 方法打开它。

if uploaded_file is not None:
    img = Image.open(uploaded_file)

为了在界面上显示图像信息,我们创建三个占位符,分别用于显示图像的尺寸、模式和格式。

size_placeholder = st.empty()
mode_placeholder = st.empty()
format_placeholder = st.empty()

然后,将获取到的图像属性填充到对应的占位符中。

size_placeholder.markdown(f"<h6>尺寸: {img.size}</h6>", unsafe_allow_html=True)
mode_placeholder.markdown(f"<h6>模式: {img.mode}</h6>", unsafe_allow_html=True)
format_placeholder.markdown(f"<h6>格式: {img.format}</h6>", unsafe_allow_html=True)

总结

本节课中我们一起学习了如何使用 Streamlit 和 Pillow 创建一个基础的图像编辑器。我们实现了以下功能:

  1. 设置开发环境并导入必要的库。
  2. 创建了一个带有标题和分隔线的 Web 应用界面。
  3. 添加了文件上传器,允许用户上传图片。
  4. 使用 Pillow 处理上传的图像,并在界面上显示其基本属性(尺寸、模式、格式)。

在下一节课中,我们将为这个图像编辑器添加更多功能,例如图像滤镜和调整选项。

023:Streamlit 图像编辑器 - 添加控件

在本节课中,我们将为图像编辑器添加调整大小、旋转和滤镜功能。我们将学习如何使用 Streamlit 的输入控件来获取用户参数,并准备好在后续课程中应用这些参数。

概述

我们将分步构建图像编辑器的用户界面。首先,我们会添加一个用于调整图像大小的区域,允许用户输入新的宽度和高度。接着,我们会添加一个用于旋转图像的区域。最后,我们将添加一个滤镜选择器,让用户可以为图像应用不同的视觉效果。

添加调整大小控件

上一节我们完成了图像上传和显示的基础功能。本节中,我们来看看如何让用户调整图像尺寸。

首先,我们使用 Markdown 添加一个标题,并将其居中显示。

st.markdown("<h2 style='text-align: center;'>Resizing</h2>", unsafe_allow_html=True)

接下来,我们需要让用户输入新的宽度和高度。我们将使用 st.number_input 控件来获取数值。

以下是创建宽度和高度输入框的代码:

width = st.number_input("Width")
height = st.number_input("Height")

保存并运行后,界面会显示两个输入框,但初始值为0。为了提供更好的用户体验,我们希望输入框的初始值显示为当前上传图像的原始尺寸。

我们可以使用 Pillow 库来获取图像的原始宽度和高度,并将其设置为输入框的默认值。

# 假设 img 是已打开的 Pillow 图像对象
width = st.number_input("Width", value=img.width)
height = st.number_input("Height", value=img.height)

现在,当用户上传图像后,宽度和高度输入框会自动填充该图像的原始尺寸,用户可以通过加减按钮来调整数值。

添加旋转控件

完成了尺寸调整功能后,现在我们来添加图像旋转功能。

我们同样先添加一个居中的标题。

st.markdown("<h2 style='text-align: center;'>Rotation</h2>", unsafe_allow_html=True)

然后,添加一个数字输入框,让用户输入旋转角度(以度为单位)。

degree = st.number_input("Degrees")

这样,用户界面就拥有了一个用于输入旋转角度的控件。

添加滤镜控件

最后,我们为编辑器添加滤镜功能。Pillow 库提供了多种内置的图像滤镜,如模糊、轮廓、细节增强等。

首先,添加滤镜部分的标题。

st.markdown("<h2 style='text-align: center;'>Filters</h2>", unsafe_allow_html=True)

接着,我们使用 st.selectbox 控件创建一个下拉选择框,列出可用的滤镜选项。

filters = st.selectbox("Filters", options=["None", "Blur", "Detail", "Emboss", "Smooth"])

这里我们提供了“无”、模糊、细节、浮雕和平滑几种滤镜选项。用户可以从下拉列表中选择他们想要应用的滤镜。

优化界面布局

在添加了所有控件后,界面可能显得有些拥挤。为了提升可读性,我们可以在最上方添加一个“信息”标题,并使用 st.empty() 创建一个占位符来更好地组织内容区域。

info = st.empty()
info.markdown("<h2 style='text-align: center;'>Information</h2>", unsafe_allow_html=True)
# 之后的其他控件代码放在这里

这样,界面结构就变得更加清晰:顶部是信息区,下方依次是调整大小、旋转和滤镜控件。

总结

本节课中我们一起学习了如何扩展 Streamlit 图像编辑器的用户界面。我们成功添加了三个核心功能区域:

  1. 调整大小:使用 st.number_input 获取目标宽度和高度,并智能地以原图尺寸作为默认值。
  2. 旋转:添加了用于输入旋转角度的控件。
  3. 滤镜:利用 st.selectbox 提供了多种图像滤镜选项供用户选择。

目前,这些控件已经就绪并显示在界面上。在下一节课中,我们将为这些控件添加实际的图像处理逻辑,使用户的输入能够真正改变所显示的图像。

024:Streamlit 图像编辑器

在本节课中,我们将为之前创建的图像编辑器界面中的各个控件添加实际功能。我们将实现图像的大小调整、旋转以及滤镜应用,并最终在应用中展示处理后的图像。

概述

我们将创建一个“提交”按钮,当用户点击它时,程序会读取所有控件的当前值(宽度、高度、旋转角度、滤镜),对上传的图像依次应用这些操作,并将最终结果显示在网页上。

实现提交按钮与图像处理

上一节我们创建了用于调整图像宽度、高度、旋转角度和滤镜的下拉菜单。本节中,我们来看看如何将这些设置应用到图像上。

首先,我们需要创建一个“提交”按钮。当用户点击此按钮时,程序将开始处理图像。

以下是创建按钮并检查其点击状态的代码:

s_b = st.button('Submit')

接下来,我们需要在按钮被点击后执行图像处理逻辑。我们将使用 Pillow 库来操作图像。

if s_b:
    # 处理图像

if 语句内部,我们将首先应用图像的尺寸调整和旋转操作。

    edited = image.resize((width, height)).rotate(degree)

这行代码做了两件事:

  1. image.resize((width, height)):将图像调整为指定的宽度和高度。
  2. .rotate(degree):将图像旋转指定的角度。

处理完成后,我们使用 st.image() 函数来显示编辑后的图像。

    st.image(edited)

现在,运行程序并上传一张图片。调整旋转角度为180度,然后点击“提交”按钮,可以看到图像成功旋转。

添加滤镜功能

图像的基本调整功能已经实现。现在,我们来为下拉菜单中的滤镜选项添加功能。

我们需要检查用户是否选择了滤镜。如果选择了“无”,则不应用任何滤镜;否则,根据选择应用对应的滤镜。

首先,需要从 PIL 库中导入滤镜模块。

from PIL.ImageFilter import *

然后,在处理逻辑中,在应用尺寸和旋转之后,添加滤镜判断逻辑。

    # 初始化 filtered_image 为仅经过尺寸和旋转处理的图像
    filtered_image = edited

    # 检查并应用滤镜
    if filters != 'None':
        if filters == 'Blur':
            filtered_image = edited.filter(BLUR)
        elif filters == 'Detail':
            filtered_image = edited.filter(DETAIL)
        elif filters == 'Smooth':
            filtered_image = edited.filter(SMOOTH)
        # 可以根据需要添加更多滤镜条件

最后,我们不再显示 edited 图像,而是显示应用了所有效果(包括滤镜)的 filtered_image

    st.image(filtered_image)

保存并重新运行程序。上传一张图片,选择“模糊”滤镜,然后点击“提交”。可以看到图像变得模糊了。尝试组合使用不同的旋转角度、尺寸和滤镜,观察最终效果。

总结

本节课中我们一起学习了如何为 Streamlit 图像编辑器添加核心功能。我们实现了通过一个提交按钮来触发处理流程,该流程会:

  1. 读取用户设置的宽度、高度和旋转角度。
  2. 使用 Pillow 库的 resizerotate 方法对图像进行基本编辑。
  3. 根据下拉菜单的选择,使用 filter 方法为图像应用不同的滤镜效果(如模糊、细节增强、平滑)。
  4. 最终使用 st.image() 将处理后的图像展示在网页上。

现在,你已经拥有了一个功能完整的简易图像编辑工具。在接下来的课程中,我们将探索 Streamlit 的更多组件和功能。

025:使用 Streamlit 构建 URL 缩短器

在本教程中,我们将学习如何使用 Python 的 Streamlit 库来创建一个 URL 缩短器应用程序。我们将从搭建基础界面开始,并集成一个第三方库来实现 URL 缩短功能。

创建项目文件与导入库

首先,我们需要创建一个新的 Python 文件。将其命名为 url_shortener.py

接下来,在文件的开头导入 Streamlit 库,我们通常使用 st 作为其别名。

import streamlit as st

构建基础用户界面

上一节我们导入了必要的库,本节中我们来看看如何构建应用的基础界面。

我们将首先创建一个居中对齐的标题。

st.markdown("<h1 style='text-align: center;'>URL Shortener</h1>", unsafe_allow_html=True)

接下来,我们需要创建一个表单来接收用户输入的 URL。我们将使用 Streamlit 的 st.form 方法。

以下是创建表单和输入框的步骤:

  1. 使用 st.form 创建一个表单对象。
  2. 在表单内添加一个文本输入框,用于接收用户输入的 URL。
  3. 在表单内添加一个提交按钮。
with st.form("url_form"):
    url = st.text_input("Enter URL Here")
    submit_button = st.form_submit_button("Shorten")

运行 streamlit run url_shortener.py 命令,你将看到一个带有输入框和按钮的简单界面。

集成 URL 缩短功能

现在界面已经就绪,我们需要实现 URL 缩短的核心逻辑。为此,我们将使用一个名为 pyshorteners 的 Python 库。

首先,在终端中安装这个库:

pip install pyshorteners

安装完成后,在代码文件顶部导入该库:

import pyshorteners as ps

pyshorteners 库中的 Shortener 类提供了多种缩短服务。我们将使用不需要 API 密钥的 TinyURL 服务。

在表单的提交逻辑中,我们实例化 Shortener 类并调用其 tinyurl.short 方法来缩短 URL。

if submit_button:
    shortener = ps.Shortener()
    shortened_url = shortener.tinyurl.short(url)
    print(shortened_url)

此时,当用户输入 URL 并点击提交后,缩短后的链接会打印在终端中。你可以复制该链接到浏览器中测试,确认其可以正确跳转到原始网站。

总结

本节课中我们一起学习了使用 Streamlit 创建 URL 缩短器应用的基础步骤。我们首先搭建了包含标题、输入框和按钮的用户界面,然后通过集成 pyshorteners 库实现了 URL 缩短的核心功能。目前,缩短后的链接会输出在终端。

在下一节课中,我们将改进这个应用,把缩短后的链接直接显示在网页上,并添加一个“复制到剪贴板”的按钮,以提升用户体验。

026:创建复制按钮与剪贴板操作 🚀

在本节课中,我们将继续开发URL短链接生成器应用。我们将学习两个核心功能:首先,在界面上显示生成的短链接;其次,创建一个复制按钮,以便用户一键将短链接复制到系统剪贴板。


在界面上显示短链接

上一节我们完成了短链接的生成逻辑,本节我们来看看如何将其优雅地展示给用户。我们将使用Streamlit的st.markdown组件,并应用HTML标签进行样式控制。

以下是实现步骤:

  1. 移除用于调试的print语句。
  2. 使用st.markdown来渲染短链接。
  3. st.markdown中,我们使用HTML的<h6>标签来定义标题样式,并通过unsafe_allow_html=True参数允许渲染HTML。
  4. 将生成的短链接变量(例如shortened_url)嵌入到HTML字符串中。

核心代码如下:

st.markdown(f'<h6 style="...">短链接: {shortened_url}</h6>', unsafe_allow_html=True)

运行应用后,输入一个长链接并点击缩短,生成的短链接就会以设定好的样式显示在页面上。


添加复制按钮

成功显示短链接后,下一步是让用户可以方便地复制它。我们将在短链接下方添加一个按钮。

以下是实现步骤:

  1. 在显示短链接的代码上方,可以添加一个标题(例如使用st.titlest.markdown<h3>标签)来明确区域。
  2. 使用st.button创建一个按钮,按钮文本设为“复制”。
  3. 为了获得更好的视觉效果,可以将标题的标签从<h6>调整为<h3>,并优化布局。

调整后的界面代码结构如下:

st.markdown('### 短链接生成器')
st.markdown(f'<h6 style="...">{shortened_url}</h6>', unsafe_allow_html=True)
copy_button = st.button('复制')


实现复制到剪贴板功能

现在,我们需要让复制按钮真正起作用。这里有一个关键点需要注意:如果我们的按钮位于一个st.form表单内,Streamlit的默认执行流程可能会阻止复制逻辑的触发。

为了解决这个问题,我们将使用按钮的on_click属性。这个属性允许我们在Streamlit重新运行整个脚本之前,就执行指定的函数。

以下是实现步骤:

  1. 安装库:我们将使用Python的pyperclip库来操作系统剪贴板。在终端中运行安装命令:

    pip install pyperclip
    

    安装后,需要重启VS Code或你的开发环境。

  2. 导入库:在Python脚本顶部导入pyperclip

    import pyperclip
    
  3. 创建复制函数:定义一个函数,其功能是利用pyperclip.copy()方法将短链接字符串复制到剪贴板。

    def copy_to_clipboard():
        pyperclip.copy(shortened_url)
    
  4. 绑定按钮与函数:在创建按钮时,使用on_click参数直接关联上面定义的函数。这样,用户点击按钮时,复制函数会立即执行。

    st.button('复制', on_click=copy_to_clipboard)
    

完成以上步骤后,运行应用。生成短链接后,点击“复制”按钮,然后尝试在任何文本编辑器(如记事本或浏览器地址栏)中粘贴(Ctrl+V),即可看到短链接已被成功复制。


总结

本节课中我们一起学习了如何完善Streamlit应用的交互功能。我们首先将后台生成的短链接展示在前端页面上,然后重点实现了“一键复制”功能。通过使用pyperclip库和按钮的on_click属性,我们巧妙地绕过了Streamlit表单可能带来的执行顺序问题,确保了复制操作的即时性和可靠性。现在,我们的URL短链接生成器已经具备了完整可用的核心流程。

027:音频转文本转换器Web应用开发概述 🎤➡️📝

在本节课中,我们将学习如何使用 Python 的 Streamlit 库来开发一个音频转文本的转换器 Web 应用。在正式开始编码之前,我们需要先规划好整个应用的开发流程。

应用开发流程概述

开发此应用需要遵循六个核心步骤。以下是每个步骤的简要说明。

第一步:用户上传音频文件

首先,我们需要让用户上传音频文件。我们将使用 Streamlit 的 file_uploader 小部件来实现这个功能。

第二步:分割音频文件

由于我们将使用 Google 的翻译服务(或类似的外部API)来将音频转换为文本,而这类服务通常对上传的音频文件有长度限制(例如,不超过一分钟),因此我们需要将用户上传的大音频文件分割成多个小片段。

第三步:导出音频片段

分割完成后,我们需要将这些音频片段导出为独立的文件。这一步是为后续处理做准备。

第四步:重新打开音频片段

在第三步导出后,我们需要在第四步重新打开这些音频片段文件作为处理源。你可能会疑惑为何要先导出再重新打开,这个疑问我们会在后续的实际开发环节中解答。

第五步:调用翻译服务

接下来,我们将这些分割好的小音频片段逐一发送给 Google(或其他服务)进行语音识别和翻译,以获取对应的文本。

第六步:显示转换结果

最后,我们需要将转换得到的文本结果显示在应用的界面上,供用户查看和复制。

总结

本节课我们一起规划了构建音频转文本转换器 Web 应用的六个关键步骤:上传文件分割音频导出片段重新打开调用服务显示结果。从下一节课开始,我们将进入实际的代码开发阶段,逐步实现这些功能。

028:Streamlit 音频转文本转换器Web应用

在本节课中,我们将开始使用 Python 的 Streamlit 库开发一个音频转文本转换器应用。我们将学习如何上传音频文件,并使用 pydub 库将其分割成基于静默的音频片段,为后续的文本转换做准备。

概述

我们将创建一个名为 audio_to_text.py 的 Streamlit 应用。核心步骤包括:

  1. 创建文件上传组件。
  2. 使用 pydub 库加载音频文件。
  3. 基于静默检测将长音频分割成多个短片段。

第一步:创建应用框架与文件上传器

首先,我们需要导入 Streamlit 并设置应用的基本界面,包括标题和文件上传组件。

import streamlit as st

# 设置应用标题
st.title("音频转文本转换器")
st.markdown("---")

# 创建文件上传组件
uploaded_audio = st.file_uploader("上传您的音频文件", type=['mp3', 'wav'])

第二步:导入并加载音频文件

为了处理音频,我们需要使用 pydub 库。在导入之前,请确保已按照相关教程正确安装 pydub 及其依赖(如 ffmpeg)。

from pydub import AudioSegment

![](https://github.com/OpenDocCN/cs-notes-pt1-zh/raw/master/docs/py-stlt-tut/img/f6ae7e26ef4b661cadddedb2b39b56ab_7.png)

![](https://github.com/OpenDocCN/cs-notes-pt1-zh/raw/master/docs/py-stlt-tut/img/f6ae7e26ef4b661cadddedb2b39b56ab_8.png)

# 检查用户是否已上传文件
if uploaded_audio is not None:
    # 将上传的文件转换为 AudioSegment 对象
    audio_segment = AudioSegment.from_file(uploaded_audio)
    # 打印音频对象以确认加载成功
    print(audio_segment)

第三步:基于静默分割音频

直接转换长音频可能遇到限制(例如,免费API通常有长度限制)。因此,我们将音频基于静默分割成多个片段,这比随机分割更能保证语义的完整性。

以下是分割音频的核心代码:

from pydub.silence import split_on_silence

# 基于静默分割音频
chunks = split_on_silence(
    audio_segment,
    min_silence_len=500,          # 静默至少持续500毫秒(0.5秒)才被视为分割点
    silence_thresh=audio_segment.dBFS - 20, # 静默阈值:比音频平均音量低20分贝
    keep_silence=100              # 在每个分割出的片段首尾保留100毫秒静默
)

# 遍历并打印每个音频片段
for i, chunk in enumerate(chunks):
    print(f"Chunk {i}: {chunk}")

参数解释

  • min_silence_len:定义被视为“静默”并用于分割的最小持续时间(毫秒)。
  • silence_thresh:定义静默的音量阈值。audio_segment.dBFS - 20 表示比音频平均音量低20分贝的声音被视为静默。
  • keep_silence:在每个分割出的音频块开头和结尾保留的静默时长(毫秒),使转换后的语音听起来更自然。

总结

本节课中,我们一起学习了构建音频转文本转换器应用的前半部分。我们成功创建了一个 Streamlit 应用界面,实现了音频文件的上传功能,并利用 pydub 库的 split_on_silence 方法,智能地将长音频文件按静默处分割成了多个短片段。

在下一节课中,我们将继续开发,学习如何将这些音频片段导出为临时文件,并使用语音识别库(如 Google Speech Recognition)将它们逐一转换为文本,最终完成整个音频转文本的流程。

029:Streamlit 音频转文本转换器Web应用 🎙️➡️📝

概述

在本节课中,我们将继续开发音频转文本转换器应用。我们已经完成了前两个步骤,现在将从第三步开始,学习如何将音频分割成块并导出,然后使用Google的语音识别服务将音频转换为文本。


步骤三:导出音频块

上一节我们介绍了如何将大音频文件分割成块。本节中我们来看看如何将这些音频块导出为独立的文件。

我们需要为每个音频块指定一个唯一的输出文件名,以便区分它们。我们将使用循环的索引作为文件名的一部分。

以下是实现此步骤的代码修改:

# 使用enumerate函数遍历音频块,同时获取索引和块数据
for idx, chunk in enumerate(chunks):
    # 导出音频块,文件名为索引号,格式为wav
    chunk.export(f"{idx}.wav", format="wav")
  • enumerate(chunks):这个函数允许我们在遍历chunks列表时,同时获取每个元素的索引(idx)和值(chunk)。
  • chunk.export(...):这是导出音频块的方法。
  • f"{idx}.wav":这是输出的文件名。idx是索引(如0, 1, 2),.wav是文件扩展名。
  • format="wav":指定导出音频的格式为WAV。

运行应用后,你会在项目目录中看到导出的音频文件(例如 0.wav, 1.wav)。


步骤四:导入语音识别库并打开音频源

现在我们已经有了独立的音频文件,下一步是将它们转换为文本。我们将使用Python的speech_recognition库,它可以帮助我们调用Google的语音识别服务。

首先,确保你已经安装了这个库。如果没有,请在终端中运行以下命令:

pip install SpeechRecognition

安装完成后,在代码中导入该库,并准备打开我们导出的音频文件作为识别源。

以下是相关代码:

import speech_recognition as sr

# ...(之前的代码)...

for idx, chunk in enumerate(chunks):
    chunk.export(f"{idx}.wav", format="wav")
    
    # 打开导出的音频文件作为识别源
    with sr.AudioFile(f"{idx}.wav") as source:
        # 后续识别代码将写在这里
        pass

  • import speech_recognition as sr:导入语音识别库,并使用简称sr以便后续调用。
  • with sr.AudioFile(f"{idx}.wav") as source::使用with语句打开音频文件。sr.AudioFile()用于创建一个音频文件对象,as source将这个对象赋值给变量sourcewith语句能确保文件在使用后被正确关闭。

步骤五:录制音频并发送至Google识别

我们已经打开了音频源,接下来需要录制音频内容,然后将其发送到Google的语音识别引擎进行转换。

以下是实现此功能的步骤和代码:

  1. 创建识别器对象:这是speech_recognition库的核心类,用于处理识别操作。
  2. 录制音频:从打开的音频源中录制音频数据。
  3. 调用识别服务:将录制的音频发送给Google识别。这里我们使用免费的recognize_google()方法,但它有大约一分钟的长度限制。
  4. 错误处理:使用try...except块来捕获和处理识别过程中可能出现的错误(例如网络问题、音频不清晰等)。

以下是整合后的代码:

import speech_recognition as sr

# 创建识别器实例
recognizer = sr.Recognizer()

![](https://github.com/OpenDocCN/cs-notes-pt1-zh/raw/master/docs/py-stlt-tut/img/43fc69d8127a64b0d22df0b72826417b_15.png)

for idx, chunk in enumerate(chunks):
    chunk.export(f"{idx}.wav", format="wav")
    
    with sr.AudioFile(f"{idx}.wav") as source:
        # 从源中录制音频
        recorded_audio = recognizer.record(source)
        
        try:
            # 尝试使用Google的免费服务识别音频
            text = recognizer.recognize_google(recorded_audio)
            print(text)  # 打印识别出的文本
        except sr.UnknownValueError:
            # 如果Google无法理解音频内容
            print("Google Speech Recognition could not understand the audio.")
        except sr.RequestError:
            # 如果无法连接到Google服务
            print("Could not request results from Google Speech Recognition service.")
  • recognizer = sr.Recognizer():实例化一个识别器对象。
  • recorded_audio = recognizer.record(source):从source(即我们打开的音频文件)中录制音频。
  • recognizer.recognize_google(recorded_audio):调用Google的语音识别API,将recorded_audio数据发送出去,并返回识别出的文本。
  • try: ... except: ...:这是异常处理结构。try块中的代码会被尝试执行。如果发生sr.UnknownValueError(音频无法识别)或sr.RequestError(请求失败),程序将不会崩溃,而是执行except块中的代码,打印出相应的错误信息。

运行应用并上传音频文件后,你将在终端或控制台中看到转换后的文本输出。


总结

本节课中我们一起学习了音频转文本应用的核心后端逻辑:

  1. 导出音频块:将分割后的音频块保存为独立的WAV文件,并为它们命名。
  2. 设置识别环境:导入speech_recognition库,并学习如何打开音频文件作为识别源。
  3. 执行语音识别:创建识别器,录制音频,并通过recognize_google()函数将其发送到Google服务获取文本结果,同时使用try...except进行健壮的错误处理。

目前,识别结果输出在控制台。在下一节课中,我们将把这些结果显示在Streamlit Web应用的界面上,让整个应用更加完整和用户友好。

030:Streamlit 音频转文本转换器Web应用

概述

在本节课中,我们将继续开发音频转文本应用。上一节我们实现了音频文件的分块处理和语音识别,本节我们将学习如何在Streamlit Web应用中展示并优化识别结果。核心目标是让用户可以查看和编辑识别出的文本,并播放原始音频进行对照。


在Streamlit中展示可编辑的文本结果

上一节我们注意到,Google语音识别的结果并非100%准确。因此,与其以不可编辑的格式显示文本,不如将其放入一个可编辑的组件中。这样用户可以方便地修正识别错误。

为了实现这个功能,我们将使用 st.text_area 组件,因为它适合输入和显示大段文本。我们将把所有识别出的文本块合并成一个完整的字符串,然后一次性显示在这个文本区域中。

以下是实现步骤:

  1. 首先,在代码中创建一个空字符串变量,用于累积最终的识别结果。
    final_result = ""
    
  2. 在遍历处理每个音频块的循环中,将每个块的识别文本追加到这个字符串中。
    for chunk in chunks:
        # ... 识别代码 ...
        text = recognizer.recognize_google(audio_chunk)
        final_result = final_result + text + " "
        # 如果遇到无法识别的内容,可以添加标记
        # final_result = final_result + "[无法识别] "
    
  3. 重要st.text_area 组件必须创建在 for 循环之外。如果放在循环内部,会根据音频块的数量创建多个独立的文本输入框,这不是我们想要的效果。
  4. 循环结束后,使用 final_result 变量来设置 st.text_area 的初始值。
    st.text_area("识别文本", value=final_result, height=300)
    

添加音频播放器组件

为了让用户在编辑文本前能对照原始音频进行检查,我们还需要在应用中添加一个音频播放器。这非常简单,只需使用Streamlit的 st.audio 组件。

你只需要将上传的音频文件对象传递给这个组件即可:

st.audio(uploaded_file)

添加这个组件后,用户界面将同时包含音频播放器和可编辑的文本区域,用户体验将更加完整。


最终应用效果与总结

按照上述步骤完成代码后,重新运行应用。现在,用户的操作流程是:

  1. 上传一个音频文件。
  2. 应用自动处理并显示识别出的文本在一个可编辑的文本框内。
  3. 用户可以通过上方的音频播放器收听原始录音。
  4. 根据听到的内容,用户可以直接在文本框中修改识别不准确的部分。
  5. 编辑完成后,用户可以方便地复制最终文本,用于其他地方。

本节课中,我们一起学习了如何优化Streamlit应用的输出界面。我们通过 st.text_area 实现了文本的可编辑展示,并通过 st.audio 添加了音频播放功能,从而构建了一个用户友好、功能实用的音频转文本转换器Web应用。

在接下来的教程中,我们将探索Streamlit的更多新功能。

031:Streamlit 音频转文本转换器Web应用 - 添加下载功能

在本节课中,我们将修改我们的音频转文本转换器,并为其添加更多功能,例如下载翻译后的文件。我们将学习如何在表单中创建文本区域和下载按钮,以及如何将用户修改后的文本内容保存到其系统的下载文件夹中。

概述

上一节我们完成了音频转文本的核心功能。本节中,我们来看看如何让用户能够下载转换后的文本。我们将创建一个表单,内含一个可编辑的文本区域和一个下载按钮。当用户点击下载按钮时,程序会将文本区域中的内容保存为一个 .txt 文件,并自动保存到用户的下载文件夹中。

创建表单与下载按钮

首先,我们需要在应用中创建一个表单,用于容纳文本区域和下载按钮。

以下是创建表单和按钮的代码:

with st.form(key='download_form'):
    text_area = st.text_area("编辑转换后的文本", value=final_result, height=300)
    download_btn = st.form_submit_button("📥 下载文本文件")

在这段代码中:

  • st.form 创建了一个表单容器,key 参数用于标识这个表单。
  • st.text_area 在表单内创建了一个文本编辑区域,其初始值 value 被设置为之前转换得到的 final_result
  • st.form_submit_button 创建了一个表单提交按钮,其文本标签为“下载文本文件”。

处理下载逻辑

当用户点击下载按钮时,我们需要将文本区域中的内容写入一个文件。我们计划将文件保存到用户的“下载”文件夹中,以确保跨用户系统的兼容性。

以下是处理下载的核心逻辑:

if download_btn:
    # 获取用户“下载”文件夹的路径
    user_profile = os.environ.get('USERPROFILE')
    downloads_path = os.path.join(user_profile, 'Downloads')
    file_path = os.path.join(downloads_path, 'transcript.txt')

    # 将文本内容写入文件
    with open(file_path, 'w', encoding='utf-8') as file:
        file.write(text_area)
    st.success(f"文件已成功下载至:{file_path}")

这段代码的执行步骤如下:

  1. 检查按钮状态if download_btn: 判断下载按钮是否被点击。
  2. 获取下载路径
    • 通过 os.environ.get('USERPROFILE') 获取当前用户的配置文件路径(例如 C:\Users\YourName)。
    • 使用 os.path.join 将“Downloads”文件夹名拼接上去,得到完整的下载文件夹路径。
    • 再次使用 os.path.join 指定要创建的文件名 transcript.txt
  3. 写入文件
    • with open(file_path, 'w', encoding='utf-8') as file: 以写入模式('w')和UTF-8编码打开(或创建)文件。'w' 模式会覆盖已存在的同名文件。
    • file.write(text_area) 将文本区域 text_area 中的内容写入文件。
  4. 提示用户st.success 显示一条成功消息,告知用户文件保存的位置。

代码整合与运行

将上述代码整合到你的Streamlit应用中。完整的核心部分结构如下:

import streamlit as st
import os
# ... 其他导入(如语音识别库)

# 音频上传和处理部分(之前的代码)
# ...

# 显示转换结果和下载表单
if final_result:
    st.subheader("转换结果")
    st.text(final_result)

    with st.form(key='download_form'):
        edited_text = st.text_area("编辑转换后的文本", value=final_result, height=300)
        download_btn = st.form_submit_button("📥 下载文本文件")

        if download_btn:
            user_profile = os.environ.get('USERPROFILE')
            downloads_path = os.path.join(user_profile, 'Downloads')
            file_path = os.path.join(downloads_path, 'transcript.txt')

            with open(file_path, 'w', encoding='utf-8') as file:
                file.write(edited_text)
            st.success(f"文件已成功下载至:{file_path}")

运行应用后,流程如下:

  1. 上传音频文件并完成转换。
  2. 转换结果显示在页面上,同时下方会出现一个文本编辑区域(内容已预填)和一个“下载文本文件”按钮。
  3. 用户可以在文本区域中修改文本。
  4. 点击“下载文本文件”按钮。
  5. 页面提示文件已保存到“下载”文件夹,用户可以在该文件夹中找到 transcript.txt 文件。

总结

本节课中我们一起学习了如何为Streamlit音频转文本应用添加文件下载功能。我们创建了一个包含可编辑文本区域和下载按钮的表单,并利用Python的 os 模块动态获取用户系统的下载文件夹路径,从而实现了将用户修改后的文本内容一键保存到本地。这个功能极大地提升了应用的实用性和用户体验。在接下来的课程中,我们将探索Streamlit的更多高级特性。

032:Streamlit YouTube 关键词提取器 Web 应用

在本教程中,我们将开始使用 Streamlit 制作一个 YouTube 关键词提取器应用程序。

理解 YouTube 页面结构

在开始抓取 YouTube 之前,理解 YouTube 的结构以及它在哪里存储视频的隐藏关键词非常重要。让我们开始理解其结构。

你需要右键点击页面,然后点击“检查元素”,这将打开开发者工具界面。虽然这里有很多代码行,但让我们回顾一些 HTML 和 CSS 的概念。

YouTube 关键词实际上是一种元数据。如果你对 HTML 和 CSS 编码有一点了解,就会知道我们总是将元数据放在 <head> 标签内。

首先,让我们在 <head> 标签内进行研究。关闭 <body> 标签,打开 <head> 标签。这里有很多 <script> 标签。这里有一个 meta 数据,但它的属性是 property,这不是我们要找的。

这里有一个 meta 标签,其 name 属性是 keywords,这些就是这个视频的所有关键词。这样,我们就获得了访问任何视频的 YouTube 隐藏关键词的途径。

同时,这里还有一个隐藏的描述信息。YouTube 为其网站提供了这个描述:“享受你喜爱的视频和音乐,上传原创内容,并与全世界的朋友、家人和观众分享。” 这是 YouTube 网站的隐藏描述。我们对此不关心,我们只关心这些关键词。

现在,我们将提取这部分内容。请记住,它位于 <head> 标签内,并且是一个 meta 标签。

开始创建抓取器

现在,让我们开始为它创建一个抓取器。打开你的 VS Code,创建一个新文件,命名为 youtube_keywords.py

首先,我们需要导入 Streamlit。

import streamlit as st

我们将使用 Beautiful Soup 进行网页抓取。

from bs4 import BeautifulSoup

我们还需要导入另一个库:requests

import requests

借助 requests 库,我们将首先向 YouTube URL 发送 GET 请求,以查看它是否可抓取。复制一个 YouTube 视频的 URL。

在代码中,首先获取页面内容并检查状态码。

page = requests.get('YOUR_YOUTUBE_URL_HERE')
print(page.status_code)

运行这段代码,如果输出是 200,则表示一切正常,我们成功发送了 GET 请求。

现在回到正题。将页面内容转换为 Beautiful Soup 对象。

soup = BeautifulSoup(page.content, 'lxml')

我们已经成功将内容转换为 Beautiful Soup 对象。现在看看如何抓取 YouTube 关键词。

如你所见,页面中有多个 <meta> 标签。如何区分它们呢?这些标签没有类引用之类的标识。唯一的区别是每个 <meta> 标签有不同的 nameproperty 属性。

因此,我们可以借助 name 属性来区分它们。如果使用 findfind_all 函数,我们需要类引用来区分不同的标签,但这里没有类。我们只有一个解决方案:使用 CSS 选择器。

借助 CSS 选择器,我们可以实际区分每个 <meta> 标签。在代码中,我们将使用 selectselect_all 函数来进行 CSS 选择。

meta_tag = soup.select('meta[name="keywords"]')
print(meta_tag)

运行后,我们得到了输出。这是一个列表,我们需要访问列表的第一个值,也就是包含数据的那个元素。

meta_tag = soup.select('meta[name="keywords"]')[0]

现在,我们需要访问这个元素的 content 属性值。

keywords = meta_tag['content']
print(keywords)

运行后,我们成功提取出了所有关键词。

整合到 Streamlit 应用

现在是与 Streamlit 交互的时候了。首先创建一个标题。

st.title('YouTube 关键词提取器')

在标题之后,创建一个简单的分隔线,然后创建一个文本输入组件。借助这个组件,我们将从用户那里获取 YouTube 链接。

url = st.text_input('在此输入 YouTube 视频 URL')

将用户输入的信息保存在 url 变量中。然后,我们需要向这个 URL 发送请求。

我们需要检查用户输入的 URL 是否为空。如果用户输入了 URL,我们再处理所有内容。

if url:
    page = requests.get(url)
    soup = BeautifulSoup(page.content, 'lxml')
    meta_tag = soup.select('meta[name="keywords"]')[0]
    keywords = meta_tag['content']
    st.write(keywords)

保存所有内容,然后运行我们的 Streamlit 应用。

streamlit run youtube_keywords.py

在浏览器中打开应用,输入一个 YouTube 视频 URL,然后按回车键。现在,页面上应该会显示提取出的所有关键词。

我们已成功提取出关键词。

总结

在本节课中,我们一起学习了如何分析 YouTube 页面的 HTML 结构以定位隐藏的关键词元数据。我们使用了 requests 库获取网页内容,并用 BeautifulSoup 进行解析。通过 CSS 选择器 meta[name="keywords"],我们精准地找到了存储关键词的标签,并提取出其 content 属性的值。最后,我们将整个流程整合进一个 Streamlit 应用,通过文本输入框接收用户输入的 URL,并实时显示提取出的关键词。

在下一教程中,我们将在 Streamlit Web 应用上更好地展示这些关键词,并从 YouTube 提取更多信息。

033:Streamlit YouTube关键词提取器Web应用

在本节课中,我们将继续开发YouTube关键词提取器应用,学习如何将提取到的关键词和视频标题美观地展示在Streamlit网页应用界面上,而不是仅仅在终端打印。

上一节我们完成了关键词的提取逻辑,本节中我们来看看如何将这些数据呈现在前端。

将关键词输出到Streamlit界面

首先,我们需要修改代码,将原本打印到终端的关键词保存到一个变量中,然后在Streamlit应用里显示它们。

以下是实现步骤:

  1. 保存关键词:将提取到的关键词列表赋值给一个变量,例如 KEYWORDS
  2. 创建标题:使用 st.title()st.header() 为关键词区域创建一个标题,例如“Tags”。
  3. 使用Markdown格式化输出:利用 st.markdown() 函数,结合HTML标签(如 <h5>)来格式化显示文本。这允许我们自定义样式,比如颜色。
  4. 设置样式:在HTML标签内使用 style 属性来定义颜色等CSS样式。例如,可以使用十六进制颜色代码。
  5. 允许不安全HTML:由于我们使用了HTML标签,需要在 st.markdown() 中设置参数 unsafe_allow_html=True

核心实现代码如下:

# 假设keywords_list是提取到的关键词列表
KEYWORDS = keywords_list

# 为关键词区域创建标题
st.title("Tags")

# 使用Markdown和HTML格式化显示关键词
st.markdown(
    f'<h5 style="color: #FF6B6B;">{KEYWORDS}</h5>',
    unsafe_allow_html=True
)

运行应用后,输入一个YouTube视频链接,你将看到提取出的关键词以指定的样式显示在网页上。

提取并显示视频标题

除了关键词,视频标题也是一个重要信息。接下来,我们修改代码来一并提取并显示视频标题。

以下是具体操作:

  1. 提取标题:使用BeautifulSoup查找包含视频标题的HTML元素。通常,标题位于 <title> 标签或特定的 <meta> 标签中。根据页面结构,找到正确的选择器。
  2. 获取文本内容:提取到标题元素后,需要使用 .text 属性来获取其内部的纯文本字符串。
  3. 在界面上显示:在关键词上方,先显示视频标题。可以创建一个新的标题(如使用 st.title()),然后同样用 st.markdown() 来显示标题文本,并可以使用不同的HTML标签(如 <h4>)以示区分。

实现此功能的代码修改如下:

# 提取视频标题(假设通过soup对象查找)
title_element = soup.find('title') # 请根据实际页面结构调整选择器
video_title = title_element.text if title_element else "Title not found"

# 显示视频标题
st.title("Video Title")
st.markdown(
    f'<h4 style="color: #4ECDC4;">{video_title}</h4>',
    unsafe_allow_html=True
)

![](https://github.com/OpenDocCN/cs-notes-pt1-zh/raw/master/docs/py-stlt-tut/img/609b8cba821bf97edec7d612e7bb31ff_7.png)

![](https://github.com/OpenDocCN/cs-notes-pt1-zh/raw/master/docs/py-stlt-tut/img/609b8cba821bf97edec7d612e7bb31ff_8.png)

# 显示关键词(之前已实现的代码)
st.title("Tags")
st.markdown(
    f'<h5 style="color: #FF6B6B;">{KEYWORDS}</h5>',
    unsafe_allow_html=True
)

完成以上修改后,重新运行应用。现在,当你输入一个YouTube视频URL,应用将首先展示提取到的视频标题,然后在下方面显示所有的关键词。

本节课中我们一起学习了如何将后端提取的数据(视频标题和关键词)优雅地整合到Streamlit前端界面中。我们使用了 st.markdown() 配合HTML和CSS来定制显示样式,使得最终的应用界面信息清晰、美观。至此,一个功能完整的简易版YouTube关键词提取器Web应用就构建完成了。在接下来的课程中,我们将探索Streamlit的更多新功能。

034:Streamlit 关键词密度检查器 Web 应用

在本教程中,我们将开始使用 Streamlit 制作一个关键词密度检查器应用程序。这个工具对于搜索引擎优化(SEO)非常重要,它能帮助你分析特定关键词在文本段落中出现的频率,从而撰写更符合搜索引擎友好的内容。

概述

我们将创建一个 Web 应用,允许用户输入一段文本(段落),然后程序会清理文本、分割成单词,并计算每个单词出现的次数。这是构建关键词密度分析器的核心逻辑。

创建项目文件与基础设置

首先,我们需要创建一个 Python 文件。我们将它命名为 density_checker.py

接下来,导入必要的库并设置应用标题。

import streamlit as st
import re

st.title("关键词密度检查器")
st.write("此应用用于检查特定单词在文本行或段落中的密度。")

获取用户输入

我们需要一个文本区域让用户输入他们想要分析的段落。

text = st.text_area("请输入段落:", height=150)

文本预处理

在分析之前,必须清理文本。这包括移除标点符号并将所有字符转换为小写,以确保分析的准确性。

以下是文本预处理的步骤:

  1. 移除特殊字符:使用正则表达式 re.sub() 方法移除句号、问号、感叹号等标点。
  2. 转换为小写:使用 .lower() 方法确保大小写不影响单词计数。
  3. 分割成单词列表:使用 .split() 方法根据空格将文本分割成独立的单词。

对应的代码如下:

if text:
    # 1. 移除特殊字符
    simple_text = re.sub(r'[.,?!;:\-*]', '', text)
    # 2. 转换为小写
    simple_text = simple_text.lower()
    # 3. 分割成单词列表
    words = simple_text.split()

构建关键词密度逻辑

文本预处理完成后,下一步是统计每个单词出现的频率。我们将使用一个字典来存储结果,其中键是单词,值是该单词出现的次数。

以下是构建字典的逻辑:

  1. 遍历分割后的单词列表。
  2. 检查当前单词是否已存在于字典中。
  3. 如果存在,将其计数值加1。
  4. 如果不存在,在字典中创建该单词作为新键,并将其初始值设为1。
    word_dict = {}
    for word in words:
        if word in word_dict:
            word_dict[word] += 1
        else:
            word_dict[word] = 1

    st.write("单词出现频率统计:")
    st.write(word_dict)

测试应用程序

现在,让我们运行应用程序来测试其功能。

  1. 在终端中运行命令:streamlit run density_checker.py
  2. 在打开的网页文本框中输入一段文字,例如:“Hello, I am a programmer. I love programming!”。
  3. 按下 Ctrl+Enter(或在文本框外点击)提交。
  4. 应用程序下方将显示一个字典,展示每个单词及其出现的次数。例如:{'hello': 1, 'i': 2, 'am': 1, 'a': 1, 'programmer': 1, 'love': 1, 'programming': 1}

总结

在本节课中,我们一起学习了如何使用 Streamlit 构建一个关键词密度检查器 Web 应用的基础部分。我们完成了以下核心步骤:

  • 创建了应用界面并获取用户输入。
  • 使用正则表达式和字符串方法对文本进行预处理(清理标点、统一小写、分割单词)。
  • 实现了核心逻辑,通过遍历列表和使用字典来统计每个单词的出现频率。

目前,我们的应用可以输出原始的单词频率字典。在下一节课中,我们将在此基础上进行扩展,计算每个单词的出现百分比,并以更美观、直观的格式(如表格或图表)在 Streamlit 网页上展示结果。

035:Streamlit 关键词密度检查器 Web 应用

在本节课中,我们将继续开发关键词密度检查器应用。我们将学习如何从字典中提取数据,并使用 Streamlit 的布局功能,将关键词、出现次数和百分比以美观的表格形式展示在网页上。

概述

上一节我们构建了一个字典,用于存储每个关键词及其在文本中出现的次数。本节中,我们将把这个字典的内容清晰地展示在 Streamlit 应用界面上。我们将使用多列布局,分别显示关键词、出现次数和计算出的百分比。

从字典中提取数据

首先,我们需要从 word_dictionary 字典中分别提取出所有的键(关键词)和值(出现次数)。我们将把它们转换为列表格式,以便后续遍历和展示。

以下是提取键和值的代码:

keys = list(word_dictionary.keys())
values = list(word_dictionary.values())
  • word_dictionary.keys() 返回字典中所有的键。
  • list() 函数将其转换为列表。
  • word_dictionary.values() 返回字典中所有的值。
  • 同样使用 list() 函数将其转换为列表。

遍历并展示数据

现在我们有了 keysvalues 两个列表。我们需要遍历它们,并将每一项内容显示出来。我们将使用一个 for 循环,循环次数由列表的长度决定。

以下是遍历和展示数据的初始代码:

for i in range(len(keys)):
    st.markdown(f"<h5>{keys[i]}</h5>", unsafe_allow_html=True)
    st.markdown(f"<h5>{values[i]}</h5>", unsafe_allow_html=True)

这段代码会依次显示每个关键词及其出现次数,但它们是上下排列的,不够直观。

优化布局:使用多列

为了获得更好的视觉效果,我们将使用 Streamlit 的 columns 功能创建三列,分别用于显示关键词、出现次数和百分比。

以下是创建三列布局的代码:

col1, col2, col3 = st.columns(3)

现在,我们可以在循环内,将内容分别放入对应的列中。同时,我们还需要计算每个关键词出现的百分比。

以下是优化后的循环代码:

total_length = len(words)  # 计算文本总词数

for i in range(len(keys)):
    with col1:
        st.markdown(f"<h5>{keys[i]}</h5>", unsafe_allow_html=True)
    with col2:
        st.markdown(f"<h5>{values[i]}</h5>", unsafe_allow_html=True)
    with col3:
        percentage = (values[i] / total_length) * 100
        st.markdown(f"<h5>{round(percentage, 2)}%</h5>", unsafe_allow_html=True)

  • total_length 是输入文本的总词数。
  • 百分比的计算公式为:(某个词的出现次数 / 总词数) * 100
  • round(percentage, 2) 将百分比结果四舍五入到小数点后两位,使显示更整洁。

添加列标题

为了让表格更清晰,我们还需要为每一列添加一个标题。标题应该添加在循环开始之前。

以下是添加列标题的代码:

with col1:
    st.markdown("<h3 style='text-align: center;'>关键词</h3>", unsafe_allow_html=True)
with col2:
    st.markdown("<h3 style='text-align: center;'>出现次数</h3>", unsafe_allow_html=True)
with col3:
    st.markdown("<h3 style='text-align: center;'>百分比</h3>", unsafe_allow_html=True)

style='text-align: center;' 用于将标题文字居中显示。

最终效果

完成以上所有步骤后,运行应用并输入一段文本。你将看到一个清晰的三列表格,展示了每个关键词、它的出现频率以及占总词数的百分比。

总结

本节课中,我们一起学习了如何将 Python 字典中的数据有效地展示在 Streamlit 网页应用中。关键步骤包括:

  1. 使用 list(dict.keys())list(dict.values()) 从字典提取数据。
  2. 使用 st.columns() 创建多列布局以组织内容。
  3. 在循环中遍历数据,并将每一项放入对应的列容器中。
  4. 进行简单的数学计算(如百分比)并格式化输出。
  5. 为各列添加标题以提升可读性。

通过本节的实践,你已经掌握了使用 Streamlit 构建数据展示界面的基本方法。在接下来的教程中,我们将探索 Streamlit 的更多功能。

036:Streamlit 数据可视化 Web 应用

在本节课中,我们将开始制作一个数据可视化应用。我们将学习如何构建一个允许用户上传、选择并可视化Excel数据的完整流程。

项目概述与步骤

要完成这个项目,我们需要遵循四个核心步骤。首先,用户需要上传多个Excel文件。接着,用户从已上传的文件中选择需要可视化的文件。然后,用户通过单选按钮选择要针对时间进行绘制的数据项。最后,我们将根据用户的选择生成可视化图表。

以下是实现此项目的具体步骤列表:

  1. 让用户上传多个Excel文件。
  2. 让用户从已上传的文件中选择要可视化的文件。
  3. 让用户通过单选按钮选择要针对时间进行绘制的数据项。
  4. 根据用户的选择,将数据可视化。

在下一节教程中,我们将正式开始编写代码来实现这些功能。



本节课中,我们一起学习了构建Streamlit数据可视化应用的整体规划和四个关键步骤。从下一节课开始,我们将动手编写代码,逐步实现文件上传、选择、配置和可视化的完整功能。

037:数据可视化应用 - 文件上传与选择

在本节课中,我们将开始构建一个数据可视化应用。我们将学习如何创建一个文件上传器,允许用户上传多个Excel文件,并提供一个交互式界面让用户选择要分析的文件和数据列。

概述

我们将创建一个名为 data_visualizer.py 的Python文件。应用的核心功能包括:

  1. 使用 st.file_uploader 上传多个 .xlsx 文件。
  2. 使用 st.multiselect 让用户从上传的文件中选择一个或多个进行分析。
  3. 使用 st.radio 让用户选择要针对“债务”数据进行分析的实体(如GPU、CPU等)。

现在,让我们一步步来实现它。

创建应用文件与标题

首先,我们需要导入Streamlit库并设置应用的标题。

import streamlit as st

st.title('数据可视化应用')

创建文件上传器

接下来,我们需要创建一个文件上传部件,允许用户上传多个Excel文件。我们使用 st.file_uploader 函数来实现。

以下是创建文件上传器的代码:

uploaded_files = st.file_uploader(
    "上传多个文件",
    type=['xlsx'],
    accept_multiple_files=True
)
  • label:定义了上传按钮旁显示的文本。
  • type:限制了用户只能上传 .xlsx 格式的文件。
  • accept_multiple_files=True:允许用户一次性选择并上传多个文件。

获取上传文件的名称

用户上传文件后,我们需要获取这些文件的名称,以便后续让用户进行选择。我们通过遍历 uploaded_files 列表来实现。

以下是获取文件名的逻辑:

file_names = []
if uploaded_files:
    for file in uploaded_files:
        file_names.append(file.name)
    # print(file_names) # 用于调试,在实际应用中可注释掉
  • 首先检查 uploaded_files 是否不为空(即用户已上传文件)。
  • 然后遍历每个文件对象,将其 name 属性(文件名)添加到一个列表中。

创建文件选择部件

上一节我们获取了文件名列表,本节中我们来看看如何让用户选择要分析的具体文件。我们将使用 st.multiselect 创建一个多选下拉菜单。

以下是创建多选部件的代码:

selected_files = st.multiselect(
    "选择文件",
    options=file_names
)
  • label:定义了选择框的标签。
  • options:将上一步获取的 file_names 列表作为可选项提供给用户。

创建数据分析选项

当用户选择了文件后,我们需要进一步询问他们想分析什么数据。这里我们假设每个Excel文件都有“债务”列,以及“GPU”、“CPU”等实体列。我们使用 st.radio 创建一个单选按钮组。

以下是创建单选按钮的代码:

if selected_files:
    option = st.radio(
        "选择要对比债务的实体",
        options=['GPU', 'CPU', 'mouse', 'keyboard', 'casing', 'None']
    )
  • 只有当 selected_files 不为空(即用户已选择文件)时,才会显示这个单选按钮。
  • options 参数列出了所有可选的实体,以及一个“None”选项,表示不进行特定分析。

处理用户选择

最后,我们需要对用户的选择做出响应。当用户没有选择“None”时,我们执行后续的数据处理逻辑(本节课暂不实现,仅打印选项)。

以下是处理选择的代码:

    if option != 'None':
        # 这里将放置后续读取Excel文件和进行数据可视化的代码
        # 本节课暂时只打印出用户的选择
        print(option)
  • 通过判断 option 是否等于 'None' 来决定是否进行数据处理。

总结

本节课中我们一起学习了构建Streamlit数据可视化应用的基础框架。我们实现了:

  1. 使用 st.file_uploader 上传多个文件。
  2. 使用 st.multiselect 让用户选择文件。
  3. 使用 st.radio 让用户选择要分析的数据维度。
  4. 建立了基本的条件逻辑来控制应用流程。

在接下来的教程中,我们将在此基础上,学习如何读取被选中的Excel文件,提取数据,并最终生成图表来完成数据可视化。

038:Streamlit 数据可视化Web应用 - 数据提取与处理

在本节课中,我们将继续开发数据可视化Web应用。我们将学习如何从用户上传的Excel文件中提取特定数据,并对其进行处理,为后续的可视化步骤做准备。核心内容包括使用Pandas库读取数据、筛选用户选择的文件、提取特定列的数据以及处理日期格式。


概述与目标

上一节我们完成了文件上传和选项选择界面的搭建。本节中,我们将重点实现数据的后端处理逻辑。具体来说,我们需要:

  1. 遍历用户上传的所有文件。
  2. 仅处理用户通过多选框选定的文件。
  3. 使用Pandas读取Excel文件。
  4. 提取用户通过单选按钮选择的特定列数据。
  5. 正确处理日期列,为绘制图表做好准备。

遍历与筛选用户选择的文件

首先,我们需要遍历所有上传的文件,但只处理用户明确选中的那些。以下是实现步骤:

我们使用一个for循环来遍历uploaded_files列表中的每个文件。在循环内部,通过一个if语句检查当前文件名是否存在于用户选择的文件列表selected_files中。

for file in uploaded_files:
    if file.name in selected_files:
        # 处理这个文件
        pass
    else:
        # 跳过这个文件
        continue

这样,只有被选中的文件才会进入后续的数据处理流程。


使用Pandas读取Excel数据

为了高效地处理表格数据(如Excel、CSV),我们使用强大的pandas库。如果尚未安装,请在终端中运行以下命令:

pip install pandas

安装后,在代码中导入pandas,并使用pd.read_excel()函数读取文件。为了避免pandas自动生成行索引(0, 1, 2...),我们需要指定文件中的某一列作为索引。在本例中,第一列“ID”适合作为索引,我们使用参数index_col=0

import pandas as pd
# 读取Excel文件,并指定第一列为索引
shop_data = pd.read_excel(file, index_col=0)

提取特定列的数据

用户通过单选按钮选择他们想要可视化的数据列(如CPU、GPU)。我们需要根据这个选择,从DataFrame中提取相应的列数据。

提取单列数据非常简单,只需将列名(即option变量的值)放入方括号中即可。提取出的数据是一个Pandas Series对象。

# 提取用户选择的列数据
selected_column_data = shop_data[option]

为了后续绘图方便,我们通常需要将Series转换为Python列表。

# 将数据转换为列表
data_list = selected_column_data.tolist()


处理日期数据

我们的数据表中包含一个“Date”列,但其在Excel中的格式是“日期时间”类型(例如 2023-10-27 00:00:00)。直接转换为列表会得到复杂的datetime对象,不利于在图表轴上显示。

解决方案如下:

  1. 我们首先提取该列的所有原始值。
  2. 然后,将每个datetime对象转换为字符串。
  3. 接着,利用日期和时间之间的分隔符“T”进行分割(ISO格式日期字符串如2023-10-27T00:00:00)。
  4. 最后,只取分割后的第一部分,即纯日期部分。

我们创建一个专门的函数date_converter来完成这个任务:

def date_converter(date_column):
    """
    将日期时间列转换为纯日期字符串列表。
    参数 date_column: pandas Series,包含日期时间数据。
    返回: 纯日期字符串列表。
    """
    date_values = date_column.values # 获取原始值数组
    result = [] # 初始化结果列表
    for value in date_values:
        # 转换为字符串并按‘T’分割,取日期部分
        date_only = str(value).split('T')[0]
        result.append(date_only)
    return result

# 使用函数处理‘Date’列
dates_list = date_converter(shop_data['Date'])
print("处理后的日期列表:", dates_list)

运行后,我们将得到一个干净的日期字符串列表,例如 [‘2023-10-26’, ‘2023-10-27’],这非常适合用作图表的X轴数据。


本节总结

本节课中我们一起学习了数据可视化应用的核心数据处理步骤。

  1. 我们学会了如何筛选用户选择的文件进行针对性处理。
  2. 掌握了使用Pandas读取Excel文件并设置正确索引的方法。
  3. 实现了根据用户交互动态提取特定数据列的功能。
  4. 最关键的是,我们创建了一个函数来清洗和转换日期时间数据,得到了干净的日期列表,为下一步绘制图表做好了充分准备。

至此,数据的提取和预处理工作已经完成。在下一节课中,我们将使用Matplotlib库,把处理好的数据(dates_list作为X轴,data_list作为Y轴)绘制成直观的折线图,并集成到Streamlit应用中展示给用户。

039:使用 Matplotlib 在 Streamlit 中绘制图表 📈

在本节课中,我们将学习如何在 Streamlit 应用中集成 Matplotlib 库,以创建交互式的数据可视化图表。我们将从安装必要的库开始,逐步构建一个能够实时更新、显示多组数据并具有完整图表元素的折线图应用。

概述与准备工作

首先,我们需要确保开发环境中已安装 Matplotlib 和 NumPy 这两个核心库。Matplotlib 是 Python 中强大的绘图库,而 NumPy 则用于高效处理数组数据。

以下是安装命令:

pip install matplotlib numpy

如果在安装 Matplotlib 时遇到错误,提示缺少 Microsoft Visual C++ 构建工具,你需要前往微软官方网站下载并安装这些构建工具。完成安装后,请重启你的代码编辑器(如 VS Code)。

准备工作完成后,我们可以在代码中导入这些库:

import matplotlib.pyplot as plt
import numpy as np

创建基础图表

上一节我们完成了环境配置,本节中我们来看看如何在 Streamlit 中初始化一个 Matplotlib 图形。

使用 Matplotlib 与 Streamlit 结合时,必须先实例化一个图形对象。这是确保图表能在 Web 应用中正确显示的关键步骤。

fig = plt.figure()  # 实例化一个图形对象

接下来,我们将使用店铺销售数据来绘制图表。假设我们有一个包含日期和销售额的列表。为了更灵活地处理 X 轴(日期),我们首先创建一个与日期列表长度相同的索引数组。

# 假设 dates 是日期列表
idx = np.arange(len(dates))  # 创建一个从0到len(dates)-1的数组

然后,我们可以在一个循环中,为每个选中的店铺数据绘制折线。以下是绘制单条折线的核心代码:

# 假设 shop_data 是某个店铺的 DataFrame,option 是选中的商品列名(如‘CPU’)
item_values = shop_data[option].tolist()  # 将指定列的数据转换为列表
plt.plot(idx, item_values)  # 使用索引数组作为X轴,商品数据作为Y轴绘图

绘制完成后,需要使用 Streamlit 的 st.write() 函数将图形显示在网页上。

st.write(fig)

优化图表显示

基础图表已经可以工作,但X轴显示的是数字索引而非实际日期,并且图表缺乏必要的标签和样式。本节我们将解决这些问题。

首先,使用 Matplotlib 的 xticks 函数将 X 轴的刻度标签替换为实际的日期。为了避免日期标签重叠,我们同时启用自动格式化功能。

以下是优化 X 轴显示的代码:

plt.xticks(idx, dates)  # 用日期列表替换默认的刻度标签
plt.gcf().autofmt_xdate()  # 自动调整日期标签的格式和角度,防止重叠

接着,为图表添加标题、坐标轴标签并启用网格,使图表更易读。

plt.xlabel(‘Date‘)  # 设置X轴标签
plt.ylabel(option)  # 设置Y轴标签,显示当前商品名
plt.title(f‘{option} Chart‘)  # 设置图表标题
plt.grid(True)  # 启用网格

增强图表可读性

为了让同时显示的多条折线(代表不同店铺)更容易区分,我们需要为每条线添加图例和标记点。

plt.plot() 函数中,我们可以为每条线指定一个标签(通常用店铺名)和标记样式。

以下是增强图表可读性的步骤:

  1. 在绘图时为每条线指定标签和标记。
  2. 调用 plt.legend() 函数来显示图例。

具体实现代码如下:

# 在循环内部,为每个店铺的数据绘图时
plt.plot(idx, item_values, label=file.name, marker=‘o‘)  # ‘o‘代表圆形标记,label用于图例

# 在循环外部,显示图例
plt.legend()

完成以上步骤后,我们的图表将具备完整的元素:清晰的坐标轴标签、带标记点的折线、自动定位的图例以及实时更新的能力。当用户在侧边栏选择不同的商品或店铺时,图表会立即响应并重新绘制。

总结

本节课中我们一起学习了如何在 Streamlit 应用中集成 Matplotlib 进行数据可视化。我们从安装库开始,逐步构建了一个交互式折线图应用,并对其进行了多项优化:

  • 使用 plt.figure() 实例化图形对象。
  • 利用 NumPy 数组管理 X 轴数据。
  • 通过 plt.xticks()autofmt_xdate() 优化日期显示。
  • 添加了标题、坐标轴标签和网格系统。
  • 为多条数据线配置了图例和标记点,并通过 st.write() 将最终图表渲染到网页。

你现在已经掌握了在 Streamlit 中创建基础动态图表的方法。你可以在此基础上尝试添加柱状图等其他图表类型,或结合更多 Python 模块来实现更复杂的实时数据跟踪功能。

040:Streamlit中的回调与属性

在本节课中,我们将学习Streamlit中的概念性编程,这些概念在实际应用场景中非常重要。我们将重点讨论Streamlit的回调机制。回调是在特定事件发生时执行的函数,这些事件可以是按钮点击、单选按钮选项变更或复选框状态改变等。理解回调对于构建交互式应用至关重要。

理解问题:为什么复选框不工作?

首先,我们创建一个简单的应用来演示一个常见问题。

import streamlit as st

input_name = st.text_input("Enter your name:")
submit_button = st.button("Submit")

if submit_button:
    option = st.checkbox("Want to display your name?")
    if option:
        print(input_name)

运行此应用,输入名字并点击“提交”按钮后,会出现一个复选框。然而,当你勾选复选框时,控制台并不会打印出名字,复选框本身也会消失。

这是因为Streamlit的工作机制:每当用户与交互式小部件(如复选框)交互时,整个脚本都会从头到尾重新运行。当脚本重新执行到 if submit_button: 这一行时,由于我们没有再次点击“提交”按钮,条件为假,因此复选框根本不会被创建,后续的打印逻辑也就不会执行。

解决方案:使用回调函数

为了解决上述问题,我们需要使用回调函数。回调可以改变Streamlit的执行顺序,在重新运行整个脚本之前,优先执行指定的回调函数。

Streamlit主要提供两种回调:

  • on_click:用于按钮点击事件。
  • on_change:用于交互式小部件(如复选框、单选按钮、滑块等)的状态改变事件。

以下是修改后的代码,使用 on_change 回调:

import streamlit as st

# 定义回调函数
def printer():
    print("Message from callback!")

![](https://github.com/OpenDocCN/cs-notes-pt1-zh/raw/master/docs/py-stlt-tut/img/b4693d1cc434b3603bb0267c17e8651c_3.png)

input_name = st.text_input("Enter your name:")
submit_button = st.button("Submit")

if submit_button:
    # 为复选框添加 on_change 回调
    option = st.checkbox("Want to display your name?", on_change=printer)

现在,当你勾选或取消勾选复选框时,回调函数 printer 会被触发,并在控制台打印消息。这是因为在脚本重新运行前,Streamlit会先执行回调函数。

向回调函数传递参数

在实际应用中,我们经常需要将一些数据(例如用户输入的名字)传递给回调函数。这可以通过 args 参数实现。

以下是向回调函数传递参数的示例:

import streamlit as st

# 定义回调函数,接受一个参数
def printer(name):
    print(name)

input_name = st.text_input("Enter your name:")
submit_button = st.button("Submit")

if submit_button:
    # 使用 args 参数向回调函数传递参数,参数需要以元组形式提供
    option = st.checkbox("Want to display your name?", on_change=printer, args=(input_name,))

在这段代码中,我们将 input_name 变量作为元组 (input_name,) 传递给 args 参数。回调函数 printer 则定义了一个参数 name 来接收这个值。现在,当复选框状态改变时,控制台将打印出用户输入的名字。

关键点args 的参数必须是一个元组。即使只有一个参数,也需要写成 (input_name,) 的形式,末尾的逗号是必需的。

总结

本节课我们一起学习了Streamlit中回调函数的核心概念与应用。

我们首先通过一个实例了解了为什么直接在小部件条件判断中处理逻辑会失败,其根源在于Streamlit响应交互时会重新执行整个脚本。

接着,我们引入了回调函数作为解决方案。回调函数(通过 on_clickon_change 参数指定)允许我们在脚本重新运行前执行特定逻辑,从而正确处理交互事件。

最后,我们学习了如何使用 args 参数向回调函数传递必要的数据,这使得回调函数能够访问和应用运行时的状态信息。

掌握回调机制是构建复杂、响应式Streamlit应用的基础。

041:Session States详解 🧠

在本节课中,我们将要学习Streamlit中一个至关重要的概念——Session State。它是在用户会话间共享和保存变量数据的关键工具。

概述

Session State是Streamlit中用于在不同次运行(reruns)之间为每个用户保存变量状态的方法。当您刷新浏览器或与应用交互时,它能够防止数据丢失,从而极大地简化开发工作。

一个简单的例子:切换按钮文本

为了理解Session State的工作原理,我们先创建一个简单的程序。这个程序包含一个按钮,点击按钮时,按钮上显示的文本(一个表情符号)会在🐶和🐱之间切换。

首先,我们尝试不使用Session State的写法:

import streamlit as st

text = "🐶"  # 初始文本为狗表情
button = st.button(text)  # 创建一个按钮

if button:
    text = "🐱"  # 当按钮被点击时,尝试将文本改为猫表情

运行这段代码,点击按钮,你会发现没有任何变化。这是因为每次与Streamlit应用交互(如点击按钮)时,整个脚本都会从头到尾重新执行。重新执行时,变量text又被重置为初始值"🐶",然后才渲染页面,所以我们永远看不到"🐱"

上一节我们介绍了不使用Session State时遇到的问题,本节中我们来看看如何使用Session State来解决它。

使用Session State解决问题

Session State允许我们在应用重新运行后保留变量的值。使用它通常需要两个步骤:

  1. 初始化Session State变量。
  2. 检查并更新Session State变量,执行业务逻辑。

以下是修改后的代码:

import streamlit as st

# 第一步:初始化Session State变量
if 'clicked' not in st.session_state:
    # 如果‘clicked’变量不存在于session_state中,则创建它,初始值为False
    st.session_state.clicked = False

# 根据Session State中的值决定按钮的初始文本
if st.session_state.clicked:
    text = "🐱"
else:
    text = "🐶"

# 创建按钮
button = st.button(text)

# 第二步:检查并更新Session State
if button:
    # 当按钮被点击时,切换‘clicked’的状态
    if st.session_state.clicked == False:
        st.session_state.clicked = True  # 切换到猫
    else:
        st.session_state.clicked = False  # 切换回狗

    # 重要:使用st.rerun()来触发脚本重新运行,以更新按钮文本
    st.rerun()

代码逻辑解析:

  1. 应用首次运行时,st.session_state中没有‘clicked’键,因此将其创建并设为False。按钮文本初始化为“🐶”
  2. 用户点击按钮,button变为True,进入if button:代码块。
  3. 检查st.session_state.clicked的值。首次点击时它为False,所以将其改为True
  4. 调用st.rerun()强制Streamlit重新运行整个脚本。
  5. 脚本重新运行时,因为st.session_state.clicked已经存在且值为True,所以按钮文本被设置为“🐱”
  6. 再次点击按钮,st.session_state.clickedTrue变回False,重新运行后按钮文本变回“🐶”

通过这种方式,按钮的状态得以在多次应用重新运行间保留。

核心方法与概念

以下是使用Session State时的一些关键点:

  • 访问与赋值:可以使用st.session_state.key_namest.session_state[‘key_name’]来访问和设置变量。
  • 检查存在性:使用if ‘key_name’ not in st.session_state:来初始化变量,避免覆盖已存在的值。
  • 触发更新:更改Session State的值后,通常需要调用st.rerun()来让应用响应新的状态。

总结

本节课中我们一起学习了Streamlit的Session State。我们了解到,由于Streamlit应用在交互时会重新执行脚本,普通变量无法保持状态。Session State提供了一种在用户会话期间持久化存储数据的机制。通过初始化、检查并更新Session State变量,我们可以构建出能够记住用户操作和数据的交互式应用。这是开发复杂Streamlit应用的基础。

042:Streamlit缓存机制详解 🚀

在本节课中,我们将要学习Streamlit中一个至关重要的性能优化工具——缓存机制。缓存能够显著提升应用的运行效率,尤其是在处理复杂计算或数据加载时。

什么是缓存?

缓存是一种技术,它存储给定资源的副本,并在请求时将其返回,以实现更快的功能执行。在Streamlit中,缓存机制允许你存储函数的计算结果。当函数再次被调用时,如果输入参数没有变化,Streamlit会直接返回缓存的结果,而不是重新执行整个函数。这对于执行时间较长的函数(例如数据处理、模型训练)非常有用。

一个简单的例子

为了理解缓存的工作原理,我们先创建一个没有缓存的函数作为对比。

以下是一个模拟耗时操作的函数:

import time
import streamlit as st

def printer(message):
    # 模拟一个耗时3秒的操作
    time.sleep(3)
    return message

st.write(printer(“Hello, Streamlit Cache!”))

每次运行这个应用,你都需要等待3秒钟才能看到输出信息。在开发或用户交互频繁时,这种延迟会严重影响体验。

使用@st.cache装饰器

现在,我们来看看如何使用Streamlit的缓存功能来优化上述函数。只需在函数定义前添加@st.cache装饰器即可。

import time
import streamlit as st

@st.cache  # 添加缓存装饰器
def printer(message):
    time.sleep(3)
    return message

![](https://github.com/OpenDocCN/cs-notes-pt1-zh/raw/master/docs/py-stlt-tut/img/0c434b40cc03bf81e5852a6b68a09a4b_3.png)

![](https://github.com/OpenDocCN/cs-notes-pt1-zh/raw/master/docs/py-stlt-tut/img/0c434b40cc03bf81e5852a6b68a09a4b_4.png)

st.write(printer(“Hello, Streamlit Cache!”))

添加装饰器后,第一次运行函数时,它仍然需要3秒来执行并返回结果。但Streamlit会将该结果与当前的函数名和输入参数(message)一起存储起来。

关键点:当你第二次、第三次或更多次地运行应用(或触发函数调用)时,如果输入的message参数没有改变,Streamlit将不会执行函数体内的代码(即不会等待3秒),而是直接返回之前缓存的结果。这极大地提升了响应速度。

缓存的管理与验证

你可能会好奇如何验证缓存是否生效,或者如何清除缓存。

  1. 验证缓存:运行上述带缓存的代码。第一次运行会等待3秒。刷新页面后,消息应立即显示,没有延迟,这证明缓存起了作用。
  2. 清除缓存:在运行的Streamlit应用页面,点击右上角的汉堡菜单(☰),你会找到“Clear cache”选项。点击它,然后刷新页面,你会发现应用又需要等待3秒才能显示结果,因为缓存已被清空。

处理缓存警告

有时,在缓存函数内部使用st.write等Streamlit命令可能会触发警告。为了解决这个问题,@st.cache装饰器提供了一个suppress_st_warning参数。

以下是一个会产生警告的例子:

@st.cache
def printer(message):
    st.write(“Function is running...”)
    time.sleep(3)
    return message

为了避免警告,可以将suppress_st_warning参数设置为True

@st.cache(suppress_st_warning=True)
def printer(message):
    st.write(“Function is running...”)
    time.sleep(3)
    return message

设置之后,警告信息将不再显示。请注意,在缓存函数内部使用st.write等命令时,它们只在函数首次执行(即缓存未命中)时运行。当从缓存中读取结果时,这些命令不会被执行。因此,上例中的“Function is running...”信息只会在第一次调用时出现。

缓存的应用场景

Streamlit缓存机制在以下场景中尤为重要:

  • 数据加载:从数据库或大型CSV文件加载数据。
  • 复杂计算:进行数据预处理或特征工程。
  • 机器学习:加载训练好的模型或进行预测。例如,使用Scikit-learn、TensorFlow或PyTorch时,模型加载和初始化可能很耗时,缓存可以避免每次交互都重复这个过程。
  • API调用:调用外部API获取数据,可以缓存结果以避免频繁请求并节省时间。

总结

本节课中我们一起学习了Streamlit的核心功能——缓存机制。我们了解了缓存的基本概念,即存储计算结果以加速后续相同的请求。通过@st.cache装饰器,我们可以轻松地为任何函数添加缓存能力,从而优化应用性能。我们还学习了如何管理缓存(清除缓存)以及如何处理与Streamlit命令相关的缓存警告。掌握缓存是构建高效、响应迅速的Streamlit应用的关键一步。在接下来的教程中,我们将探索Streamlit的其他功能。

043:在Streamlit中使用自定义HTML 🎨

在本节课中,我们将学习如何在Streamlit Web应用中嵌入自定义HTML代码。我们将介绍两种主要方法,并详细讲解如何使用components.html函数来添加样式和交互性。

概述

Streamlit提供了两种添加自定义HTML的方式。一种是通过st.markdown函数,这是一种非官方的方法。另一种是使用streamlit.components.v1.html函数,这是官方推荐的方式。本节课我们将重点学习后者的使用方法。

导入必要模块

首先,我们需要导入Streamlit及其组件模块。以下是导入代码:

import streamlit as st
from streamlit.components.v1 import html as components_html

使用components.html函数

components.html函数与st.markdown函数的一个主要区别在于,它提供了三个额外的属性来控制HTML内容的显示。这些属性是:

  • width: 定义HTML内容的宽度。
  • height: 定义HTML内容的高度。
  • scrolling: 启用或禁用滚动功能。

以下是该函数的基本用法:

components_html(html_code, width=None, height=None, scrolling=False)

编写基础HTML

我们可以将HTML代码作为字符串传递给components.html函数。对于简短的代码,可以使用双引号;对于较长的代码,建议使用三引号以便在多行中编写。

以下是一个创建标题和段落的示例:

html_content = """
<div>
    <h1>这是标题</h1>
    <p>这是一段示例文本。Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>
"""

components_html(html_content, height=400)

为HTML添加CSS样式

我们可以通过三种方式为嵌入的HTML添加CSS样式:内联样式、内部样式表和外部样式表。本节将介绍内部和外部样式表的方法。

使用内部样式表

内部样式表将CSS规则直接写在HTML文档的<style>标签内。以下是如何为标题添加样式的示例:

styled_html = """
<style>
    .my-heading {
        background-color: lightblue;
        color: darkblue;
        text-align: center;
        padding: 10px;
        border-radius: 5px;
    }
</style>
<div>
    <h1 class="my-heading">这是带样式的标题</h1>
    <p>这是一段示例文本。</p>
</div>
"""

![](https://github.com/OpenDocCN/cs-notes-pt1-zh/raw/master/docs/py-stlt-tut/img/66fb7a821ab49a4a2b579e14a7920efc_10.png)

![](https://github.com/OpenDocCN/cs-notes-pt1-zh/raw/master/docs/py-stlt-tut/img/66fb7a821ab49a4a2b579e14a7920efc_11.png)

components_html(styled_html, height=400)

使用外部样式表

当CSS样式非常复杂时,最好将其保存在单独的文件中。以下是加载外部CSS文件的步骤:

  1. 创建一个CSS文件(例如style.css)并定义样式规则。
  2. 在Python代码中读取该文件。
  3. 将读取的CSS内容嵌入到HTML的<style>标签中。

style.css 文件内容:

.my-heading {
    background-color: lightgreen;
    color: darkgreen;
    text-align: center;
    padding: 15px;
    border-radius: 8px;
}

Python 代码:

# 读取外部CSS文件
with open('style.css', 'r') as file:
    css_content = file.read()

# 将CSS内容嵌入到HTML中
external_styled_html = f"""
<style>
{css_content}
</style>
<div>
    <h1 class="my-heading">使用外部样式的标题</h1>
    <p>这段文字的样式来自外部CSS文件。</p>
</div>
"""

![](https://github.com/OpenDocCN/cs-notes-pt1-zh/raw/master/docs/py-stlt-tut/img/66fb7a821ab49a4a2b579e14a7920efc_19.png)

components_html(external_styled_html, height=400)

控制显示区域:宽度、高度与滚动

components.html函数的widthheightscrolling参数非常有用,可以精确控制HTML内容在应用中的显示方式。

  • 设置固定高度: 当内容超出设定高度时,如果未启用滚动,超出的部分将被隐藏。
  • 启用滚动: 将scrolling参数设置为True,可以在内容超出设定高度时显示滚动条。
# 示例:创建一个带滚动条的长内容区域
long_html = """
<div>
    <h2>长内容示例</h2>
    <p>很多行文本...</p>
    <!-- 此处有很多行文本 -->
</div>
"""

# 高度设置为300像素,并启用滚动
components_html(long_html, height=300, scrolling=True)

总结

本节课我们一起学习了在Streamlit中嵌入自定义HTML的官方方法。我们了解了如何使用streamlit.components.v1.html函数,掌握了编写基础HTML结构、通过内部和外部样式表添加CSS样式,以及利用widthheightscrolling参数控制内容显示区域的核心技能。通过结合HTML和CSS,你可以在Streamlit应用中创建高度定制化的视觉组件。

044:在 Streamlit 中使用自定义 CSS 🎨

在本节课中,我们将学习如何为 Streamlit 应用程序添加自定义 CSS 样式,以改变其外观和布局。我们将通过修改一个 URL 缩短器应用来演示整个过程,从检查元素到编写并嵌入 CSS 代码。

概述

我们将通过以下步骤学习如何自定义 Streamlit 应用的样式:

  1. 运行应用并使用浏览器开发者工具检查其 HTML 和 CSS 结构。
  2. 识别需要修改的特定元素及其类名。
  3. 创建一个独立的 CSS 文件并编写样式规则。
  4. 使用 Streamlit 的 Markdown 组件将 CSS 样式内部嵌入到应用中。
  5. 应用各种 CSS 属性(如背景色、字体、边框)来美化应用。

检查应用结构

首先,运行你的 Streamlit 应用程序。为了理解其结构,我们需要使用浏览器的开发者工具。

以下是操作步骤:

  • 在浏览器中打开你的 Streamlit 应用。
  • 在页面上右键点击,选择“检查”或“Inspect”。
  • 这将打开开发者工具,显示应用的 HTML 和 CSS 代码。

通过检查,我们可以找到想要修改的元素的类名或标签。例如,要修改应用标题,可以右键点击标题,选择“检查元素”,找到对应的 <span> 标签及其类名。

创建并编写 CSS 文件

找到目标元素的类名后,我们可以在项目中创建一个单独的 CSS 文件来编写样式规则。

  1. 在项目目录中创建一个新文件,例如 designing.css
  2. 在 CSS 文件中,我们通过选择器来定位元素并定义样式。选择器可以是标签名、类名或 ID。
    • 使用类名选择器时,需要在类名前加一个点 .,例如 .className
    • 如果元素有多个类,需要用点替换空格,例如 .class1.class2

以下是一个基本的 CSS 规则结构:

span.class1.class2 {
    background-color: blueviolet;
    color: lightyellow;
    border-radius: 20px;
    font-family: Impact;
}

在这个例子中,我们修改了背景色、文字颜色、边框圆角和字体。

将 CSS 嵌入 Streamlit 应用

创建好 CSS 文件后,我们需要将其内容嵌入到 Streamlit 应用中。我们将使用内部样式表的方式,通过 Markdown 组件来实现。

上一节我们介绍了如何编写 CSS 文件,本节中我们来看看如何将其嵌入到 Python 代码中。

操作步骤如下:

  1. 在 Python 脚本中,使用 open() 函数读取 CSS 文件的内容。
  2. 使用 st.markdown() 函数,并设置 unsafe_allow_html=True 参数,将 CSS 代码包裹在 <style> 标签中插入到页面。

以下是关键代码示例:

import streamlit as st

# 读取 CSS 文件内容
with open(‘designing.css’) as source_design:
    css_content = source_design.read()

![](https://github.com/OpenDocCN/cs-notes-pt1-zh/raw/master/docs/py-stlt-tut/img/060a5be1fdc466ad54d1f4de77167c30_28.png)

![](https://github.com/OpenDocCN/cs-notes-pt1-zh/raw/master/docs/py-stlt-tut/img/060a5be1fdc466ad54d1f4de77167c30_29.png)

# 使用 Markdown 嵌入 CSS 样式
st.markdown(f‘<style>{css_content}</style>’, unsafe_allow_html=True)

这样,CSS 文件中定义的样式就会应用到整个 Streamlit 应用上。

使用 CSS 选择器定位嵌套元素

有时我们需要修改的元素没有直接的类名或 ID。这时,可以使用 CSS 选择器通过其父元素来定位。

例如,要修改一个在特定 <div> 内的 <hr>(水平线)标签的颜色,可以按以下步骤操作:

  1. 在开发者工具中找到包含 <hr><div> 的类名。
  2. 在 CSS 中使用后代选择器(空格)或子元素选择器(>)来定位。

以下是使用子元素选择器的 CSS 代码示例:

/* 选择具有特定类名的 div 下的直接子元素 hr */
div.parentClass > hr {
    background-color: red;
}

通过这种方式,我们可以精确地控制页面中任何元素的样式。

探索更多 CSS 属性

CSS 提供了丰富的属性来控制页面样式。你可以尝试修改以下属性来进一步定制你的应用:

以下是你可以尝试修改的一些常见 CSS 属性:

  • padding / margin: 控制元素的内边距和外边距。
  • font-size: 改变字体大小。
  • text-align: 设置文本对齐方式(如居中)。
  • box-shadow: 为元素添加阴影效果。
  • width / height: 调整元素的宽度和高度。

建议访问 W3Schools CSS 教程 来学习和实验更多属性。

总结

本节课中我们一起学习了如何为 Streamlit 应用添加自定义 CSS 样式。我们从检查应用结构开始,学会了如何识别元素并获取其类名。接着,我们创建了独立的 CSS 文件,并编写了样式规则。然后,我们通过 st.markdown() 将 CSS 代码内部嵌入到应用中。最后,我们还探讨了如何使用 CSS 选择器定位复杂元素,并鼓励大家尝试更多 CSS 属性来创造独特的应用界面。通过自定义 CSS,你可以让 Streamlit 应用摆脱默认样式,展现出个性化的视觉效果。

045:在 Streamlit 中添加动画 🎬

在本教程中,我们将学习如何在 Streamlit 网页应用中添加动画。我们将介绍两种主要方法:使用 iframe 函数嵌入外部动画,以及使用 streamlit-lottie 库加载本地 JSON 动画文件。通过本课,你将能够为你的应用增添生动的视觉效果。

准备工作 🛠️

首先,我们需要清理之前的代码,并导入必要的组件。我们将从 streamlit.components.v1 导入 iframe 功能。

import streamlit as st
import json
from streamlit.components.v1 import iframe
from streamlit_lottie import st_lottie

上一节我们介绍了导入组件,本节中我们来看看如何具体使用它们来添加动画。

方法一:使用 iframe 嵌入动画 🌐

iframe 函数允许我们在 Streamlit 应用中嵌入外部的 HTML 和 CSS 文件。这是一种快速集成网络动画的简便方法。

以下是使用 iframe 的步骤:

  1. 访问提供免费动画的网站,例如 LottieFiles
  2. 注册并登录后,在“发现”选项卡中找到“免费动画”部分。
  3. 选择一个你喜欢的动画(例如,一只猫的动画)。
  4. 点击该动画,进入详情页,找到“嵌入”选项下的 iframe 代码。
  5. 复制 iframe 标签中的 src 属性值(即网址链接)。
  6. 在你的 Streamlit 代码中,使用 iframe 函数并传入该链接。
# 示例:嵌入一个猫的动画
cat_animation_url = "https://assets9.lottiefiles.com/packages/lf20_ktwnwv5m.json"
iframe(cat_animation_url, height=400)

保存并运行应用,你将看到嵌入的动画在页面中播放。

方法二:使用 streamlit-lottie 加载 JSON 动画 📄

第二种方法需要安装 streamlit-lottie 库,并直接使用动画的 JSON 文件。这种方法提供了更多控制选项。

以下是具体操作流程:

  1. 首先,通过终端安装 streamlit-lottie 库。
    pip install streamlit-lottie
    
  2. 在 LottieFiles 网站上,找到想要的动画并点击下载按钮,选择“Lottie JSON”格式进行下载。
  3. 将下载的 .json 文件放入你的项目目录中。
  4. 在代码中导入 st_lottie 函数,并使用 Python 的 json 库读取动画文件。
  5. 将读取的 JSON 数据传递给 st_lottie 函数以显示动画。
# 1. 读取本地的 JSON 动画文件
with open(‘animation.json‘, ‘r‘) as f:
    animation_data = json.load(f)

# 2. 使用 st_lottie 显示动画
st_lottie(animation_data, speed=1, reverse=False, loop=True, quality=‘high‘, height=400, key=‘cat‘)

st_lottie 函数提供了丰富的参数来控制动画,例如播放速度 (speed)、是否循环 (loop)、画质 (quality) 以及高度宽度等。你可以根据需要调整这些参数。

总结与回顾 📝

本节课中我们一起学习了在 Streamlit 中添加动画的两种有效方法。

  • 使用 iframe:适合快速嵌入来自网络的现成动画,操作简单直接。
  • 使用 streamlit-lottie:通过加载本地 JSON 文件,提供了对动画属性(如速度、循环、尺寸)更精细的控制。

你可以根据项目需求选择合适的方法。尝试将动画放入不同的布局(如列 st.columns 中),调整其属性,并组合其他 Streamlit 组件来创建更复杂、更具交互性的应用。多加练习是掌握这些技能的关键。

posted @ 2026-03-29 09:25  布客飞龙II  阅读(162)  评论(0)    收藏  举报