ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

用Streamlit打造多页面网站集合:从组织架构到部署上线全攻略

用Streamlit打造多页面网站集合:从组织架构到部署上线全攻略 简介一套基于Streamlit库制作的Python网站应用示例集合主要面向数据科学家、工程师及希望快速搭建交互式数据应用的开发学习者。资源通过多个可运行脚本演示了从数据导入、图表绘制到交互控件添加的完整流程帮助读者绕过复杂前端技术直接用Python实现美观的Web界面。压缩包共7个文件包含2个Python脚本和3张示例图片并附有说明文档及依赖清单整体仅518KB结构简明、便于上手。目前已有2685人学习下载。示例覆盖st.write、st.selectbox等常用API并包含图片展示、布局组织、数据处理及本地运行等场景对照脚本与说明可快速理解Streamlit的“代码即文档”理念掌握构建数据应用、自定义组件和部署分享的基本方法适合作为入门练习或项目模板。 这段时间我一直在用Streamlit搭各种小工具陆陆续续攒了十几个页面从数据清洗、报表导出到文本批量处理、模型Demo展示全都塞在同一个项目里最终拼成了一个“Streamlit网站集合”。说实话一开始我只是想找个能快速把Python脚本变成网页的方案结果现在这套集合已经成了我日常工作里最常用的一块阵地。这篇文章就围绕“用Streamlit库制作网站集合”这个主题把我从零开始搭建、踩坑、优化、上线的一套完整经验捋一遍。无论你是只想做个个人作品集还是想给团队整一个内部工具平台这篇内容都能直接参考。网上关于Streamlit的教程很多但大都是单个Demo真正讲到“多个网站如何组织、如何部署、如何避免互相干扰”的经验相对零散我这里尽量一次讲清楚。1. 网站集怎么组织我为什么选了Streamlit1.1 把零散工具收拢成一个“站点集合”最开始我的Python小工具都是孤立的脚本一个处理Excel的、一个画趋势图的、一个做关键词提取的。每次要用都得打开命令行改参数结果就是工具越写越多用起来却越来越麻烦。后来我意识到真正缺的不是更多脚本而是一个集中入口让所有工具能通过浏览器访问像网站一样有导航、有页面、有交互。Streamlit恰好就是干这个的。它不像传统Web框架那样要求你写HTML、CSS、JavaScript而是让你用纯Python描述界面组件脚本一跑本地就会起一个Web服务浏览器打开就是交互页面。更关键的是Streamlit自带多页面支持我可以在同一个项目里放进好几个独立页面左侧自动生成导航菜单整体看起来就是一个完整的“网站集合”而不是一堆散落的脚本。1.2 对比Flask、Django、Gradio之后的选择很多人问我为什么不用Flask或者Django答案很简单维护成本。用Flask做一个带交互的页面你得自己处理表单提交、路由跳转、渲染模板还要操心前端样式Django虽然功能全但对这种轻量工具集来说有点“杀鸡用牛刀”起步和学习成本都不低。Streamlit的优势在于它把“输入控件”和“输出组件”都封装好了我只需要关注Python代码本身的逻辑界面是自动生成的。我也对比过Gradio。Gradio更适合快速给模型做一个演示界面对交互流程的支持比较轻但Streamlit在数据展示、表格处理、图表联动、状态管理这些方面成熟得多还有丰富的第三方组件生态适合做一个需要长期维护、多应用集中管理的“工具站”。两句话总结就是Gradio适合演示Streamlit适合做产品。1.3 项目目录结构和导航设计一套合理的目录结构是网站集合后续不混乱的关键。我的做法是用Streamlit原生的pages/多页面模式主入口作为首页其余功能页面全部丢进pages目录每个.py文件就是一个独立子页面。my-streamlit-site/ ├── app.py # 首页入口 ├── pages/ │ ├── 1__数据分析.py │ ├── 2__Excel清洗.py │ ├── 3__文本工具.py │ └── 4__数据看板.py ├── utils/ │ ├── data_loader.py │ └── chart_helpers.py ├── requirements.txt ├── config.toml └── .streamlit/ └── secrets.tomlStreamlit会自动读取pages目录下的文件名生成左侧导航文件名前面加数字可以控制排序加Emoji可以提升辨识度。不过我不建议在文件名里放太多特殊符号部分服务器部署时容易出编码问题最好只用“数字 下划线 名称”的组合。入口首页我通常放一个总览用st.caption写一段说明用st.link_button提供跳转形成统一的门户感。2. 核心细节解析与入门要点2.1 千万别忽略“每次交互都会重跑脚本”刚上手Streamlit的人都会踩这个坑你以为页面是“控件 → 回调 → 更新页面”的经典Web模式实际上Streamlit每操作一次都会从上到下重新执行一遍整个脚本。这个机制叫“脚本重运行”它极大地简化了开发逻辑——你不需要关心状态怎么传递因为每次交互后所有代码自动刷新。但这也带来两个直接影响一是大量重复计算会导致页面卡顿所以我很快学会了用st.cache_data做缓存二是不能让耗时操作直接写在页面顶层否则每次滑动滑块都要重新跑一次全量逻辑。理解了“重运行”这个核心机制后面很多问题都能自己想明白。比如为什么按钮点击后变量不保留因为下一次运行是新的变量环境想跨交互保留数据必须借助st.session_state。2.2 缓存机制st.cache_data的正确用法st.cache_data是Streamlit性能优化的核心工具使用它的场景包括加载大数据集、调用外部API、执行耗时计算。它的原理和Python的functools.lru_cache类似第一次执行时把结果存下来之后相同参数直接读缓存。简单示例import streamlit as st import pandas as pd st.cache_data(ttl3600, show_spinnerFalse) def load_sales_data(): df pd.read_csv(sales.csv) df[date] pd.to_datetime(df[date]) return df df load_sales_data() st.dataframe(df)这里ttl3600表示缓存保留一小时过期后重新加载show_spinnerFalse可以关闭加载时的转圈动画。有一点要特别注意st.cache_data缓存的对象必须能被序列化如果你缓存的是数据库连接对象或者无法序列化的自定义类程序会报错那种场景应该用st.cache_resource。另外依赖外部文件的数据最好在函数内部读取完整数据并做必要校验避免缓存了一份“半成品”。2.3 状态管理session_state与页面交互st.session_state是Streamlit中处理跨交互数据的唯一正道。它类似浏览器的Session但每个浏览器标签页会单独分配一份状态互不干扰。常用场景是保存登录信息、记录多步骤表单中间结果、实现自定义计数器。import streamlit as st if count not in st.session_state: st.session_state.count 0 if st.button(点我加一): st.session_state.count 1 st.write(f当前计数{st.session_state.count})我特别建议菜鸟提前理解这个机制而不是直接在网上找“点击按钮后如何更新列表”的答案。如果你只是把按钮点击后的临时结果保存在普通变量里脚本一重跑就全丢了这几乎是新手最容易踩的坑。反过来当你发现某些数据在不同组件之间共享有问题时优先去查st.session_state的更新时机和生命周期。2.4 界面美化多花十分钟专业感提升一大截Streamlit默认界面是简洁风格但完全不调整就会显得“很Demo”。我常用的三个美化手段第一用st.set_page_config设置页面标题、图标和布局宽度首行就要调用。第二在.streamlit/config.toml里配置主题色、背景色、字体比每个页面重复写CSS高效得多。第三用st.markdown(html_content, unsafe_allow_htmlTrue)注入少量CSS比如自定义卡片容器和表格样式但一定要克制注入过多自定义CSS会让组件状态异常。一个比较稳妥的配置模板[theme] primaryColor #2E86AB backgroundColor #F9F9FB secondaryBackgroundColor #EDEDF0 textColor #1A1A1A font sans serif3. 实操过程从零搭一套网站集合3.1 把多页面框架真正跑起来第一步是做环境准备pip install streamlit即可建议配合虚拟环境。然后创建项目目录建立app.py和一个pages子目录。首页我通常会写成这样import streamlit as st st.set_page_config( page_title数据工具集合, page_icon, layoutwide, ) st.title(数据工具集合) st.caption(这里收录了我日常使用频率最高的几个数据处理小工具。) col1, col2 st.columns(2) with col1: st.subheader(工具列表) st.write( - 数据分析快速查看维度、趋势与异常值 - Excel清洗去重、拆列、格式标准化 - 文本工具关键词提取、词频统计、批量替换 - 数据看板实时刷新核心指标 ) with col2: st.subheader(使用说明) st.info(从左侧边栏选择工具即可开始。所有操作均在浏览器本地完成。)启动命令是streamlit run app.py浏览器打开http://localhost:8501左侧导航会自动出现pages目录下的页面。这一步跑通整个集合的地基就打好了。3.2 子应用开发实例报表中心、工具集和数据看板网站集合里我最常用的三个页面分别是“报表中心”、“文本批量处理工具集”和“数据看板”它们的定位完全不同正好覆盖了三种典型的Streamlit场景。报表中心核心是“上传Excel → 预览 → 筛选 → 下载”。关键是上传文件后用pd.read_excel读取但要限制文件大小和类型下载用st.download_button传入经过处理的DataFrame转成的字节流。一个容易忽略的点是用户上传文件的默认大小限制是200MB内部分析平台往往不够用需要在启动命令或配置中调整。文本批量处理工具集硬骨头是文件编码。用户上传的TXT可能是UTF-8、GBK或者GB18030不能只按UTF-8解码否则全是乱码。我写了一个自动识别编码的小函数优先尝试UTF-8失败时用GBK再失败就报错并提示用户手动选择编码。数据看板这里适合用st.fragment做局部刷新或者用st_autorefresh组件定时重跑页面。数据库连接用st.cache_resource缓存连接池避免每次刷新都新建连接。图表选用Plotly而不是默认的st.line_chart因为交互式缩放、悬停提示对数据探索更友好。3.3 发布上线从本地到服务器本地验证没问题后最省事的发布方式是Streamlit Community Cloud把代码推到GitHub仓库绑定项目地址它会自动安装依赖并启动。需要注意requirements.txt里写清楚依赖版本比如streamlit1.30不要裸写streamlit否则过几个月可能因为大版本更新导致组件API不兼容。如果需要部署在自有服务器上我试过的比较稳妥的方式是系统服务Docker二选一。Docker方式更干净一个简单的Dockerfile加上构建指令就能搞定。注意容器内要映射8501端口并设置--server.enableCORSfalse和--server.enableXsrfProtectionfalse否则通过反向代理访问时可能出现连接失败。我自己最终选择了systemd 服务器的方式管理因为我的数据文件都在服务器本地部署路径更直接。核心就是写一个service文件指定Python解释器和项目路径重启后自动拉起服务稳定运行了几个月没出过问题。4. 常见问题与排查技巧实录4.1 页面加载特别慢卡得像死机这几乎都出在“脚本重运行”上。每次交互都会执行整个脚本如果你的顶层代码里有耗时的完整数据加载或全量计算页面自然就卡。排查分两步第一步看控制台输出的执行时间定位最耗时的函数第二步给耗读数据的函数加st.cache_data。如果依旧卡再考虑把大表切片显示、用st.data_editor代替全量表格、加分页或者前端懒加载。4.2 中文乱码与文件编码问题中文乱码有两个来源一个是源代码文件编码文件名或中文常量出现乱码多数是文件没有保存为UTF-8另一个是读取的数据文件编码不一致比如CSV是GBK编码直接用pd.read_csv默认UTF-8读就会乱码。解决办法是读取时指定编码比如pd.read_csv(file, encodinggbk)或者用chardet自动检测编码。上传场景更要考虑多种编码不能假设对方一定给你UTF-8文件。4.3 上传文件大小受限默认最大200MB听起来不小但真要传一个几万行的Excel就很容易触顶。官方提供了两个配置项server.maxUploadSize和server.maxMessageSize单位是MB。我用Docker部署时会在启动命令里追加--server.maxUploadSize1024把限制提升到1GB。这里提醒一句如果走Nginx反向代理还要调整client_max_body_size否则两层限制夹击改Streamlit没用。4.4 按钮、输入框的值不符合直觉新手经常写if st.button(确定):然后发现页面一加载就执行了内部逻辑。原因还是脚本重运行机制按钮的返回值在每次运行时会根据当前点击状态重新计算而不是“记住”上次点击。真要记住状态得让按钮执行的结果写入st.session_state后续逻辑从session_state读取而不是依赖按钮的返回值。这也是很多教程说“按钮里的代码只在点击后执行”的表述不够准确准确说是“点击后那一次脚本运行中按钮返回True”。4.5 多用户同时使用导致数据互相污染st.session_state是按浏览器会话隔离的但全局变量、文件缓存和数据库连接不是。如果你把一个DataFrame放到模块级变量里两个用户同时访问就会串数据。解决方法是把共享数据全部放到缓存函数里并且尽量避免在页面里直接操作全局可变对象需要写文件时文件名加会话ID或时间戳避免不同用户覆盖同一个文件。4.6 排查技巧善用控制台日志和版本锁定真正遇到棘手问题时我会先去启动终端看输出Streamlit的日志比界面里的提示详细很多很多组件报错原因都会直接打印出来。其次是版本锁定Streamlit迭代很快不同版本API差异并不小如果复制网上的代码报错优先检查双方版本是否一致。我在项目的requirements.txt里会精确锁版本比如streamlit1.32.2上线前再统一升级并测试。5. 目前这套集合的扩展方向这套网站集合已经稳定运行了一段时间下一步我打算做三件事。第一接入用户权限系统用st.experimental_auth或第三方登录给不同用户开放不同功能第二增加更丰富的图表交互比如用Plotly实现联动筛选、下钻分析第三把常用组件抽成公共模块封装到utils里保持每个页面尽量短小方便后续加新工具时直接复用。最后再分享一个我个人的小习惯每个页面开头都先用st.set_page_config统一风格每个耗时函数都写清楚缓存策略每次新增页面都在首页更新说明。这套看起来不起眼但正是这些细节让一个工具集合长期维护也稳得住。如果你是第一次接触Streamlit不用急着追求炫酷效果先照着这整套流程把一个多页面网站从零跑通再逐步往里面加自己的东西你会感受到“用Python直接做网站集合”这件事确实能大大提升日常工作流效率。本文还有配套的精品资源点击获取
返回列表