Python爬虫+pandas+Flask:拆解一个数据采集展示项目
简介pythonProject.zip 是一份包含约2000个文件的Python工程压缩包适合有一定Python基础、希望研读或复用完整项目源码的开发者。压缩包整体约57.14MB文件类型以1745个py脚本为核心另有103个js、68个txt、45个c、29个h以及少量md、html、json、xml、cpp、sh文件覆盖源码逻辑、依赖说明、文本数据、C扩展、前端页面与Shell脚本等常见工程组成部分结构较为典型。内容预览中可见fortranobject.c、cpu_avx512_*.c等文件推测项目涉及科学计算或数值优化方向包含C语言扩展及面向特定CPU指令集的针对性优化适合对底层实现与性能调优感兴趣的读者深入挖掘。目前已有134人学习浏览该代码包可作为研究Python项目组织方式、C扩展接口设计或重构思路的参考样例解压后即可查看完整目录结构与源码细节便于按模块拆解学习。1. 拆开 pythonProject.zip 之前先搞清楚这是个什么工程拿到一个 pythonProject.zip解压后看到一堆 .py 文件和几个子文件夹第一反应通常是「先从哪个文件跑起来」。这个压缩包其实是一套完整的数据采集与展示小系统爬虫负责抓取公开列表页pandas 负责清洗去重和聚合统计Flask 把结果以 JSON 接口和网页表格的形式吐出来。整套东西没有中间件、没有消息队列一个 SQLite 加三个核心模块就把链路走通了。适合刚学完 Python 基础、想看看真实工程怎么组织的人也适合需要快速搭「采集 → 分析 → 展示」最小闭环的开发者当脚手架用。下面按拆包顺序讲架构、核心代码、启动步骤、避坑最后给出二次改造的具体方案。2. 工程骨架与技术选型轻量组合为什么够用2.1 技术栈requests pandas Flask全链路只用三个主力库这个项目最值得先看的一点是它没有引入重型框架。采集层用的是 requests 加 BeautifulSoup4而不是 Scrapy分析层是 pandas展示层是 Flask。常见做法是「爬虫直接上 Scrapy站点大了再上 FastAPI」但这里场景很简单目标是一个公开列表页最多翻几页数据量在千条级别。这个量级下 Scrapy 的调度器、中间件、管道全是负担反而掩盖了「一个请求怎么进来、怎么解析、怎么落库」这条主线。我一般会给这种小工程定三个选型标准一是每个模块只用一层依赖requests 管 HTTPBeautifulSoup 管解析pandas 管表格互不越界二是数据落盘用 SQLite 和 CSV零部署成本三是接口层用 Flask 而不是 Django因为这里不需要 ORM、Admin 后台和模板全家桶一个 app 对象加三个路由就够了。这套组合的代价是性能和并发都有限但作为学习项目和业务原型完全合格。2.2 目录结构不要把代码全堆在根目录解压后你会看到下面的结构这也是这个工程最容易被忽略但最值得抄的部分——它把「采集、分析、展示、工具」四条线从代码上就分开了pythonProject/ ├── requirements.txt ├── config.py ├── main.py ├── scraper/ │ ├── __init__.py │ └── collector.py ├── analysis/ │ ├── __init__.py │ └── processor.py ├── api/ │ ├── __init__.py │ └── server.py ├── utils/ │ ├── __init__.py │ ├── logger.py │ └── db.py ├── data/ │ ├── raw/ │ └── output/ └── tests/ └── test_pipeline.py根目录只留三个东西入口 main.py、全局配置 config.py、依赖清单 requirements.txt。真正的业务逻辑按职责放进了 scraper、analysis、api 三个包utils 放日志和数据库这类横切工具data 只存数据。这里有一个值得记住的约定修改一个功能时你只动对应的包不用在入口文件里翻找逻辑。比如要改采集规则进 scraper/collector.py要改统计口径进 analysis/processor.py。__init__.py在这个工程里只是把目录标记成包内容可以为空。真正起作用的是各模块内部的类和方法这一点新人常误解以为__init__.py必须写导入语句——其实 Python 3.3 之后没有它也能用命名空间包只是显式加上能让 IDE 识别得更清楚。2.3 配置先行config.py 和 requirements.txt 的分工config.py 把一切「跑起来前要改的东西」集中到了一起这是这个小工程最实用的设计。URL、请求头、超时、休眠范围、数据库路径全部以字典形式放在一处代码里没有任何写死的链接。这样做的好处是换数据源时你不需要碰业务代码改配置即可。# -*- coding: utf-8 -*- 全局配置改数据源、调采集参数都在这里业务代码不碰。 SCRAPE_CONFIG { base_url: https://example.com/list, # 目标列表页地址 headers: { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64), }, timeout: 10, # 单次请求超时秒数 max_pages: 5, # 最多抓几页 retry_interval: 2, # 请求失败后重试等待秒数 sleep_range: (1, 3), # 两次请求之间的随机休眠区间 } DB_CONFIG { path: data/app.db, # SQLite 文件路径 }参数说明里最容易忽略的是sleep_range它是一个元组采集代码会用random.uniform(1, 3)在区间内取随机值。这个随机不是玄学是避免固定间隔请求被目标站点的限流策略识别。timeout配合重试逻辑使用请求在超时后不会立刻抛异常而是进入最多三次的重试循环重试间隔由retry_interval控制。requirements.txt 则负责锁定依赖的底线版本写法上我一般用大于等于而不是精确锁定方便在不同环境下安装requests2.28 beautifulsoup44.11 lxml4.9 pandas1.5 flask2.2注意这里显式声明了 lxml。虽然 BeautifulSoup 默认也能用 Python 标准库解析但速度慢且容错差指定 lxml 作为解析器是工程里的标准做法。requirements.txt 和 config.py 的分工可以概括成一句话前者管「装什么」后者管「怎么配」两者都改完才能跑通。3. 核心模块拆解一条数据从网页到图表的完整链路3.1 采集层 collector.py会话复用、重试、解析三段式采集模块是这个项目里代码量最大的一层核心思路是「请求、解析、翻页」分别封装成独立方法。先看完整实现# -*- coding: utf-8 -*- 采集层抓取公开列表页解析出结构化记录。 import time import random from typing import List, Dict import requests from bs4 import BeautifulSoup from config import SCRAPE_CONFIG from utils.logger import get_logger logger get_logger(collector) class Collector: 列表页采集器负责抓取、解析、翻页。 def __init__(self, base_url: str, headers: dict None): self.base_url base_url self.session requests.Session() self.session.headers.update(headers or SCRAPE_CONFIG[headers]) def fetch_page(self, page: int) - str: 抓取单页 HTML带三次重试和状态码校验。 for attempt in range(3): try: resp self.session.get( self.base_url, params{page: page}, timeoutSCRAPE_CONFIG[timeout], ) resp.raise_for_status() return resp.text except requests.RequestException as e: logger.warning(第 %s 页第 %s 次请求失败: %s, page, attempt 1, e) time.sleep(SCRAPE_CONFIG[retry_interval]) raise RuntimeError(f页面抓取失败: page{page}) def parse_page(self, html: str) - List[Dict]: 从 HTML 里抽取标题、链接、日期字段。 soup BeautifulSoup(html, lxml) items [] for node in soup.select(ul.list li): link node.find(a) if not link: continue date_node node.find(span, class_date) items.append({ title: link.get_text(stripTrue), url: link.get(href), date: date_node.get_text(stripTrue) if date_node else , }) return items def run(self, max_pages: int 5) - List[Dict]: 串行抓取多页页间随机休眠。 results: List[Dict] [] for page in range(1, max_pages 1): html self.fetch_page(page) results.extend(self.parse_page(html)) time.sleep(random.uniform(*SCRAPE_CONFIG[sleep_range])) return results逻辑上分三段看。第一段是构造函数里用requests.Session()创建会话并统一设置请求头比每次请求都重新传 headers 更高效因为 Session 会复用 TCP 连接对列表页这种连续翻页场景能明显减少握手开销。第二段是fetch_page关键在于raise_for_status()——它会把 4xx、5xx 响应变成异常避免你拿着一张 403 页面当成功数据去解析这是血泪经验不校验状态码的话很多翻车都发生在下游清洗环节而不是采集环节。第三段是parse_page用 CSS 选择器ul.list li定位每条记录的容器节点再用 find 提取字段。参数上要注意两点。params{page: page}用的是 GET 查询参数如果你的目标站是路径式分页比如/list/p2要把这行改成f{self.base_url}/p{page}。max_pages默认是 5这只是个安全默认值真实项目里应该根据目标列表的总页数来设。run方法用串行方式翻页对这个量级没问题如果以后目标站有几千页再改成线程池或换成 Scrapy 不迟。3.2 分析层 processor.py清洗与聚合的逻辑都在这采集层拿到的是一堆字典很多字段可能是空的日期格式也可能五花八门。分析模块负责把这堆半成品变成干净的表格核心是「先清洗、后聚合」两个步骤# -*- coding: utf-8 -*- 分析层pandas 清洗去重按天聚合统计。 import pandas as pd from utils.logger import get_logger logger get_logger(processor) class DataProcessor: 把采集结果转成 DataFrame执行标准分析链路。 def __init__(self, items: list): self.df pd.DataFrame(items) def clean(self) - DataProcessor: 去空、去重、日期转换返回自身支持链式调用。 self.df.dropna(subset[title, date], inplaceTrue) self.df.drop_duplicates(subset[url], inplaceTrue) self.df[date] pd.to_datetime(self.df[date], errorscoerce) self.df self.df[self.df[date].notna()] return self def aggregate_by_day(self) - pd.DataFrame: 按天统计条目数返回含 day 和 count 两列的 DataFrame。 daily self.df.copy() daily[day] daily[date].dt.date return daily.groupby(day).size().reset_index(namecount) def export_csv(self, path: str) - None: 导出清洗后的明细数据utf-8-sig 避免 Excel 乱码。 self.df.to_csv(path, indexFalse, encodingutf-8-sig) logger.info(已导出 %s 条记录到 %s, len(self.df), path)clean方法里三个操作各解决一类问题。dropna(subset[title, date])删掉关键字段为空的记录比如页面里那些没有日期的置顶项drop_duplicates(subset[url])按链接去重防止翻页过程中重复条目被采集两次pd.to_datetime(errorscoerce)把不标准的时间字符串转成统一的 datetime 类型解析不了的会变成 NaT紧接着用notna()过滤掉。这里最容易被忽视的设计是clean返回self。这样调用方可以写成DataProcessor(items).clean().aggregate_by_day()这种链式结构少写中间变量读起来也更像一条流水线。aggregate_by_day里先copy()再新增 day 列是为了避免修改原始明细数据——这是一个好习惯聚合永远不动原始表后续要重新定义统计口径时不用重新清洗。3.3 展示层 server.pyFlask 接口与简易看板展示层在这个工程里承担两个职责对外提供 JSON 接口给其他系统调用对内提供一个最简单的 HTML 表格页看结果。代码很短但把「接口返回结构化数据、页面负责渲染」这层分工表达得很清楚# -*- coding: utf-8 -*- 展示层Flask 提供 JSON 接口和简单页面。 from flask import Flask, jsonify, render_template_string from analysis.processor import DataProcessor from utils.db import load_records app Flask(__name__) app.route(/api/daily) def daily(): 返回按天聚合的统计结果供前端或其他系统消费。 records load_records() processor DataProcessor(records).clean() summary processor.aggregate_by_day() return jsonify(summary.to_dict(orientrecords)) app.route(/) def index(): 直接渲染一个简易看板页面。 import pandas as pd try: summary pd.read_csv(data/output/daily_summary.csv) rows summary.to_dict(orientrecords) except FileNotFoundError: rows [] return render_template_string(INDEX_HTML, datarows) INDEX_HTML !DOCTYPE html html headmeta charsetutf-8title采集数据看板/title/head body h1每日采集量/h1 table border1 trth日期/thth数量/th/tr {% for row in data %} trtd{{ row.day }}/tdtd{{ row.count }}/td/tr {% endfor %} /table /body /html /api/daily接口的链路是从 SQLite 读记录 → 走一遍清洗 → 聚合 → 转成 JSON 列表。to_dict(orientrecords)是关键参数它会把 DataFrame 转成[{day: 2025-01-01, count: 12}]这种结构直接能被jsonify序列化如果漏掉这个参数pandas 默认转成{列名: 值列表}的形态前端拿到的就是另一种结构。/页面则直接读上次分析落盘的 CSV用 Jinja2 模板循环渲染成表格。这种「接口实时算、页面读文件」的设计看着有点不一致其实是故意的接口面向程序调用要求数据新鲜所以每次实时计算页面面向人看数据量小、不常变读 CSV 已经足够省去每次打开页面都重算一遍的开销。真要统一把页面也改成查接口即可二三十行代码的事后面改造章节会提到。4. 跑通全流程从建虚拟环境到看到第一条数据4.1 准备环境venv 与依赖安装跑任何 Python 项目第一步都是隔离环境别直接用全局 Python 装依赖。这个工程依赖里有 pandas 这种带二进制包的库全局环境下极易和已有项目的版本冲突。虚拟环境用标准库 venv 就能建不需要装额外工具cd pythonProject python -m venv venv在 Windows 上激活命令是venv\Scripts\activatemacOS 和 Linux 上是source venv/bin/activate。激活后命令行前缀会变成(venv)这代表当前 shell 用的已经是隔离环境了。接着安装依赖pip install -r requirements.txt这里有个常见坑如果安装过程中 lxml 或 pandas 编译报错说明 pip 在尝试从源码构建。常见做法是先用国内镜像源装或者升级 pip 到最新版本再试因为新版 pip 对预编译 wheel 的选择策略更好。装完后用pip list检查一下五个核心库都在再走下一步。4.2 改配置数据源、请求参数、输出路径跑之前先改 config.py。这个工程默认连的是 example.com直接跑当然会失败所以第一步是把base_url换成你想采集的真实公开列表页。有三个参数需要根据目标站点情况调整参数默认值怎么调base_urlexample.com/list改成目标的列表页地址headers通用 UA目标站有反爬时补 Referer、Cookiemax_pages5目标页数少就调小避免抓空headers里通常只需要 User-Agent 就能通过大多数站点的基础校验。如果目标网站要求登录才能看列表那这个项目默认的匿名抓取就不够用了需要往 headers 里加 Cookie或者在 Collector 初始化时传入带 Cookie 的 headers 字典。max_pages不要盲目调大先跑一页看看返回结构确认parse_page里的ul.list li选择器能匹配到节点再把页数调上去——这个习惯能帮你省掉大半排查时间。4.3 启动与验证三条命令和一个自检清单配置改完后启动顺序是先跑数据管道再起展示服务python main.py python api/server.py第一条命令执行的是「采集 → 清洗 → 聚合 → 导出」全流程正常输出应该类似INFO [main] 开始采集 https://example.com/list INFO [collector] 完成第 1 页解析到 20 条记录 INFO [processor] 已导出 96 条记录到 data/output/items.csv INFO [main] 分析完成输出到 data/output/看到分析完成后检查data/output/目录下是否生成了items.csv和daily_summary.csv两个文件。日志是判断流程是否正常的第一手依据如果某一步日志没出现就从那一步往前查。第二条命令启动 Flask默认监听 5000 端口浏览器打开http://127.0.0.1:5000/应该能看到表格页面访问http://127.0.0.1:5000/api/daily应该返回 JSON。自检清单按顺序过一遍虚拟环境激活了吗、config.py 的 base_url 换了吗、日志里有没有 WARNING、CSV 生成了吗、接口返回的是不是合法 JSON。这五条都通过项目就跑通了。如果卡在某一步下一章就是为这些情况准备的。5. 避坑指南pythonProject 最常见的五个翻车点5.1 现象抓下来的 HTML 全是乱码或空字符串原因基本只有一个requests 自动猜测的编码不对或者页面内容是通过 JavaScript 动态渲染的requests 只拿到了空壳 HTML。判断方法是把resp.text前 500 字打印出来看如果里面是乱码就是编码问题如果内容是标准的 HTML 标签但找不到你要的数据就是动态渲染问题。解决编码问题用resp.encoding resp.apparent_encoding强制按页面 meta 声明解码或者直接指定目标站点常用的utf-8、gbk。动态渲染问题则要在parse_page之前先确认这站是不是前后端分离如果是直接找它的 JSON 数据接口往往比解析 HTML 更省事。5.2 现象pandas 报No columns to parse这条错误信息几乎都出在pd.DataFrame(items)这一步但根子在采集层。items 是空列表或者 items 里的字典字段名不一致pandas 建表时找不到预期列。解决别在分析层调回到采集层打印前三条parse_page的返回结果。如果返回空列表说明 CSS 选择器ul.list li没匹配到节点用浏览器 F12 检查目标页面实际的 DOM 结构按真实结构调整选择器。如果字段名对不上比如页面里没有classdate的节点字段会变成空字符串而不是缺失这时要在 parse 方法里做兜底而不是指望分析层处理。5.3 现象CSV 用 Excel 打开中文乱码这个问题的原因非常明确pandas 默认to_csv用的是 utf-8 编码而 Windows 版 Excel 打开 CSV 时默认按 GBK 解码两边对不上就乱码了。解决我的习惯是导出 CSV 一律用encodingutf-8-sig这个编码会在文件开头写入 BOM 标记Excel 能据此正确识别为 UTF-8。注意utf-8-sig和utf-8是有区别的只改这里就行不用动其他代码。如果你要交付给下游程序读取的话utf-8-sig也兼容不影响 pandas 和 Python 的open正常读取。5.4 现象Flask 接口 404或者启动时报端口被占用404 一般是路由问题接口路径访问错了或者server.py根本没起在新的进程里——改完代码后旧进程还在访问的是旧版本。端口占用则是另一个进程已经占用了 5000常见于上次启动没关干净。解决先netstat -ano | findstr 5000查出占用进程的 PID确认是不是自己遗留的 Flask 进程是就杀掉。404 的话访问http://127.0.0.1:5000/api/daily前先确认路由装饰器写的是app.route(/api/daily)斜杠和大小写差一个字符都不行。开发阶段可以把app.run(debugTrue)打开这样改代码自动重载也能在页面里直接看到报错堆栈。5.5 现象SQLite 报database is locked这个错误本质是多个进程同时写同一个 SQLite 文件SQLite 默认只允许一个写者。在这个工程里典型场景是采集主流程写库的同时Flask 接口也在写库或者你开了多个终端反复跑main.py。解决先检查有没有重复进程把多余的停掉。代码层面sqlite3.connect()加上timeout10参数让写入在锁等待 10 秒再放弃能解决大部分偶发冲突。如果冲突频繁说明业务已经不适合单文件 SQLite 了应该换成独立的 MySQL 或用队列串行化写入——这是判断「要不要换数据库」的一个清晰信号。6. 二次开发实战把 pythonProject 改造成自己的脚手架这个工程最大的价值是提供了一个结构清晰的基线往里面加东西比从零写快得多。最常见的三个改造方向是换数据源、加持久化、加定时任务。换数据源是最优先的改造。除了改base_url核心工作集中在parse_page的选择器上。不同网站的结构差异很大但有一步可以复用先把目标页面存成data/raw/下的本地 HTML 文件写解析逻辑时直接读本地文件调好选择器再换成线上抓取。这样调试不被网络和反爬干扰改一次跑一遍比每次都抓线上快一个量级。改完之后记得data/raw/目录本身不提交版本库在 gitignore 里把它和data/output/一起忽略掉。加持久化的话现有utils/db.py已经提供了save_records和load_records两个函数底层是 SQLite。换成 MySQL 或 PostgreSQL 只需要改这两个函数内部把sqlite3.connect换成 SQLAlchemy 引擎to_sql和read_sql的调用方式不变。pandas 对两类数据库的接口是统一的这一步的改动量比想象中小# utils/db.py 改造示例从 SQLite 换到 MySQL from sqlalchemy import create_engine engine create_engine(mysqlpymysql://user:passlocalhost/dbname) def save_records(items): import pandas as pd pd.DataFrame(items).to_sql(items, engine, if_existsappend, indexFalse) def load_records(): import pandas as pd return pd.read_sql(select * from items, engine).to_dict(orientrecords)要注意的是换成 MySQL 后原来的DB_CONFIG里的path要改成连接串database is locked这类 SQLite 特有的问题也就不存在了。另一个高频改造是定时跑采集用标准库的schedule包就能实现在main.py外面包一层循环每天固定时间执行main()跑完再自动调一次server.py里的接口刷新看板。如果以后要追赶更多站点把 Collector 的run方法改成线程池并发抓多页再在__init__里按站点传入不同 header就是一个多源采集器了。我从一个教训里养成了习惯拿到任何陌生 zip先跑一遍完整流程再读代码跑通时的日志输出就是理解代码的索引。这个工程也一样main.py的日志打印了每一步的入口和出口顺着日志找对应模块比从入口文件逐行读代码快得多。从那以后我每次拆新项目都强制自己先python main.py再打开编辑器这个习惯能让陌生代码的熟悉速度提升一大截。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

AI推理批量执行优化:从GPU并行到动态批处理与KV Cache实践

AI推理批量执行优化:从GPU并行到动态批处理与KV Cache实践

刚接手一个文本生成服务的性能优化时,后台监控图让我很尴尬:GPU利用率只有百分之十几,单卡吞吐低得可怜,但服务端平均响应时间却不低。翻了下调用链,问题不在模型本身,而在于线上请求基本是单条推理&#x…

2026/10/20 18:42:50 阅读更多 →
Dapper + 原生SQL的CRUD实践:从基础增删改查到事务与性能优化

Dapper + 原生SQL的CRUD实践:从基础增删改查到事务与性能优化

1. 用了一年 Dapper 之后,我把这个原生 SQL 的 CRUD 示例重新理了一遍前两天翻到之前负责的一个老项目,里面有一套用 VOL 框架搭的基础服务,数据访问层选的是 Dapper,SQL 全部手写,没上任何重量级 ORM。我重新把这套 C…

2026/10/20 18:42:51 阅读更多 →
DevEco Studio项目推送Gitee完整指南:从本地到远程的版本控制实战

DevEco Studio项目推送Gitee完整指南:从本地到远程的版本控制实战

DevEco Studio的开发者们,尤其是刚接触鸿蒙开发的朋友,估计不少人都有过这样的经历:项目在本地越写越大,突然想备份一下,或者想和队友一起改代码,却发现不知道该怎么把本地工程安全地托管到远程仓库。我最近…

2026/10/20 18:43:08 阅读更多 →

最新新闻

EBS采购订单审批API集成实战:工作流、中间件与存储过程设计

EBS采购订单审批API集成实战:工作流、中间件与存储过程设计

做EBS集成的同学对采购订单审批肯定不陌生。标准功能里,审批人每天登录EBS工作台,从一堆待办通知里逐个点开、审批、写意见,流程虽然完整,但一旦公司上了OA、企业微信、钉钉或者供应商协同平台,业务方就会立刻找你&…

2026/10/20 18:47:50 阅读更多 →
计算机视觉论文速递:动态计算、自监督数据质量与多模态对齐新进展

计算机视觉论文速递:动态计算、自监督数据质量与多模态对齐新进展

1. 为什么我要做一期计算机视觉方向的论文速递做研究的人都有一个共同的痛点:每天新挂出来的论文实在太多了,光是计算机视觉这个方向,几个主流预印本平台一天就能更新上百篇。你不可能每篇都点开看,但你又怕错过真正重要的东西。我…

2026/10/20 18:47:50 阅读更多 →
6502硬件调试监控系统:基于AVR的实时总线采样与指令追踪

6502硬件调试监控系统:基于AVR的实时总线采样与指令追踪

简介:本资源是一套面向嵌入式系统开发者与计算机体系结构学习者的硬件监控实践方案,聚焦Ben Eater 6502 8位计算机的底层运行状态观测与调试。它基于AVR单片机(Teensy 2.0)构建实时监控系统,通过捕获6502的地址总线、数…

2026/10/20 18:47:50 阅读更多 →
PX4位置环与速度环详解:从代码到调参排错全攻略

PX4位置环与速度环详解:从代码到调参排错全攻略

有段时间我一直在折腾一台中型四轴,拿到手之后最明显的问题是:飞控切到位置模式,往前推杆让它飞出去,到达目标点之后机头会轻轻点一下,机身前后晃两三次才稳住。这个现象不致命,却很影响手感,也…

2026/10/20 18:47:50 阅读更多 →
工业计量三维检测软件:软硬协同与自主可控如何重塑产线质检

工业计量三维检测软件:软硬协同与自主可控如何重塑产线质检

这两年国产三维检测软件的声量确实大了。作为常年在检测室跟点云、公差、检测报告打交道的人,我最大的感受倒不是某个软件又多了几个功能图标,而是过去那种"扫描归扫描、分析归分析"的割裂状态正在被打破。以前测一个复杂曲面零件,…

2026/10/20 18:47:50 阅读更多 →
Base64编码原理与实战:解决JS图片上传乱码、截断、兼容性问题

Base64编码原理与实战:解决JS图片上传乱码、截断、兼容性问题

1. 为什么Base64不是“加密”,而是“编码”——从一张图片上传失败说起上周帮某高校实验室调试一个图像处理Demo,前端同学发来截图:用户上传一张2MB的PNG图,点击提交后控制台报错Failed to execute btoa on Window: The string to…

2026/10/20 18:46:50 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →