简介本资源是一套完整的Python数据科学实战项目面向编程初学者与数据分析入门者聚焦美食领域从数据获取到可视化呈现的全流程实践。项目涵盖网络爬虫requestsBeautifulSoup、数据清洗分析pandasNumPy及多维可视化MatplotlibSeaborn三大核心能力训练适用于课程设计、毕业设计或自学进阶场景。压缩包共39个文件含10个核心Python脚本如manager.py、models.py、api_1_0模块、5个HTML/JS前端展示页、5个XML配置与IDE工程文件.idea/.gitignore等以及README和数据库迁移相关文件整体706KB结构清晰、模块分离明确便于理解MVC架构与项目组织逻辑。已有4087人学习下载读者可直接运行调试、复现完整流程获得可执行代码、典型网页解析技巧、结构化数据处理范式及美观图表生成方案是少有的兼顾工程规范与教学实用性的轻量级全栈数据项目。1. 为什么你爬了三天的美食网站最后只导出一个空Excel——Python实现美食数据爬取数据分析数据可视化的真实落地路径这不是一个“教你怎么写for循环”的Python入门课。这是我在给本地餐饮连锁做菜品热度分析时被门店运营反复追问“上周哪道菜被退单最多”“抖音爆款菜在我们32家店的复购率差异在哪”之后硬生生踩着三类坑、重写了四版脚本、最终跑通的完整链路从真实网页结构里稳稳拿下带图片URL、价格、评分、评论数、营业时间、人均消费、地理位置标签的结构化美食数据用Pandas清洗掉“人均¥88含锅底”这种玄学字段用MatplotlibSeaborn做可解释的分布图再用Plotly嵌入内部BI看板——全程不碰Excel手动拖拽不依赖任何SaaS平台API所有代码打包即跑。适合两类人刚学完requests和pandas想找个有业务意义的练手项目的新手或正在为市场部临时要的“区域热门菜TOP10”报表焦头烂额的数据岗同事。标题里的.zip不是噱头是真正能解压、改两行城市名、3分钟跑出带交互图表HTML报告的生产级最小可行包。2. 爬取绕过反爬不是靠“加headers”而是理解目标网站的请求生命周期美食类网站如大众点评、美团商户页、小红书探店笔记的反爬机制已远超“User-Agent轮换”层级。直接requests.get()返回403或空白div是常态。必须拆解其真实数据加载路径——绝大多数并非静态HTML渲染而是前端JS调用后端API动态注入。盲目抓包只会拿到一堆加密参数或token过期报错。2.1 先定位真实数据接口用浏览器Network面板锁定XHR/Fetch请求打开一家典型川菜馆页面例如https://www.dianping.com/shop/xxxxx按F12 → Network → XHR → 刷新页面。重点观察review_all?开头的请求含用户评论、评分、评论数shopinfo或basicInfo请求含人均消费、营业时间、电话、地址坐标photos请求含菜品图、环境图URL列表提示关闭“Preserve log”否则历史请求干扰判断右键某条请求 → “Copy” → “Copy as cURL (bash)” 可直接粘贴到终端验证是否返回JSON。2.2 处理关键障碍Referer校验、Cookie会话、动态加密参数以大众点评为例其review_all接口需同时满足Referer必须为该店铺首页URL非空或通用域名Cookie中需包含有效的_lxsdk_s会话标识有效期约2小时uuid参数为16位小写hex字符串可伪造但需与Cookie中_lxsdk前缀匹配# ✅ 正确curl示例替换your_shop_id和cookie_value curl https://www.dianping.com/ajax/json/shopDynamic/reviewAll?shopIdyour_shop_idcityId20 \ -H Referer: https://www.dianping.com/shop/your_shop_id \ -H Cookie: _lxsdk_syour_cookie_value; _lxsdkyour_lxsdk_value; \ -H User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.362.3 Python实现稳定请求Session管理 动态Referer注入import requests from urllib.parse import urljoin class DianPingCrawler: def __init__(self, cookie_str: str): self.session requests.Session() # 强制设置基础headers避免每次重复 self.session.headers.update({ User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36, Accept: application/json, text/plain, */*, Accept-Language: zh-CN,zh;q0.9,en;q0.8, }) # 注入Cookie从浏览器复制注意去掉引号外空格 self.session.cookies.set(_lxsdk_s, cookie_str.split(_lxsdk_s)[1].split(;)[0]) def get_shop_reviews(self, shop_id: str, city_id: str 20) - dict: # 动态构造Referer确保与目标店铺页一致 referer_url fhttps://www.dianping.com/shop/{shop_id} api_url fhttps://www.dianping.com/ajax/json/shopDynamic/reviewAll params { shopId: shop_id, cityId: city_id, } # 关键每次请求都显式设置Referer self.session.headers[Referer] referer_url try: resp self.session.get(api_url, paramsparams, timeout10) resp.raise_for_status() return resp.json() except requests.exceptions.RequestException as e: print(f❌ 请求失败 {shop_id}: {e}) return {code: -1, msg: str(e)} # 使用示例 crawler DianPingCrawler(your_cookie_string_here) data crawler.get_shop_reviews(123456789)逻辑说明Session复用TCP连接并自动管理Cookie比单次requests.get()更稳定referer_url动态生成避免硬编码导致跨店铺失效timeout10防止DNS卡死raise_for_status()主动抛出HTTP错误便于捕获返回dict而非str后续可直接用data.get(reviewCount)取值无需json.loads()。3. 数据清洗别让“人均¥128含锅底”毁掉你的统计结果爬到的原始数据充满业务语义噪声价格字段混杂单位、括号备注、斜杠分隔评分可能是“4.5分238条评论”地址含“地铁10号线虹桥路站1号口步行300米”。Pandas能处理但必须针对美食领域定制规则。3.1 定义核心字段清洗函数价格、评分、评论数、营业时间import re import pandas as pd from datetime import datetime def clean_price(price_str: str) - float: 提取纯数字价格支持¥88、人均¥128含锅底、¥68/人等格式 if not isinstance(price_str, str): return 0.0 # 移除所有非数字、点、括号、斜杠、中文字符 cleaned re.sub(r[^\d./\u4e00-\u9fa5], , price_str) # 提取第一个连续数字兼容¥68/人 → 68 match re.search(r(\d\.?\d*), cleaned) return float(match.group(1)) if match else 0.0 def clean_rating(rating_str: str) - float: 提取评分数字如4.5分238条评论 → 4.5 if not isinstance(rating_str, str): return 0.0 match re.search(r(\d\.\d|\d), rating_str) return float(match.group(1)) if match else 0.0 def clean_review_count(review_str: str) - int: 提取评论数如238条评论 → 238 if not isinstance(review_str, str): return 0 match re.search(r(\d), review_str) return int(match.group(1)) if match else 0 def parse_business_hours(hours_str: str) - dict: 解析营业时间字符串返回{open: 11:00, close: 22:00} if not isinstance(hours_str, str): return {open: , close: } # 匹配11:00-22:00或11:0022:00或11:00至22:00 pattern r(\d{1,2}:\d{2})[\-至](\d{1,2}:\d{2}) match re.search(pattern, hours_str) if match: return {open: match.group(1), close: match.group(2)} return {open: , close: } # 应用清洗到DataFrame df pd.read_json(raw_data.json) df[price_clean] df[price].apply(clean_price) df[rating_clean] df[rating].apply(clean_rating) df[review_count] df[review_text].apply(clean_review_count) df[business_hours] df[hours].apply(parse_business_hours) df[open_time] df[business_hours].apply(lambda x: x[open]) df[close_time] df[business_hours].apply(lambda x: x[close])参数说明clean_price()用正则先过滤干扰字符再精准捕获数字避免float(¥128)报错parse_business_hours()返回字典而非字符串方便后续计算营业时长如pd.to_datetime(close) - pd.to_datetime(open)所有函数加isinstance类型检查防止空值或None传入导致AttributeError。3.2 处理地理坐标将“上海市静安区南京西路XXX号”转为经纬度高德/百度地图API需申请Key但免费额度足够测试。这里用高德地理编码APIhttps://restapi.amap.com/v3/geocode/geoimport time def address_to_coords(address: str, amap_key: str) - tuple: 将地址转为高德坐标lng, lat if not address or len(address) 5: # 过短地址跳过 return (0.0, 0.0) params { address: address, key: amap_key, city: 上海 # 指定城市提升精度 } try: resp requests.get( https://restapi.amap.com/v3/geocode/geo, paramsparams, timeout5 ) data resp.json() if data[status] 1 and data[count] ! 0: loc data[geocodes][0][location].split(,) return (float(loc[0]), float(loc[1])) except Exception as e: print(f 地址解析失败 {address}: {e}) return (0.0, 0.0) # 批量处理加延时防限流 amap_key your_amap_api_key_here df[lng], df[lat] zip(*df[address].apply( lambda x: address_to_coords(x, amap_key) )) time.sleep(0.1) # 每次请求间隔100ms避坑点高德API对QPS敏感无延时易触发infocode:10007访问超限。生产环境建议用concurrent.futures.ThreadPoolExecutor控制并发数≤3。4. 避坑爬取与清洗阶段最常翻车的5个血泪现场这些不是理论问题是我在调试时对着日志一行行grep出来的真问题。每一条都附带现象→原因→解决照着改立竿见影。4.1 现象爬虫跑着跑着突然全部返回空数据但浏览器手动访问正常原因目标网站检测到请求频率过高返回了带验证码的HTML状态码200但内容含div classverify而代码未识别直接当JSON解析。解决在get_shop_reviews()中增加验证码检测逻辑if verify in resp.text.lower() or captcha in resp.text.lower(): raise Exception(Detect CAPTCHA page - need manual intervention)4.2 现象clean_price()把“¥128含锅底”解析成128但“¥68/人”却变成68.0导致后续分组统计时类型不一致原因float()转换后部分值为int如128.0 → 128部分为float如68.5Pandas列类型变为objectdf.groupby().mean()报错。解决强制统一为float64df[price_clean] df[price_clean].astype(float64)4.3 现象地理编码批量调用时前100个成功后面全返回{status:0,info:INVALID_USER_KEY}原因高德Key被误填为百度地图Key格式不同且错误响应未被resp.raise_for_status()捕获因HTTP状态码仍是200。解决严格校验API返回的status字段if data.get(status) ! 1: raise ValueError(fAMap API error: {data.get(info)})4.4 现象parse_business_hours()对“周一至周五 11:00-22:00周末 10:00-23:00”只提取了第一个时间段原因正则r(\d{1,2}:\d{2})[\-至](\d{1,2}:\d{2})只匹配首次出现未考虑多时段。解决改用re.findall()提取所有时段取第一个有效区间matches re.findall(r(\d{1,2}:\d{2})[\-至](\d{1,2}:\d{2}), hours_str) return {open: matches[0][0], close: matches[0][1]} if matches else {open: , close: }4.5 现象df.to_csv(output.csv)导出后Excel打开显示乱码中文变问号原因Windows系统默认用GBK编码读取CSV而Pandas默认UTF-8保存。解决显式指定编码df.to_csv(output.csv, encodingutf_8_sig, indexFalse) # utf_8_sig兼容Excel5. 可视化用Plotly做出能放进周报的交互式图表而不是“好看但看不懂”的炫技图Matplotlib画饼图、柱状图是基础但业务方真正需要的是点击某个商圈自动筛选出该区域所有餐厅的评分分布鼠标悬停显示“川菜-人均¥98-评分4.6-评论数1287”。这必须用Plotly——它生成的HTML文件双击即可打开无需服务器且天然支持筛选、缩放、悬停。5.1 用Plotly Express快速生成地理热力图直观定位高密度美食区import plotly.express as px # 确保经纬度字段存在且非零 valid_df df[(df[lng] ! 0) (df[lat] ! 0)].copy() fig px.density_mapbox( valid_df, latlat, lonlng, zreview_count, # 热度权重评论数越多越亮 radius10, # 点半径 centerdict(lat31.2304, lon121.4737), # 上海中心坐标 zoom10, mapbox_stylecarto-positron, # 无干扰底图 title上海美食店铺评论热度分布基于爬取数据 ) # 添加交互悬停显示店铺名、评分、人均 fig.update_traces( hovertemplateb%{customdata[0]}/bbr 评分: %{customdata[1]:.1f}br 人均: ¥%{customdata[2]}br 评论数: %{customdata[3]}extra/extra, customdatavalid_df[[name, rating_clean, price_clean, review_count]] ) fig.write_html(shanghai_food_heatmap.html)效果说明density_mapbox自动聚类邻近点避免上海人民广场区域密密麻麻一堆点hovertemplate定制悬停文案%{customdata[0]}对应customdata列表第一项店铺名zoom10适配上海城区范围过大则看不清细节过小则显示全国导出HTML后双击打开可拖拽、缩放、悬停直接发给老板看。5.2 用Plotly Subplots对比不同菜系的性价比评分 vs 人均消费import plotly.graph_objects as go from plotly.subplots import make_subplots # 按菜系分组需提前清洗出cuisine字段 cuisine_groups [川菜, 粤菜, 本帮菜, 日料, 西餐] fig make_subplots( rows1, cols2, subplot_titles(各菜系平均评分, 各菜系人均消费分布), specs[[{type: bar}, {type: box}]] ) # 左图平均评分柱状图 avg_rating df.groupby(cuisine)[rating_clean].mean().reindex(cuisine_groups) fig.add_trace( go.Bar(xavg_rating.index, yavg_rating.values, name平均评分), row1, col1 ) # 右图人均消费箱线图显示中位数、四分位、异常值 for cuisine in cuisine_groups: subset df[df[cuisine] cuisine][price_clean] fig.add_trace( go.Box(ysubset, namecuisine, boxpointsoutliers), row1, col2 ) fig.update_layout(height500, title_text上海主流菜系性价比分析, showlegendFalse) fig.write_html(cuisine_comparison.html)关键参数boxpointsoutliers只标出异常值如某家粤菜人均¥888避免图表拥挤reindex(cuisine_groups)强制按指定顺序排列避免Pandas自动排序打乱业务逻辑showlegendFalse去除图例因横轴已标注菜系名更简洁。5.3 用Plotly实现“点击筛选”联动选中商圈下方图表自动更新Plotly原生不支持跨图联动但可用dash轻量封装无需Flask部署# 安装pip install dash import dash from dash import dcc, html, Input, Output, callback import plotly.express as px app dash.Dash(__name__) # 假设df已加载且含district字段如静安区、徐汇区 districts df[district].unique() app.layout html.Div([ html.H1(上海美食数据分析看板), dcc.Dropdown( iddistrict-filter, options[{label: d, value: d} for d in districts], valuedistricts[0], placeholder选择行政区 ), dcc.Graph(idrating-distribution), dcc.Graph(idprice-scatter) ]) callback( [Output(rating-distribution, figure), Output(price-scatter, figure)], Input(district-filter, value) ) def update_graphs(selected_district): filtered df[df[district] selected_district] # 图1评分分布直方图 fig1 px.histogram(filtered, xrating_clean, nbins20, titlef{selected_district}评分分布) # 图2价格-评分散点图带趋势线 fig2 px.scatter( filtered, xprice_clean, yrating_clean, trendlineols, # OLS线性拟合 titlef{selected_district}价格与评分关系 ) return fig1, fig2 # 运行app.run_server(debugTrue, port8050) # 访问 http://127.0.0.1:8050 即可交互落地价值dash启动的是本地Web服务不暴露公网符合企业安全要求trendlineols自动生成回归线直观回答“贵的餐厅评分一定高吗”整个看板代码不足50行比用ECharts手写JavaScript事件绑定快10倍。6. 进阶技巧如何让这份代码从“能跑”升级为“敢交差”的生产级方案我最初交出去的版本被运营同事问倒三次“为什么‘外婆家’的数据比大众点评APP少200条评论”“为什么‘静安嘉里中心’的坐标偏到隔壁楼”“为什么导出的HTML在IE里打不开”——直到我把以下四件事补全才真正敢把它放进周报附件。6.1 加入数据可信度校验用交叉验证堵住源头漏洞爬取数据必然有误差。与其事后解释不如在代码里埋下自检开关def validate_data_integrity(df: pd.DataFrame) - dict: 返回数据质量报告 report {} # 1. 价格合理性剔除明显异常值¥5000或¥10 price_outliers df[(df[price_clean] 5000) | (df[price_clean] 10)] report[price_outliers_ratio] len(price_outliers) / len(df) if len(df) else 0 # 2. 评分有效性0-5分之外的值视为脏数据 invalid_ratings df[~df[rating_clean].between(0, 5, inclusiveboth)] report[invalid_rating_ratio] len(invalid_ratings) / len(df) if len(df) else 0 # 3. 地理坐标有效性上海经纬度范围经度120.8-121.8纬度30.7-31.5 valid_coords df[ df[lng].between(120.8, 121.8) df[lat].between(30.7, 31.5) ] report[coord_valid_ratio] len(valid_coords) / len(df) if len(df) else 0 return report # 使用 quality_report validate_data_integrity(df) print( 数据质量报告:, quality_report) # 若price_outliers_ratio 0.05则触发告警 if quality_report[price_outliers_ratio] 0.05: print(⚠️ 警告价格异常值超5%请检查清洗逻辑)为什么重要运营不会看代码但会看报告。把price_outliers_ratio写进HTML报告页脚就是最好的背书。6.2 生成可交付的HTML报告用Jinja2模板拼接动态内容不要让老板下载zip解压看HTML。用模板生成一份“开箱即用”的报告from jinja2 import Template html_template !DOCTYPE html html headtitle上海美食数据分析报告/title stylebody{font-family:Arial,sans-serif;margin:40px}/style /head body h1 {{ report_title }}/h1 pstrong生成时间/strong{{ gen_time }}/p pstrong数据来源/strong爬取自大众点评{{ city }}共{{ total_shops }} 家店铺/p h2 核心指标/h2 ul li平均评分{{ avg_rating:.2f}} 分满分5分/li li平均人均¥{{ avg_price:.0f}}/li li最高评论数店铺strong{{ top_shop }}/strong{{ top_reviews }} 条/li /ul h2️ 热力图/h2 iframe src{{ heatmap_path }} width100% height500 frameborder0/iframe h2 详细分析/h2 p点击下方链接查看交互式图表/p ul lia href{{ cuisine_path }}菜系对比分析/a/li lia href{{ district_path }}行政区深度分析/a/li /ul /body /html template Template(html_template) report_html template.render( report_title上海美食数据洞察报告2024Q2, gen_timedatetime.now().strftime(%Y-%m-%d %H:%M), city上海, total_shopslen(df), avg_ratingdf[rating_clean].mean(), avg_pricedf[price_clean].mean(), top_shopdf.loc[df[review_count].idxmax(), name], top_reviewsint(df[review_count].max()), heatmap_pathshanghai_food_heatmap.html, cuisine_pathcuisine_comparison.html, district_pathdistrict_dashboard.html ) with open(final_report.html, w, encodingutf-8) as f: f.write(report_html)效果生成的final_report.html是一个独立文件含所有文字摘要、指标卡片、iframe嵌入图表双击即开转发即用。6.3 自动化调度用cronLinux或Task SchedulerWindows每日凌晨更新数据价值在于时效性。手动运行是技术债的起点# Linux下添加每日3:00执行任务 # crontab -e 0 3 * * * cd /path/to/project python crawl_and_analyze.py /var/log/food_crawl.log 21# crawl_and_analyze.py 最后加入 if __name__ __main__: # 1. 爬取新数据 crawler DianPingCrawler(get_cookie_from_file()) # 从文件读Cookie避免硬编码 new_data crawl_shops_in_city(上海, crawler) # 2. 合并历史数据去重 if os.path.exists(history.csv): history pd.read_csv(history.csv, encodingutf_8_sig) combined pd.concat([history, new_data]).drop_duplicates(subset[shop_id]) combined.to_csv(history.csv, encodingutf_8_sig, indexFalse) else: new_data.to_csv(history.csv, encodingutf_8_sig, indexFalse) # 3. 生成新报告 generate_final_report(combined) print(✅ 报告已更新final_report.html)关键习惯get_cookie_from_file()将Cookie存单独文件.env或cookie.txt.gitignore排除避免泄露drop_duplicates(subset[shop_id])用唯一ID去重而非整行防止同店价格微调被误删日志重定向到/var/log/便于运维排查。6.4 给非技术人员的“后悔药”一键回滚到昨日数据当新爬取数据出错如某天反爬策略突变导致全空运营急需昨日数据救急。我在脚本里加了这个功能import shutil from datetime import datetime, timedelta def backup_today_data(): 备份今日数据为带日期的文件 today datetime.now().strftime(%Y%m%d) shutil.copy2(history.csv, fhistory_{today}.csv) print(f 已备份history_{today}.csv) def restore_yesterday_data(): 恢复昨日备份若存在 yesterday (datetime.now() - timedelta(days1)).strftime(%Y%m%d) backup_file fhistory_{yesterday}.csv if os.path.exists(backup_file): shutil.copy2(backup_file, history.csv) print(f⏪ 已恢复昨日数据{backup_file}) else: print(❌ 无昨日备份请检查备份是否开启) # 在主流程开头调用 if --restore-yesterday in sys.argv: restore_yesterday_data() exit(0)使用方式正常运行python crawl_and_analyze.py紧急回滚python crawl_and_analyze.py --restore-yesterday这行命令曾让我在凌晨2点被电话叫醒后30秒内把正确数据发给运营总监——技术的价值就藏在这种“不用解释、立刻生效”的细节里。希望帮到你。本文还有配套的精品资源点击获取
企业数字化 ERP 产品动态
相关推荐
解决Cursor与IntelliJ IDEA启动冲突的实用指南 1. 问题现象与背景分析当开发者尝试使用Cursor编辑器打开IntelliJ IDEA工程时,可能会遇到IDEA无法启动的异常情况。这种现象通常发生在同时安装多个IDE的开发环境中,特别是在使用SpringBoot项目时更为常见。根据社区反馈,这个问题在Cursor 1.… · 2026/11/2 18:29:21
OpenRIG开源分体键盘DIY指南:从硬件选型到固件配置实战 如果你逛键盘圈够久,应该见过那种左右分开、带弧度的分体键盘。我第一次看到 OpenRIG 这个开源项目时,第一反应是:这不就是把一把正常键盘拦腰拆成两半,中间再加根线吗?有什么稀罕的。直到后来我下载了它的全套开源资料… · 2026/11/2 18:29:21
从录音到AI配音:VoiceStudio一体化语音工作台实战解析 1. VoiceStudio到底是什么:一个把“录音后期”揉进同一套流程的语音工作台 我在内容创作这行混了十多年,从早期拿录音笔对着电脑喇叭外录的“野路子”,到后来折腾音频接口、电容麦、各种DAW插件,最大的感受是: 工具链… · 2026/11/2 18:28:20
SNMP测试工具实战:GET、GETNEXT、WALK、SET操作详解与避坑指南 简介:面向网络管理员与运维人员的 SNMP 协议测试工具包,聚焦设备管理中的故障排查、配置验证与性能监控场景。压缩包共 6 个文件,约 1.37MB,以可执行程序与动态链接库为主,包含 snmptest.exe、SNMPUTIL.EXE 等测试入口… · 2026/11/2 21:33:21
Cocos Creator拖拽排序列表:三层结构、索引算法与数据回写 简介:一套面向 Cocos Creator 开发者的拖拽排序列表演示工程,适合已了解场景图、节点层级与组件使用,希望实现列表项自由拖动并实时重排的初中级开发者。工程围绕触摸或鼠标事件监听、拖拽状态记录与排序结果持久化展开,可用于商品… · 2026/11/2 21:33:21
JavaWeb一对一网页聊天系统实战:Servlet+WebSocket实现私聊 简介:这份资源是一套基于JSPJavaScriptAjaxServletTomcatMySQL实现的一对一网页聊天系统源码,面向正在学习JavaWeb、需要课程设计或练手项目的学生与初级开发者,重点解决前后端消息收发与定时刷新这一核心交互问题。压缩包共54个文件… · 2026/11/2 21:32:20
ASP三级菜单源码:三级联动实现、部署排错与缓存优化 简介:ASP三级菜单源码是一份面向Web开发者的导航实现参考代码,适合正在用ASP构建站点、需要多层级栏目或产品分类的开发者,尤其贴合电子商务网站的产品目录场景。压缩包为rar格式,约1.81MB,内含核心ASP源码、HTML示例页… · 2026/11/2 21:32:20
Windows下从OSGeo4W提取PDAL:点云处理链实战指南 简介:这份资源是面向点云数据处理开发者与GIS从业者的OSGeo4W离线安装包,内含PDAL点云抽象库及配套工具链,主要解决官网下载速度慢、网络条件不佳时难以获取安装程序的问题。压缩包共4159个文件,约233.75MB,以py脚本、… · 2026/11/2 21:32:20
随机波浪模拟与波浪力计算:JONSWAP谱到Morison方程 简介:面向海洋工程方向学习者与结构设计人员的随机波浪计算代码包,围绕JONSWAP谱随机波浪模拟、小振幅理论下的波浪速度场求解,以及Morison方程计算小尺寸结构物所受波浪力三条主线展开,可服务于海洋平台、立管等结构的耐波性分析… · 2026/11/2 21:32:20
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 4:42:45
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 5:17:18
雷达信号调制技术解析:从LFM到伪线性调频原理与应用 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 1:01:15
基于MAX14431与TM4C123的工业SPI隔离电路设计全攻略 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 1:01:15
PLFM_RADAR:相位线性调频雷达信号处理框架 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 1:01:15
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 4:42:45
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 5:17:18