三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

基于WorkBuddy与Streamlit的自动化信息筛选系统:从装修家电选购到通用决策辅助

基于WorkBuddy与Streamlit的自动化信息筛选系统:从装修家电选购到通用决策辅助

1. 项目概述:当装修遇上自动化

最近刚忙完家里的装修,选家电这一步差点把我逼疯。面对琳琅满目的品牌、型号、参数和铺天盖地的评测,我这个装修小白感觉像在信息海洋里溺水。预算就五万块,想配齐全屋家电——冰箱、洗衣机、电视、空调、热水器,还得兼顾颜值、功能和性价比,这简直是个不可能完成的任务。刷了几天小红书,收藏夹里塞了上百篇笔记,越看越乱,笔记里的“绝绝子”和“踩大雷”让我完全无法判断。

就在我快要放弃,准备闭眼瞎买的时候,一个想法冒了出来:能不能让机器来帮我做这个枯燥的信息筛选和决策工作?作为一个有点Python基础的“技术半吊子”,我决定自己动手。我不想学爬虫去硬刚平台规则,那太复杂且容易出问题。我的思路更取巧:既然小红书本身有强大的搜索功能,那我能不能模拟一个“超级用户”,让它不知疲倦地执行搜索、阅读、分析和总结,最后给我一个清晰的购买清单?

这就是“WorkBuddy”出场的时候。它不是一个现成的软件,而是我基于一系列技术工具组合起来的一个自动化工作流。核心目标很明确:自动化收集小红书上的家电评测信息,并通过预设的评分逻辑,帮我分析出预算内最具性价比的选购方案。最终,这个自制的“数字装修顾问”高效地刷了500多篇相关笔记,输出了一份让我非常满意的采购清单,成功把控住了五万块的预算。整个过程,就像拥有一个不知疲倦、绝对理性的购物伙伴。

2. 核心思路与技术选型

这个项目的核心逻辑并不复杂,可以概括为“搜索 -> 获取 -> 解析 -> 评分 -> 输出”。但每一步具体如何实现,选用什么工具,里面有不少讲究。我的原则是:尽量利用现有、易用的工具,避免从零造轮子,快速实现核心功能。

2.1 为什么是 WorkBuddy + Streamlit,而不是纯 Python 脚本?

提到自动化,很多人第一反应是写Python爬虫。但对于小红书这样的动态内容平台,直接爬取网页(HTML)结构复杂且变动频繁,需要不断维护解析规则,对于非专业开发者来说门槛高、效率低、风险大。更关键的是,我的需求是“浏览和筛选信息”,而不是“批量下载数据”。

因此,我选择了WorkBuddy作为核心执行器。你可以把它理解为一个能够模拟人在电脑上操作(点击、输入、滚动等)的自动化助手。我的方案是:让 WorkBuddy 控制浏览器,打开小红书网页版,执行我设定的搜索关键词(如“冰箱 选购 2024”、“海尔洗衣机 测评”),然后滚动页面,获取屏幕上展示的笔记标题、首段文字、点赞收藏数等公开可见信息。这种方式更接近于真实用户行为,规避了直接调用未公开API的风险。

那么,为什么还要Streamlit呢?因为我们需要一个界面来配置任务、查看结果。纯命令行操作对后续调整关键词、查看分析结果不友好。Streamlit 能以极简的代码将 Python 脚本转化为交互式 Web 应用。我可以用它来:

  1. 设置搜索关键词列表和预算。
  2. 启动/停止 WorkBuddy 自动化任务。
  3. 实时展示收集到的笔记摘要和初步分析。
  4. 最终生成并展示可视化报告和推荐清单。

技术栈全景图:

  • 前端/交互层 (Streamlit):提供用户操作界面,接收参数,展示结果。
  • 自动化层 (WorkBuddy):执行浏览器自动化操作,模拟搜索和内容采集。
  • 数据处理层 (Python + Pandas):清洗、解析 WorkBuddy 抓取回来的文本,提取品牌、型号、价格、评价关键词。
  • 决策模型层 (Python 逻辑):基于规则(如品牌权重、口碑关键词、预算匹配度)给每个产品打分。
  • 数据交换格式 (JSON):用于在 WorkBuddy 和 Python 数据处理脚本之间传递采集到的结构化数据。

2.2 关键工具与数据流转设计

整个系统的运行始于我在 Streamlit 界面上点击“开始收集”。接下来会发生:

  1. Streamlit 将配置参数(关键词列表、任务时长)生成一个 JSON 配置文件。这个 JSON 文件是衔接 Streamlit 和 WorkBuddy 的“任务工单”。

    { "search_keywords": ["嵌入式冰箱 推荐", "洗烘套装 性价比", "75寸电视 测评"], "max_notes_per_keyword": 50, "scroll_times": 10 }
  2. Python 脚本调用 WorkBuddy,并传入这个 JSON 配置文件。WorkBuddy 读取配置,启动浏览器,开始自动化作业。

  3. WorkBuddy 执行任务,并将采集到的原始数据(笔记标题、正文片段、互动数据)保存为新的 JSON 文件。这里采集的是页面可见文本,不涉及图片下载或深度内容。

  4. Python 数据处理脚本读取 WorkBuddy 产出的 JSON 文件,进行文本清洗和关键信息提取。例如,使用正则表达式从文本中查找“¥4599”、“海尔”、“零嵌”等模式。

  5. 提取的信息被送入评分模块,结合我设定的规则(如品牌知名度加分、出现“噪音大”减分、价格超预算减分等)进行计算。

  6. 最终,所有产品的评分、摘要和原始笔记链接被整理好,由 Streamlit 界面渲染成清晰的表格和图表展示给我。

注意:这个方案的核心是自动化浏览与公开信息分析,而非大规模数据爬取。务必控制请求频率,模拟真人操作间隔(如每次滚动后随机等待3-5秒),避免给目标服务器造成负载压力,这既是技术伦理,也是保证任务能稳定运行的前提。

3. 实操搭建:从零到一的步骤拆解

下面我来详细拆解如何一步步搭建这个系统。你可以跟着做,也可以根据你的具体需求(比如选数码产品、选旅游目的地)调整其中的逻辑。

3.1 基础环境准备与工具安装

工欲善其事,必先利其器。首先需要配置好开发环境。

1. Python 环境安装与配置:这是所有工作的基础。建议直接安装最新稳定版的 Python 3.10 或 3.11。

  • Windows/macOS 用户:访问 Python 官网下载安装包,安装时务必勾选 “Add Python to PATH” 选项,这样才能在命令行中直接使用python命令。
  • 验证安装:打开终端(Windows 是 CMD 或 PowerShell,macOS 是 Terminal),输入python --version,能显示版本号即成功。

2. 安装必要的 Python 库:在终端中,使用 pip(Python 包管理器)一键安装我们所需的库。建议先创建一个专属的项目文件夹,并在该文件夹下操作。

# 安装 Streamlit,用于构建界面 pip install streamlit # 安装 Pandas,用于数据处理和分析 pip install pandas # 可选但推荐:安装 Jupyter Notebook,用于交互式地调试数据处理代码 pip install jupyter

3. WorkBuddy 的部署与准备:WorkBuddy 的具体安装方法因其版本和来源而异。你需要根据找到的可靠教程或官方指南进行安装。通常,它可能是一个需要安装的桌面应用,也可能是一个命令行工具。确保它能被你的系统调用即可。关键一步是:找到并测试 WorkBuddy 的“命令执行”或“脚本加载”功能。我们的 Python 脚本最终需要能启动它并传递参数。

4. 代码编辑器选择:VS Code 是绝佳选择,轻量且插件丰富。安装 Python 扩展后,它能提供智能提示、调试等功能,极大提升效率。

3.2 Streamlit 控制面板开发

Streamlit 的哲学是“用脚本创建应用”。我们创建一个名为app.py的文件。

1. 构建基础界面:

import streamlit as st import json import subprocess import pandas as pd st.set_page_config(page_title="家电选购小助手", layout="wide") st.title("🏠 全屋家电智能选购分析平台") st.markdown("输入你的需求与预算,让自动化工具帮你刷遍小红书,生成分析报告。") # 侧边栏用于输入配置 with st.sidebar: st.header("任务配置") budget = st.number_input("总预算(元)", min_value=10000, max_value=100000, value=50000, step=5000) # 多行文本输入关键词,每行一个 keyword_input = st.text_area( "搜索关键词(每行一个)", value="冰箱 选购 2024\n洗烘套装 推荐\n游戏电视 测评\n空调 省电 静音\n燃气热水器 零冷水", height=150 ) search_keywords = [k.strip() for k in keyword_input.split('\n') if k.strip()] # 任务控制按钮 col1, col2 = st.columns(2) with col1: start_btn = st.button("🚀 开始收集数据", type="primary") with col2: analyze_btn = st.button("📊 分析已有数据", type="secondary")

这段代码创建了一个带有标题、预算输入框、关键词输入区和两个按钮的Web界面。侧边栏是控制中心,主区域将用来展示结果。

2. 生成任务配置(JSON):当点击“开始收集数据”时,我们需要将用户的输入转化为 WorkBuddy 能读懂的命令。

if start_btn: if not search_keywords: st.warning("请至少输入一个搜索关键词!") else: # 1. 准备任务配置 task_config = { "budget": budget, "search_keywords": search_keywords, "max_notes": 30, # 每个关键词最多收集的笔记数 "output_file": "collected_data.json" # 指定输出文件 } # 2. 将配置保存为JSON文件 config_filename = "task_config.json" with open(config_filename, 'w', encoding='utf-8') as f: json.dump(task_config, f, ensure_ascii=False, indent=2) st.success(f"任务配置已生成: `{config_filename}`") # 3. 调用 WorkBuddy (这里需要替换为你的实际调用命令) # 假设WorkBuddy可以通过命令行接收一个配置文件路径 workbuddy_cmd = ["path/to/your/workbuddy", "run", config_filename] try: # 使用subprocess启动外部程序 st.info("正在启动 WorkBuddy 进行数据收集,请耐心等待...") # 这里为了演示,我们模拟一个过程。实际应取消注释下一行。 # process = subprocess.Popen(workbuddy_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # stdout, stderr = process.communicate(timeout=300) # 设置超时 st.warning("实际运行需配置真实的 WorkBuddy 命令路径。") # 模拟一个成功的结果文件,用于后续演示 with open("collected_data.json", 'w', encoding='utf-8') as f: json.dump([], f) # 先创建一个空文件 st.balloons() st.success("数据收集任务已提交完成!请点击‘分析已有数据’查看结果。") except FileNotFoundError: st.error("未找到 WorkBuddy 程序,请检查路径配置。") except subprocess.TimeoutExpired: st.error("数据收集任务超时,可能遇到网络问题或需要调整 WorkBuddy 脚本。")

实操心得:在开发初期,可以先注释掉实际调用 WorkBuddy 的代码(subprocess.Popen那部分),用模拟数据来快速构建和测试 Streamlit 前端的数据展示功能。前后端解耦开发效率更高。

3.3 WorkBuddy 自动化采集脚本编写

这是项目的核心引擎。你需要为 WorkBuddy 编写一个脚本(可能是.js.py或其他格式,取决于 WorkBuddy 支持的类型),告诉它具体如何操作浏览器。

脚本核心逻辑伪代码:

  1. 读取task_config.json文件。
  2. 打开浏览器,访问小红书网页版并登录(如需)。
  3. 对于config中的每一个keyword
    • 在搜索框输入关键词并回车。
    • 等待页面加载。
    • 循环执行“滚动页面”动作 N 次(scroll_times),让更多笔记加载出来。
    • 在每次滚动后,使用 WorkBuddy 提供的元素选择方法,获取当前视窗内所有笔记卡片的标题、正文开头部分、点赞数、收藏数。
    • 将这些信息临时存储在一个列表里。
  4. 去重处理(避免同一篇笔记因多次滚动被重复采集)。
  5. 将最终采集到的笔记列表,按照约定的格式保存到collected_data.json文件中。

一个简化的数据格式示例:

[ { "id": "note_001", "keyword": "冰箱 选购 2024", "title": "预算5000买冰箱?看这一篇就够了!", "snippet": "研究了市面上十款主流冰箱,最后选了这款...零嵌设计真香,噪音几乎听不见。", "likes": 1500, "collected": 320, "url": "https://www.xiaohongshu.com/...", "collected_time": "2024-05-20 10:30:00" }, // ... 更多笔记 ]

注意事项:小红书网页结构可能变更,因此用于定位笔记卡片的“选择器”(如CSS Selector)需要根据实际情况调整。编写 WorkBuddy 脚本时,应加入更多的等待和容错判断,确保在页面加载慢或元素缺失时脚本不会崩溃,而是记录错误并继续执行。

3.4 数据解析与评分模型构建

数据采集回来只是原材料,我们需要从中提炼出黄金信息。这部分在 Python 中完成。

1. 数据加载与清洗:

import re import pandas as pd def load_and_clean_data(filepath): with open(filepath, 'r', encoding='utf-8') as f: raw_data = json.load(f) df = pd.DataFrame(raw_data) # 基础清洗:去重、删除无内容的条目 df.drop_duplicates(subset=['title', 'snippet'], inplace=True) df = df[df['snippet'].str.len() > 10].reset_index(drop=True) return df

2. 关键信息提取(使用正则表达式):我们需要从杂乱的文本中,提取出产品品牌、型号、价格和用户评价倾向。

def extract_product_info(text): info = {'brand': None, 'model_hint': None, 'price': None, 'tags': []} # 常见品牌关键词库 brand_pattern = r'(海尔|美的|格力|小米|西门子|博世|卡萨帝|松下|LG|三星)' # 价格模式,匹配“¥”或“元”前后的数字 price_pattern = r'[¥¥](\d{3,5})[元]?|(\d{3,5})元' # 正向评价关键词 positive_words = ['推荐', '划算', '静音', '省电', '好用', '颜值高', '能装', '智能'] # 负向评价关键词 negative_words = ['避雷', '踩坑', '噪音大', '耗电', '故障', '售后差'] # 提取品牌 brand_match = re.search(brand_pattern, text) if brand_match: info['brand'] = brand_match.group(1) # 提取价格 price_match = re.search(price_pattern, text) if price_match: # 取匹配到的第一个有效数字 for group in price_match.groups(): if group: info['price'] = int(group) break # 分析评价倾向 for word in positive_words: if word in text: info['tags'].append(f'好评:{word}') for word in negative_words: if word in text: info['tags'].append(f'差评:{word}') # 简单提取可能的型号线索(通常是一串字母数字组合) model_match = re.search(r'[A-Z][A-Z]?[A-Z]?\d+-?\d*[A-Z]?', text) if model_match: info['model_hint'] = model_match.group() return info

3. 构建评分模型:这是一个基于规则的简单模型,你可以根据自己的偏好调整权重。

def calculate_score(note_row, extracted_info, total_budget): score = 50 # 基础分 # 1. 互动数据权重(点赞收藏代表热度/认可度) engagement = note_row['likes'] * 0.1 + note_row['collected'] * 0.2 score += min(engagement, 20) # 此项最高加20分 # 2. 品牌偏好(可以预设一个品牌得分字典) brand_score_map = {'海尔': 8, '美的': 7, '格力': 9, '小米': 6, '西门子': 10, '博世': 10} if extracted_info['brand'] in brand_score_map: score += brand_score_map[extracted_info['brand']] # 3. 价格合理性(越接近预算均分越高) if extracted_info['price']: avg_item_budget = total_budget / 5 # 假设5大类家电 price_diff = abs(extracted_info['price'] - avg_item_budget) # 价格差越小,得分越高 price_penalty = price_diff / avg_item_budget * 15 # 价格偏差惩罚 score -= price_penalty # 4. 评价标签加分/减分 for tag in extracted_info['tags']: if tag.startswith('好评'): score += 2 elif tag.startswith('差评'): score -= 5 return round(score, 1)

4. 应用函数并整合数据:

def process_data(df, total_budget): results = [] for idx, row in df.iterrows(): info = extract_product_info(row['title'] + ' ' + row['snippet']) score = calculate_score(row, info, total_budget) result = { '来源关键词': row['keyword'], '笔记标题': row['title'], '疑似品牌': info['brand'], '疑似型号': info['model_hint'], '提取价格': info['price'], '评价标签': ', '.join(info['tags']), '互动量(赞/藏)': f"{row['likes']}/{row['collected']}", '综合得分': score, '原文链接': row['url'] } results.append(result) result_df = pd.DataFrame(results) # 按得分降序排列 result_df.sort_values(by='综合得分', ascending=False, inplace=True) return result_df

3.5 结果展示与报告生成

回到app.py,我们完善“分析已有数据”按钮的功能。

if analyze_btn or st.session_state.get('data_loaded', False): # 尝试加载采集到的数据 try: with open("collected_data.json", 'r', encoding='utf-8') as f: collected_raw = json.load(f) if len(collected_raw) == 0: st.info("数据文件为空,请先运行数据收集任务。") else: df_raw = pd.DataFrame(collected_raw) st.subheader(f"📈 共采集到 {len(df_raw)} 条笔记摘要") # 进行数据处理和评分 result_df = process_data(df_raw, budget) st.session_state['result_df'] = result_df st.session_state['data_loaded'] = True # 展示TOP推荐 st.subheader("🏆 综合推荐榜单 (TOP 20)") st.dataframe(result_df.head(20).reset_index(drop=True), use_container_width=True) # 按家电类别简单分组(根据关键词) st.subheader("🔍 分品类筛选建议") category_keywords = { '冰箱': ['冰箱', '冷藏'], '洗衣机': ['洗衣', '洗烘', '烘干'], '电视': ['电视', '屏幕', '观影'], '空调': ['空调', '制冷', '暖气'], '热水器': ['热水器', '沐浴', '燃气'] } for cat, kws in category_keywords.items(): with st.expander(f"查看 **{cat}** 相关推荐"): # 筛选标题或关键词中包含品类词的记录 mask = result_df['来源关键词'].str.contains('|'.join(kws)) | result_df['笔记标题'].str.contains('|'.join(kws)) cat_df = result_df[mask].head(10) if not cat_df.empty: st.dataframe(cat_df[['笔记标题', '疑似品牌', '提取价格', '综合得分']]) else: st.write(f"暂无 {cat} 相关的高评分笔记,请调整关键词重新搜索。") # 提供数据下载 csv = result_df.to_csv(index=False).encode('utf-8-sig') st.download_button( label="📥 下载完整分析报告 (CSV)", data=csv, file_name=f'家电选购分析报告_预算{budget}.csv', mime='text/csv', ) except FileNotFoundError: st.error("未找到数据文件,请先运行数据收集任务。")

至此,一个完整的、具备前端交互、自动化采集、智能分析和结果展示的“装修小白自救工具”就搭建完成了。运行streamlit run app.py,你将在浏览器中看到这个应用。

4. 避坑指南与经验总结

在实际搭建和运行过程中,我遇到了不少问题,这里把关键的经验和教训分享给你。

4.1 WorkBuddy 自动化过程中的常见问题

  1. 元素定位失败:这是最常见的问题。小红书的页面结构可能更新,导致之前写的 CSS 选择器找不到元素。

    • 解决方案:使用更稳定的定位策略。优先使用idname属性,其次使用包含特定文本或类名的组合选择器。在 WorkBuddy 脚本中加入大量的try...catch或重试机制。关键技巧:可以先用浏览器的开发者工具(F12)手动检查目标元素的属性,找到最独特的标识。
  2. 页面加载缓慢或超时:网络波动或页面内容过多会导致加载慢,脚本在元素出现前就执行了操作。

    • 解决方案:在关键操作(如点击搜索按钮、等待结果加载)后,强制让脚本等待足够的时间。WorkBuddy 通常提供waitsleep函数。更好的做法是使用“显式等待”,即等待某个特定元素出现后再继续,而不是固定等待几秒。
  3. 反爬虫机制:虽然我们模拟用户行为,但过于频繁的请求仍可能触发风控,如出现验证码。

    • 解决方案:这是重中之重。必须大幅降低操作频率。在每次搜索、滚动之间,加入随机延时(如random.uniform(3, 8)秒)。将单次任务收集的笔记数量控制在合理范围(如每个关键词30-50篇)。如果遇到验证码,目前的方案很难自动处理,可能需要手动干预或暂停任务。

4.2 数据解析与评分模型的优化方向

  1. 信息提取不准:正则表达式无法覆盖所有价格、型号的表述方式(如“五千出头”、“KFR-35GW”)。

    • 解决方案:不要追求100%准确。我们的目标是辅助决策,而非生产精确数据。可以结合多个字段综合判断。例如,如果笔记标题是“海尔BCD-501WDPG使用一个月反馈”,即使正文没提价格,我们也能从标题提取“海尔”和型号“BCD-501WDPG”。可以建立一个常见品牌型号库进行匹配。
  2. 评分模型主观:最初的评分规则可能不符合你的真实偏好。

    • 解决方案:模型必须是可调的。在 Streamlit 界面中,可以增加滑块(st.slider)来动态调整“品牌权重”、“价格敏感度”、“口碑重要性”等参数,实时查看推荐列表的变化。这就是交互式应用的优势——让算法适应人,而不是人去适应算法。
  3. 数据噪音大:采集的笔记可能包含广告、无关内容。

    • 解决方案:在数据清洗阶段增加过滤规则。例如,过滤掉标题中含有“广告”、“赞助”、“#报备”等字眼的笔记。也可以根据互动数据设定阈值,比如只分析点赞数超过100的笔记,以提高信息质量。

4.3 项目扩展与进阶思路

这个基础框架有巨大的扩展潜力:

  • 情感分析进阶:使用简单的自然语言处理库(如SnowNLPTextBlob的中文文本情感分析),对笔记正文片段进行情感打分,替代基于关键词的简单标签,能更精准地判断口碑。
  • 价格监控:将识别出的产品型号与电商平台(如京东、天猫)的API或价格监控工具结合,获取实时历史价格,判断当前是否为好价。
  • 知识图谱构建:将产品、品牌、特性、评价之间的关系用图数据库存储。例如,可以查询“所有带‘零嵌’特性且价格在4000-6000元的冰箱”,实现更智能的筛选。
  • 多平台聚合:将同样的思路应用于什么值得买(SMZDM)、B站评测视频评论区等,获取更全面的信息。只需为不同平台编写对应的 WorkBuddy 采集脚本即可。

最后一点个人体会:这个项目的价值不在于做出了一个多么强大的AI,而在于它清晰地展示了一种解决问题的思路——将重复、耗时的信息搜集工作自动化,将人的智慧聚焦于制定规则和做出最终决策。它节省了我至少几十个小时的盲目浏览时间,让我从信息焦虑中解脱出来。即使最后我没有完全按照它的推荐清单购买,但这个过程极大地帮助我理清了需求、了解了市场、建立了认知框架,这五万块钱,花得心里有底多了。技术,终究是为人服务的工具。

← 返回列表