Medium文章本地化归档:安全抓取自有内容的实战指南
1. 项目概述为什么你需要把 Medium 文章“搬回家”Medium 是个好地方——界面干净、读者精准、算法对新人还算友好不少技术作者靠它积累第一波影响力。但如果你已经写了十几篇、几十篇甚至上百篇深度长文却只把它们“寄存”在 Medium 平台上那本质上你是在用自己最值钱的资产——持续产出的专业内容——为别人的基础设施付费打工。这不是比喻Medium 的域名、CDN、数据库、推荐引擎、用户登录体系全由其运营方控制而你的文章没有独立 URL没有原始 HTML 控制权无法嵌入自定义脚本不能做 SEO 优化更无法接入自己的分析埋点或邮件订阅链路。我见过太多朋友某天 Medium 改版限流、调整分发策略或者单纯因为账号异常被临时冻结整片内容宇宙瞬间失联——不是删了是“找不到了”连导出按钮都灰掉。这正是Scraping Your Medium Stories这个项目的真实出发点它不是教你怎么绕过反爬也不是鼓动你批量盗取他人内容而是帮你把你自己发布在 Medium 上的、拥有完整版权的原创文章以结构化、可归档、可再分发的方式安全、稳定、可验证地“迁回本地”。关键词就三个你的、Medium、Stories——全部指向所有权回归。它解决的是数字时代创作者最基础也最常被忽视的生存问题内容主权。适合三类人一是长期在 Medium 持续输出的技术博主想建个人知识库二是准备将 Medium 内容迁移至自有博客如 Hugo、Next.js 或 WordPress的迁移者三是需要离线存档、做内容复盘或生成年度报告的数据型写作者。整个过程不依赖 Medium 官方 API它早已关闭公开读取权限也不需要登录态模拟或复杂会话维持核心逻辑是利用 Medium 公开页面的静态 HTML 结构稳定性结合语义化选择器精准提取正文、标题、发布时间、标签等关键字段并保留原始排版语义如代码块、引用、图片占位。实测下来单篇文章处理耗时平均 1.8 秒100 篇批量抓取可在 3 分钟内完成且成功率长期稳定在 99.2% 以上——这个数字背后是我踩过 7 轮 Medium 前端改版后沉淀下来的 selector 适配策略。2. 整体设计思路与方案选型解析2.1 为什么放弃 Puppeteer / Playwright坚持纯 Requests BeautifulSoup 路线刚接触这个需求时我也试过 Puppeteer。毕竟 Medium 页面有懒加载、动态渲染的评论区和推荐卡片用无头浏览器看起来“更稳妥”。但实际跑通一轮后立刻推翻首屏正文内容即用户真正写的那部分从 Medium 2016 年上线起就始终以标准article标签包裹所有段落、标题、代码块、图片figure都是服务端直出的静态 HTML根本不需要 JS 执行。Puppeteer 启动 Chromium 实例平均耗时 850ms内存占用 320MB而 Requests 发起一次 GET 请求仅需 120ms内存波动不到 5MB。更重要的是稳定性——Puppeteer 容易因 Chrome 版本更新、字体缺失、GPU 渲染异常导致偶发白屏而 Requests 只认 HTTP 状态码和 HTML 结构只要页面能被 curl -I 返回 200它就一定能拿到原始字节流。提示Medium 的og:url和 canonical link 始终指向同一地址且响应头中Content-Type: text/html; charsetutf-8严格声明编码这意味着我们完全规避了 JS 渲染带来的不确定性把问题降维成一个“HTML 解析精度”问题而非“浏览器兼容性”问题。2.2 为什么不用官方 API它真的不存在了吗Medium 在 2020 年彻底关闭了面向第三方开发者的 Public API包括/posts、/users/{id}/posts等所有读取接口。目前仅保留一个极窄的、需 OAuth2 授权的 Publishing API且仅允许已认证的作者通过该 API创建新文章无法读取已有文章内容。我曾用 Postman 模拟过完整的 OAuth2 流程成功获取到 access_token但调用GET https://api.medium.com/v1/users/me/posts时返回永远是{errors:[{message:Forbidden,code:403}]}。官方文档明确写着“The read endpoints for posts and users are deprecated and no longer available.” —— 不是“暂时不可用”是“已废弃且不再提供”。所以任何声称“调用 Medium API 抓取”的方案要么是旧文档误导要么是混淆了 Publishing API 的写权限与读权限。2.3 为什么选择 Python 而非 Node.js 或 Rust三个硬指标决定生态成熟度、HTML 解析精度、调试效率。BeautifulSoup4 对嵌套div的容错解析能力远超 jsdom尤其面对 Medium 那种“div 套 div 套 div”的经典前端反模式它的soup.select()方法支持完整 CSS 选择器语法能精准定位.pw-post-body-paragraph这类带连字符的 class而 Node.js 的 cheerio 在处理precode嵌套时曾多次因换行符解析差异导致代码块内容截断。Rust 的 scraper 库性能虽高但开发调试周期太长——当你需要快速验证 selector 是否匹配新改版的 Medium 页面时Python 的print(soup.select_one(.pw-title).get_text())一行就能看到结果而 Rust 需编译、运行、查日志迭代成本高出 5 倍。对于一个以“快速适配前端变化”为核心诉求的工具开发效率就是生产效率。2.4 为什么坚持“只抓自己的文章”法律与技术双重边界Medium 的 Terms of Service 第 3.2 条明确写道“You retain all rights to any Content you post on or through the Services.” —— 你对自己发布的内容拥有全部权利。但第 4.1 条同时规定“You may not… scrape, spider, or crawl the Services…”。这里的关键词是 “the Services”指整个 Medium 平台服务。然而美国第九巡回法院在HiQ Labs v. LinkedIn案中确立了一项重要判例当数据是公开可访问的publicly available且抓取行为不突破技术防护如 robots.txt、登录墙、验证码则不构成 CFAA计算机欺诈与滥用法意义上的“未经授权访问”。Medium 所有已发布文章的 URL 都是公开的medium.com/username/story-slug未登录用户也能直接访问robots.txt 也未禁止爬虫抓取/*/路径。因此“抓取自己发布的公开文章”在法律上属于灰色地带中的安全区你既是内容著作权人又是数据访问的合法用户即使未登录页面本身也未设防。但一旦扩展到抓取他人文章、用户列表、阅读数等非公开字段立刻越过红线。本项目所有 selector 设计、URL 构造逻辑、错误处理机制全部围绕“仅限自己域名下公开文章”这一前提构建这是技术方案的底线也是职业操守的起点。3. 核心细节解析与实操要点3.1 URL 构造规则如何从用户名推导出所有文章链接Medium 的 URL 结构看似随意实则高度规律。以我的账号为例主页是https://medium.com/jameschen而每篇文章的 slug如how-i-built-a-10k-maillist-in-3-months并非随机生成而是基于文章标题自动生成的 ASCII-only 字符串中间用短横线连接且全部小写。关键在于Medium 不提供用户文章列表的公开 API但它的个人主页 HTML 中包含一个隐藏的 JSON-LD 数据块完整列出了该用户所有已发布文章的 URL、标题、发布时间。具体操作请求https://medium.com/username搜索 HTML 中script typeapplication/ldjson标签其内容是一个标准的 JSON-LD 对象。其中mainEntityOfPage字段是一个数组每个元素包含{ type: Article, url: https://medium.com/jameschen/how-i-built-a-10k-maillist-in-3-months-1a2b3c4d5e6f, headline: How I Built a 10K Mail List in 3 Months, datePublished: 2023-05-12T08:30:00.000Z }这个 JSON-LD 是 Medium 为搜索引擎优化SEO而嵌入的必须存在且格式稳定。我测试过 2019 至 2024 年间 12 个不同 Medium 主页该结构从未变更。相比用 Selenium 模拟滚动加载“更多文章”解析 JSON-LD 的准确率是 100%且无需等待 JS 执行请求一次即可拿到全部文章元数据。唯一要注意的是JSON-LD 中的url字段有时会包含 Medium 的追踪参数如?source...需用urllib.parse.urlparse提取净 URL再用urlunparse重构确保后续请求的纯净性。3.2 正文提取的 selector 策略对抗 Medium 的“div 混沌”Medium 的前端工程师似乎信奉“div 即一切”哲学。一篇普通文章的 DOM 结构中div标签平均嵌套深度达 12 层同级divclass 名相似度极高如pw-post-body-paragraph、pw-post-body-paragraph--image、pw-post-body-paragraph--quote。若用传统 XPath 或模糊 class 匹配极易误抓广告位、推荐卡片或页脚。我的解决方案是三级 selector 锚定法。第一步锁定文章主体容器article[data-layoutpost]。这是 Medium 唯一不变的语义化容器自 2017 年沿用至今且不会出现在首页或用户主页中。第二步排除干扰区块在article内用:not([data-blockad])、:not([data-blockrecommendation])、:not([data-blocknewsletter])等伪类过滤掉所有带>pip install pipenv pipenv install requests beautifulsoup4 lxml python-dateutil tqdm这里lxml是 BeautifulSoup 的首选解析器比默认的html.parser快 3 倍且对破损 HTML 容错更强python-dateutil用于解析 Medium 返回的 ISO 8601 时间字符串如2023-05-12T08:30:00.000Ztqdm提供进度条100 篇文章处理时能直观看到实时进度。注意不要安装selenium或playwright它们会引入不必要的 Chromium 二进制依赖且与本方案设计哲学相悖。如果系统缺少libxml2-devUbuntu/Debian或libxml2macOS via Homebrewlxml编译会失败此时先运行sudo apt-get install libxml2-dev libxslt-dev python3-devLinux或brew install libxml2 libxsltmacOS。4.2 核心代码实现从 URL 列表到 Markdown 文件以下为精简后的核心函数已去除日志和异常包装保留最骨干逻辑import requests from bs4 import BeautifulSoup from urllib.parse import urlparse, urlunparse, unquote import re import os from datetime import datetime from dateutil import parser def extract_article_metadata(soup): 从 soup 对象中提取所有 meta 标签元数据 metadata {} for tag in soup.find_all(meta): prop tag.get(property) or tag.get(name) if not prop: continue content tag.get(content, ).strip() if not content: continue # 映射 property 到标准字段名 if prop og:title or prop title: metadata[title] content elif prop article:published_time: metadata[published_at] parser.isoparse(content) elif prop medium:reads: metadata[reads] int(content) if content.isdigit() else 0 elif prop medium:claps: metadata[claps] int(content) if content.isdigit() else 0 elif prop article:tag: metadata.setdefault(tags, []).append(content) return metadata def clean_url(url): 移除 Medium URL 中的 utm 参数和 source 追踪 parsed urlparse(url) # 清理 query 参数只保留必要部分 clean_query .join([ kv for kv in parsed.query.split() if not kv.startswith((utm_, source, ref)) ]) return urlunparse((parsed.scheme, parsed.netloc, parsed.path, , clean_query, )) def extract_article_content(soup): 提取文章正文内容返回 Markdown 格式字符串 article soup.select_one(article[data-layoutpost]) if not article: return # 过滤掉广告、推荐等非正文区块 for block in article.select([data-block]): block.decompose() md_lines [] # 处理标题 title_elem article.select_one(h1.pw-post-title, h1.mi-post-title) if title_elem: md_lines.append(f# {title_elem.get_text(stripTrue)}\n) # 处理所有段落 for para in article.select(p.pw-post-body-paragraph, p.mi-post-body-paragraph): # 跳过空段落和纯空白段落 text para.get_text(stripTrue) if not text: continue # 识别引用块 if para.parent.name blockquote or quote in para.get(class, []): md_lines.append(f {text}\n) continue # 识别代码块父容器 if para.parent.name pre and para.parent.select_one(code): code_elem para.parent.select_one(code) lang code_elem.get(class, [])[0].replace(language-, ) if code_elem.get(class) else code_text code_elem.get_text() md_lines.append(f{lang}\n{code_text}\n\n) continue # 普通段落 md_lines.append(f{text}\n) # 处理图片 for img in article.select(figure.pw-post-body-paragraph--image img, figure.mi-post-body-paragraph--image img): src img.get(src, ) alt img.get(alt, ).strip() if src and not src.startswith(data:): # 生成本地图片文件名 parsed_img urlparse(src) filename re.sub(r[^a-zA-Z0-9._-], -, unquote(parsed_img.path.split(/)[-1])) local_path f./images/{filename} # 下载图片此处省略下载逻辑实际需用 requests.get md_lines.append(f![{alt}]({local_path})\n) return .join(md_lines) def scrape_medium_story(url): 主抓取函数输入 URL返回 (metadata, markdown_content) 元组 headers { User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 } try: resp requests.get(url, headersheaders, timeout10) resp.raise_for_status() except Exception as e: print(f请求失败 {url}: {e}) return None, None soup BeautifulSoup(resp.text, lxml) metadata extract_article_metadata(soup) content_md extract_article_content(soup) # 补充 URL 和 ID metadata[url] clean_url(url) metadata[id] extract_medium_id_from_url(url) # 从 URL 中提取 1a2b3c4d5e6f return metadata, content_md def extract_medium_id_from_url(url): 从 Medium URL 中提取文章 ID match re.search(r/([0-9a-f]{12,})$, url) if match: return match.group(1) # fallback从 meta 标签中提取 try: resp requests.get(url, timeout5) soup BeautifulSoup(resp.text, lxml) android_url soup.select_one(meta[propertyal:android:url]) if android_url: return re.search(r/post/([0-9a-f]{12,}), android_url.get(content, )).group(1) except: pass return unknown这段代码的核心价值在于所有 selector 都做了双保险。比如标题选择器写成h1.pw-post-title, h1.mi-post-title同时兼容新旧 class 前缀图片选择器用figure.pw-post-body-paragraph--image img, figure.mi-post-body-paragraph--image img确保改版后仍生效。这种“冗余但稳健”的写法是应对 Medium 前端高频迭代的唯一可靠策略。4.3 批量抓取与文件组织构建可维护的知识库单篇文章抓取只是开始真正的价值在于规模化。我设计了一个三层目录结构medium-archive/ ├── metadata.json # 所有文章元数据汇总含 id、title、url、published_at、reads、claps、tags ├── stories/ # 所有 Markdown 文件 │ ├── how-i-built-a-10k-maillist-in-3-months.md │ ├── why-i-switched-from-react-to-svelte.md │ └── ... ├── images/ # 所有下载的图片 │ ├── how-i-built-a-10k-maillist-in-3-months-1-AbCdEfGhIjKlMnOpQrStUvWxYz.jpg │ └── ... └── archive.log # 每次运行的详细日志含时间戳、成功数、失败 URL、耗时批量抓取主逻辑如下import json from tqdm import tqdm def batch_scrape(usernames, output_dirmedium-archive): 批量抓取多个用户的 Medium 文章 os.makedirs(output_dir, exist_okTrue) os.makedirs(f{output_dir}/stories, exist_okTrue) os.makedirs(f{output_dir}/images, exist_okTrue) all_metadata [] success_count 0 failed_urls [] for username in usernames: print(f\n正在抓取 {username} 的文章列表...) profile_url fhttps://medium.com/{username} try: resp requests.get(profile_url, timeout10) soup BeautifulSoup(resp.text, lxml) # 解析 JSON-LD 中的文章列表 script_tags soup.find_all(script, typeapplication/ldjson) articles [] for script in script_tags: try: data json.loads(script.string) if isinstance(data, dict) and data.get(type) ProfilePage: main_entity data.get(mainEntityOfPage, []) if isinstance(main_entity, list): articles.extend(main_entity) except: continue print(f发现 {len(articles)} 篇文章) # 逐篇抓取 for article in tqdm(articles, descf{username}): url article.get(url, ) if not url: continue metadata, content scrape_medium_story(url) if metadata and content: # 生成文件名slug id 截断防重名 slug url.split(/)[-1].split(?)[0] filename f{slug[:50]}-{metadata[id][:8]}.md with open(f{output_dir}/stories/{filename}, w, encodingutf-8) as f: f.write(f---\n{json.dumps(metadata, ensure_asciiFalse, indent2)}\n---\n\n{content}) all_metadata.append(metadata) success_count 1 else: failed_urls.append(url) except Exception as e: print(f抓取 {username} 失败: {e}) failed_urls.append(profile_url) # 保存元数据汇总 with open(f{output_dir}/metadata.json, w, encodingutf-8) as f: json.dump(all_metadata, f, ensure_asciiFalse, indent2) # 记录日志 with open(f{output_dir}/archive.log, a, encodingutf-8) as f: f.write(f[{datetime.now().isoformat()}] 成功: {success_count}, 失败: {len(failed_urls)}\n) print(f\n✅ 抓取完成共成功 {success_count} 篇失败 {len(failed_urls)} 篇) if failed_urls: print(失败 URL 列表:) for u in failed_urls[:5]: # 只显示前5个 print(f - {u}) if len(failed_urls) 5: print(f ... 还有 {len(failed_urls)-5} 个)这个batch_scrape函数的关键设计点在于失败不中断记录后继续。Medium 的个别文章可能因作者设置为“仅限会员阅读”而返回 403或因临时网络抖动超时若遇到错误就退出100 篇文章里一个失败就得重来。而记录失败 URL 并继续既能保证整体进度又能事后针对性重试。我通常会把failed_urls导出为 CSV用 Excel 筛选“403 错误”然后手动检查是否为私密文章——如果是就跳过如果是网络问题就单独重试。4.4 本地化 Markdown 的进阶应用不只是存档生成的 Markdown 文件不是终点而是新工作流的起点。我日常用它们做三件事同步到 Obsidian 知识库Obsidian 支持直接打开文件夹作为 vault。我把medium-archive/stories/设为 vault 根目录所有文章自动成为笔记用[[链接]]语法建立跨文章引用比如在《Svelte 性能优化》里写[[为什么我从 React 切换到 Svelte]]点击即跳转。Obsidian 的图谱视图还能可视化我的技术写作脉络。生成静态博客用 Hugo 的archetypes功能把metadata.json中的字段映射为 front mattercontent部分作为正文一键生成public/站点。Hugo 的goldmark渲染器完美支持代码块高亮和数学公式效果远超 Medium 原生。训练个人写作模型把所有content字段喂给 Llama 3-8B在本地微调一个“我的写作风格”模型。提示词很简单“请模仿 James Chen 的 Medium 文章风格写一篇关于 WebAssembly 在边缘计算中应用的 800 字技术短文。” 输出结果虽不能直接发布但能快速生成初稿框架节省 60% 的构思时间。这些应用的前提是内容已脱离 Medium 的封闭生态成为你硬盘上可编程、可索引、可组合的原子数据。这才是“Scraping Your Medium Stories”最深层的价值它不是数据搬运而是数字主权的收复仪式。5. 常见问题与排查技巧实录5.1 问题速查表90% 的失败都源于这 5 类原因现象可能原因排查命令/方法解决方案requests.get()返回 403Medium 对 IP 的隐式限流curl -I https://medium.com/username加time.sleep(1)降低 QPS或更换代理 IP仅限自己家庭宽带勿用公共代理池soup.select_one(article[data-layoutpost])返回NoneURL 不是文章页而是主页或 404print(resp.url)查看重定向后的真实 URL检查输入 URL 是否为medium.com/user/slug格式排除medium.com/latest等聚合页提取的title为空h1标签被包裹在div中或 class 名变更print(soup.select(h1))查看所有 h1更新 selector 为h1, .pw-title, .mi-title用逗号分隔多选项代码块内容乱码或缺失code标签内含 HTML 实体如lt;print(code_elem.encode_contents())在提取时用code_elem.decode_contents()替代get_text()图片下载失败404Medium CDN URL 过期或格式变更curl -I https://cdn-images-1.medium.com/...改用img.get(data-src, )作为备用源Medium 的>

相关新闻

aops-ceres客户端部署教程:一键安装与命令行接口全解析

aops-ceres客户端部署教程:一键安装与命令行接口全解析

aops-ceres客户端部署教程:一键安装与命令行接口全解析 【免费下载链接】A-Ops the intelligent ops toolkit for openEuler 项目地址: https://gitcode.com/openeuler/A-Ops 前往项目官网免费下载:https://ar.openeuler.org/ar/ aops-ceres是op…

2026/7/12 4:12:39阅读更多 →
Anaconda 2025.06 环境配置:Windows/Linux/MacOS 三平台 5 步快速安装与清华源配置

Anaconda 2025.06 环境配置:Windows/Linux/MacOS 三平台 5 步快速安装与清华源配置

Anaconda 2025.06 三平台极速部署指南:从安装到镜像优化实战 对于数据科学和机器学习从业者来说,Anaconda 依然是跨平台开发环境的首选工具。2025.06 版本带来了更快的包解析速度和更智能的依赖冲突解决方案,但不同操作系统下的安装配置差异…

2026/7/12 4:07:39阅读更多 →
VSCode Git 实战:3步配置 .gitignore 与 package-lock.json 管理策略

VSCode Git 实战:3步配置 .gitignore 与 package-lock.json 管理策略

VSCode Git 实战:3步配置 .gitignore 与 package-lock.json 管理策略当你在团队协作中遇到node_modules冲突或依赖版本不一致的问题时,是否曾思考过如何通过 Git 配置来避免这些困扰?本文将带你深入理解 VSCode 中 Git 工作流的核心配置逻辑&…

2026/7/12 4:07:39阅读更多 →
MAX77654与TM4C129ENCZAD电源管理方案设计与优化

MAX77654与TM4C129ENCZAD电源管理方案设计与优化

1. 项目背景与需求分析在嵌入式系统开发领域,电源管理一直是决定产品成败的关键因素之一。随着物联网设备的普及和边缘计算的兴起,对高效能、低功耗的电源解决方案需求愈发迫切。我们团队最近完成了一个基于MAX77654和TM4C129ENCZAD的电源管理方案设计&a…

2026/7/12 5:27:44阅读更多 →
Cisco Packet Tracer 校园网设计:3层架构与VLAN规划对比2栋教学楼方案

Cisco Packet Tracer 校园网设计:3层架构与VLAN规划对比2栋教学楼方案

Cisco Packet Tracer校园网三层架构设计:从基础路由到VLAN进阶实践1. 校园网架构演进:从简单路由到三层交换校园网络设计从来不是一成不变的模板化工程。十年前,我们可能还在用几台路由器串联不同教学楼;而今天,任何超…

2026/7/12 5:27:44阅读更多 →
分类评估指标本质:从混淆矩阵到业务决策的完整指南

分类评估指标本质:从混淆矩阵到业务决策的完整指南

1. 这不是“选个指标凑数”的事:分类问题评估指标到底在回答什么问题?你训练完一个分类模型,准确率98%,心里刚冒出一丝得意,结果业务方甩来一句:“那剩下2%的错,错在哪儿?值不值得救…

2026/7/12 5:27:44阅读更多 →
企业获客陷入瓶颈?沃创云 AI 获客系统帮企业破局增收

企业获客陷入瓶颈?沃创云 AI 获客系统帮企业破局增收

市场内卷加剧,客户难挖掘、获客成本高、销售耗时长,成为制约企业发展的普遍难题。沃创云优选商机智能获客运营平台,结合大数据资源与真人 AI 电话机器人,高效拓客,助力企业业绩稳步上涨。海量资源筑牢获客根基&#xf…

2026/7/12 5:27:44阅读更多 →
不锈钢非标零件加工,为什么容易变形?

不锈钢非标零件加工,为什么容易变形?

在精密机械加工中,不锈钢非标零件一直是比较常见的加工难点。尤其是 304、316 等材料制成的薄壁件、长条形零件、六面体支架,在 CNC 加工后很容易出现弯曲、翘曲、端面不平、孔位偏移等问题。 很多时候,零件在打样阶段还能勉强符合要求&#…

2026/7/12 5:27:44阅读更多 →
Godot开发效率提升指南:Awesome-Godot资源库实战应用与避坑

Godot开发效率提升指南:Awesome-Godot资源库实战应用与避坑

1. 项目概述:为什么你需要Awesome-Godot?如果你正在用Godot引擎做游戏,或者刚刚对它产生兴趣,那你大概率听说过“Awesome-Godot”这个名字。它不是一个具体的游戏项目,而是一个在GitHub上由社区维护的、汇集了海量Godo…

2026/7/12 5:22:43阅读更多 →
VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异当你在VSCode中启动一个新的TypeScript项目时,第一个技术决策往往从安装方式开始。这个看似简单的选择——全局安装还是项目本地安装——实际上会深刻影响你的开发流程、团队协作和…

2026/7/12 0:02:11阅读更多 →
智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手 【免费下载链接】zhihuishu 智慧树刷课插件,自动播放下一集、1.5倍速度、无声 项目地址: https://gitcode.com/gh_mirrors/zh/zhihuishu 智慧树刷课插件是一款专为智慧树在线教育平台设计的Chrome浏…

2026/7/12 0:02:11阅读更多 →
Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案 【免费下载链接】WorkshopDL WorkshopDL - The Best Steam Workshop Downloader 项目地址: https://gitcode.com/gh_mirrors/wo/WorkshopDL 你是否在GOG或Epic Games Store购买了心仪的游戏…

2026/7/12 0:02:11阅读更多 →
VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异当你在VSCode中启动一个新的TypeScript项目时,第一个技术决策往往从安装方式开始。这个看似简单的选择——全局安装还是项目本地安装——实际上会深刻影响你的开发流程、团队协作和…

2026/7/12 0:02:11阅读更多 →
智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手 【免费下载链接】zhihuishu 智慧树刷课插件,自动播放下一集、1.5倍速度、无声 项目地址: https://gitcode.com/gh_mirrors/zh/zhihuishu 智慧树刷课插件是一款专为智慧树在线教育平台设计的Chrome浏…

2026/7/12 0:02:11阅读更多 →
Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案 【免费下载链接】WorkshopDL WorkshopDL - The Best Steam Workshop Downloader 项目地址: https://gitcode.com/gh_mirrors/wo/WorkshopDL 你是否在GOG或Epic Games Store购买了心仪的游戏…

2026/7/12 0:02:11阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/11 16:20:28阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/11 23:15:38阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/11 18:12:23阅读更多 →