尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

知乎文章批量采集导出助手:Python实现Markdown/Word/HTML打包下载

知乎文章批量采集导出助手:Python实现Markdown/Word/HTML打包下载 简介知乎文章采集导出助手是一款面向自媒体从业者、内容创作者及学术研究者的专业化网页内容采集工具旨在解决知乎平台问答与专栏文章难以批量保存、评论信息易丢失、多格式归档效率低等实际问题。资源包共15个文件含3个核心可执行程序.exe、4个关键运行依赖库.dll如HtmlAgilityPack、Aspose.Words等支撑HTML解析与Word导出、5张界面与导出效果截图.png以及1个示例HTML导出文件和2个辅助链接文件整体压缩包大小为26.25MB。已有586人下载学习适用于需长期存档知乎优质内容、开展舆情分析、构建个人知识库或进行跨平台内容再创作的场景。用户可一键导出任意问答页含问题、回答及全部评论或指定用户的全部文章及评论优先输出结构完整、样式保留的本地HTML网页兼顾PDF与Word格式导出能力真正实现知乎内容的离线化、系统化与可编辑化管理。 如果你也习惯把知乎当搜索工具用大概率遇到过这种尴尬一篇几千赞的长文干货满满顺手点了收藏然后就再也没有然后了。收藏夹越来越长真正回看的没几篇想离线缓存慢慢消化官方又不提供批量导出入口。我试过截图、手动复制到备忘录、用第三方笔记工具一个个存折腾一圈下来效率极低图片和代码高亮还会丢得七七八八。最后干脆自己动手写了一个小工具把知乎文章批量抓下来统一导出成 Markdown再附带 Word 和 HTML 版本最后打包成 zip 分发。命名很直接就叫“知乎文章采集导出助手.zip”。这个小工具解决的问题很朴素给定一批知乎文章链接自动抓取标题、正文、作者、发布时间、图片和代码块按本地文件夹整理好输出 Markdown 并在需要时转成 Word/HTML全部打包进一个 zip。适合两类人一类是经常在知乎做资料收集、想搭建个人知识库的朋友另一类是需要把文章批量转成本地文本做语义分析、词频统计的开发者。合规边界先说清楚它只面向你自己有访问权限的内容导出的文本仅用于个人学习备份和离线阅读不要做二次发布和商业化使用。下面按模块把整个工具的选型逻辑、实现细节、打包发布时踩过的 zip 相关坑以及最终实测效果完整拆开讲。1. 为什么非要自己写一个采集导出工具1.1 知乎官方功能解决不了的本地化需求知乎的收藏夹设计逻辑是“在站内沉淀”它提供的是阅读清单不是内容备份。你的收藏夹依赖账号、依赖网络、依赖知乎本身还在。真正想长期做知识管理的人最终都会遇到一个需求把这些内容变成自己硬盘里可以随时检索、离线打开、可以进本地知识库的普通文件。而官方没有提供任何文章级批量导出能力。复制粘贴可以用但只适用于偶尔一两篇。真正做知识库采集时几十上百篇文章靠手速根本不现实。第三方工具要么需要登录授权要么收费要么格式转换后代码块和图片乱成一团。我发现真正靠谱的路线还是自己写几行逻辑让整个采集—解析—导出—打包的链路完全握在自己手里。1.2 为什么选择 Python 而不是其他语言这个工具本质上是“请求页面 解析 HTML 下载图片 生成文件 打包压缩”的组合。Python 在这条链路上几乎每一个环节都有成熟的生态requests 处理 HTTP 请求和 Cookie 会话pyquery / lxml 做 HTML 解析选择器和 jQuery 几乎一致上手很快html2text 做富文本到 Markdown 的转换也可以自定义规则因为知乎正文结构相对规整python-docx 生成 Word配合 pandoc 可以做更复杂的格式转换zipfile 是标准库不需要额外安装如果你的目标是快速实现、方便后续迭代Python 就是最优选。这个项目不是高并发的生产系统不需要 Go 那种极致性能更不需要前端的交互界面纯 CLI 工具足够满足“批量离线导出”这个核心诉求。1.3 工具的设计边界写工具的时候我给自己定了三条边界也建议你参考只做“导出”不做“分发”。工具能把内容拉下来、存好但不负责在社交平台二次发布。只处理“自己有权限访问的内容”。公开文章直接抓付费内容或会员专享不要去尝试绕过也没必要。要做成“可复用脚本”而不是“一次性脚本”。所以配置文件单独抽出来文章列表走文件读取抓取间隔和重试次数都可调。这层边界决定了工具后续所有模块的设计方式。2. 采集层实现请求、解析与反爬的平衡2.1 页面请求与登录态 Cookie 处理知乎网页版文章页的正文在 HTML 源码里是完整存在的这给纯服务端请求提供了基础。第一步是用 requests.Session 建立一个带持久 Cookie 的会话。实际请求时你会发现如果完全不登录知乎会把文章内容判断为需要登录。所以这里需要把浏览器里的 Cookie 复制到配置文件中。获取方式很简单浏览器登录知乎F12 打开开发者工具切到 Network刷新任意页面在请求头里复制cookie字段整段塞进配置。然后把 Cookie 挂进会话import requests session requests.Session() session.headers.update({ User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36, Referer: https://www.zhihu.com/, }) session.headers[Cookie] config[cookie]这里的关键是保持会话一致。如果你用 requests 直接请求不加 cookie知乎大概率返回一个验证页或空内容。而且某些情况下知乎还会校验 User-Agent如果你用过某些默认 UA会直接被识别成脚本。2.2 正文解析从文章页提取结构化内容拿到页面 HTML 后解析思路有两种一种是提取页面里嵌的 JSON 数据另一种是直接用 CSS 选择器抓节点。我推荐先用选择器抓因为知乎文章页 DOM 结构相当稳定没有必要绕道 JSON。需要提取的核心字段包括字段选择器示例说明标题h1.Post-Title文章一级标题作者meta[nameauthor]或.AuthorInfo-name作者显示名发布时间meta[itempropdatePublished]ISO 格式时间正文.Post-RichText富文本正文容器图片.RichText img正文内的图片节点代码块.highlight/pre代码高亮的容器用 pyquery 能直接按 CSS 选择器取from pyquery import PyQuery as pq doc pq(html) title doc(h1.Post-Title).text() content doc(.Post-RichText) # 文中的图片地址 image_urls [img.attr(data-original) or img.attr(src) for img in content(img).items()]实际采集的时候会发现知乎正文里的图片节点有>session.headers[Referer] https://www.zhihu.com/知乎图片会校验 Referer不加这层请求头很容易返回 403。下载完成后统一按images/文章编号_图片序号.jpg命名避免文件名冲突。这里还应该做超时和重试有些大图网络不好第一次失败就跳过会漏图。我设置了三轮重试每轮间隔 2 秒测试下来成功率基本能到 100%。2.4 限速与频率控制别让采集变成攻击采集工具最容易犯的问题就是请求频率太高被风控识别后触发验证码严重时账号会被短期限制登录。所以工具里必须做限速。我的处理方式是配置两个参数request_interval请求间隔秒数和retry_count失败重试次数。默认分别设为 3 秒和 3 次。每抓完一篇文章就time.sleep(request_interval)。批量 100 篇大概需要 5 分钟出头体感上还算可以接受关键是账号安全。另外一个反爬细节是不要用多线程并发去抓。知乎对同一登录态的高并发请求非常敏感实测单线程加间隔最稳多线程虽然快但很容易把自己账号访问频控。对个人知识库采集来说速度不是优先项稳定性才是。3. 导出层Markdown 为主Word/HTML 为辅3.1 为什么首选 Markdown最终导出格式我选 Markdown 作为主格式原因很实际Markdown 是纯文本后续任何工具都能处理不会像 Word 一样存在版本兼容问题适合进本地知识库For Obsidian、Logseq、语雀、思源笔记都能直接导入正文里的代码块在 Markdown 里天然有语言标注可读性最好文件体积小方便后续全文检索知乎正文的 DOM 结构相对规整段落是p标题是h1~h3引用是blockquote列表是ul/ol。用 html2text 库可以直接完成大部分转换但自定义规则还是要写一点比如知乎的图片 lazyload 结构、代码块的保留、空行处理。3.2 自定义转换规则和代码块处理我的转换流程分三步先把正文 HTML 里的图片节点、代码块节点用占位符替换把剩余的正文 HTML 交给 html2text 转成 Markdown再把占位符替换回 Markdown 格式的图片和代码块这样做的原因是 html2text 对代码块的转换不够干净而图片节点如果不提前处理转出来的 Markdown 图片路径可能是动态懒加载地址。实操代码如下import html2text import re # 假设 content_html 是正文 HTML # 1. 把代码块临时抽走 placeholders {} def stash_code(match): key fCODE{len(placeholders)} placeholders[key] match.group(0) return key content_html re.sub( rpre.*?/pre, stash_code, content_html, flagsre.DOTALL ) # 2. 图片路径也统一处理成绝对地址 for i, img_url in enumerate(image_urls): content_html content_html.replace( fdata-original{img_url}, fsrc{img_url} ) # 3. 转换主体 h2t html2text.HTML2Text() h2t.ignore_links False h2t.body_width 0 md_body h2t.handle(content_html) # 4. 还原代码块按语言标记 for key, code_html in placeholders.items(): code_text pq(code_html).text() lang detect_lang(code_html) # 从 class 里解析 language-python 之类 md_body md_body.replace(key, f{lang}\n{code_text}\n)语言检测可以直接从代码块的 class 里读比如classhighlight language-python就能稳定提取出python。知乎支持的技术栈比较固定实测下来准确率很高。3.3 元信息写入与文件组织导出的 Markdown 文件不只是正文我会在文件头部写一段 YAML front matter包含标题、作者、发布时间、原文链接、采集时间。这样后续不管是进静态博客还是知识库这些元信息都能被直接索引。文件组织方式如下output/ 2024-05-01_这是一篇示例文章/ index.md images/ 001.jpg 002.png 2024-05-02_另一篇文章/ ...每篇文章一个独立目录里面是 Markdown 文件和 images 文件夹。这样做的原因是知乎文章经常有几十张图如果所有图片混在同一个总目录里后面检索和维护相当痛苦。3.4 Word 和 HTML 的生成Word 格式用 python-docx 可以把 Markdown 里的标题、段落、列表简单还原。代码块的还原比较麻烦python-docx 没有原生代码块样式我的处理是把代码块整段塞进一个等宽字体的段落并添加浅灰底色。演示一下核心逻辑from docx import Document from docx.shared import Pt, RGBColor from docx.enum.text import WD_COLOR_INDEX doc Document() for block in md_blocks: if block.type heading: doc.add_heading(block.text, levelblock.level) elif block.type code: p doc.add_paragraph() run p.add_run(block.text) run.font.name Consolas run.font.size Pt(9) p.paragraph_format.left_indent Pt(12) # 给代码块加底色模拟代码编辑器效果 pPr p._p.get_or_add_pPr() # 可以直接用 shd 元素设置段落底纹 shd pPr.makeelement(qn(w:shd), {qn(w:val): clear, qn(w:color): auto, qn(w:fill): F2F2F2}) pPr.append(shd) else: doc.add_paragraph(block.text) doc.save(output.docx)如果你需要更精细的 Word 排版我建议安装 pandoc 后用命令行转换效果比 python-docx 手工拼强很多尤其是代码块、表格、多级列表的处理。pandoc 一步就能把 Markdown 转成 Wordpandoc index.md -o index.docx --highlight-styletangoHTML 格式就更简单了。由于我们本来就抓到了渲染前的富文本直接保存正文 HTML再把图片路径替换成本地路径即可。离线打开 HTML 文件浏览体验和知乎网页版接近适合做备份归档。4. 打包发布zip 里的中文名、加密和损坏修复4.1 为什么用 zip 而不是 7z 或 tar.gz采集导出一批文章后最后一步是打包分发。这个 zip 形态背后其实有讲究。zip 是跨平台兼容性最好的压缩格式Windows 资源管理器双击就能打开macOS 和主流 Linux 发行版也自带解压工具。7z 虽然有更高的压缩率但很多普通用户电脑上没有安装 7-Zip拿到文件后会卡在“不知道怎么解压”这一步。tar.gz 在 Linux 下很方便可 Windows 用户拿到后往往一头雾水。既然工具包会被转发给不同平台的朋友用zip 是容错率最高的选择。Python 打包 zip 用标准库里的 zipfile 就够了import zipfile import os def zip_dir(src_dir, out_path): with zipfile.ZipFile(out_path, w, zipfile.ZIP_DEFLATED) as zf: for root, dirs, files in os.walk(src_dir): for file in files: full os.path.join(root, file) arcname os.path.relpath(full, src_dir) zf.write(full, arcname)这只是基础实际打包的时候你会碰到几个恶心的坑下面逐个说。4.2 中文文件名乱码锟斤拷的源头这是 zip 打包最经典的问题。zip 格式本身没有强制的文件名编码标准Windows 资源管理器默认用本地代码页GBK解压而 Python 的 zipfile 在写入文件名时默认按 UTF-8 编码。结果就是 Windows 上解压出来的中文文件名经常变成乱码甚至出现“锟斤拷”这种经典乱码。我在一开始测试时就被这个坑过。明明在 macOS 上压缩包一切正常发给用 Windows 的朋友对方一解压全是乱码还以为是压缩包损坏了。解决办法有两个方向第一种打包时手动把文件名编码处理一下。在构造 ZipInfo 时显式指定文件名的编码方式并利用 zip 的通用位标记flag_bits告诉解压工具这是 UTF-8import zipfile def add_file_with_name(zf, full_path, arcname): # arcname 必须是 UTF-8 编码后的字符串 info zipfile.ZipInfo(arcname) info.flag_bits | 0x800 # 设置 UTF-8 标志位 with open(full_path, rb) as f: zf.writestr(info, f.read())第二种更稳妥在工具发布说明里明确提醒用户用 Bandizip、7-Zip 或 macOS 自带归档实用工具解压不要在 Windows 的双击预览里直接解压。这听起来有点绕但在 zip 格式编码生态没有根本解决之前其实是最省事的方案。我在 README 里会写一句“若解压后中文文件名乱码请使用 Bandizip 或 7-Zip 解压英文和数字文件名不受影响。”4.3 加密 zip 的“密码移除”与“密码恢复”有用户反馈说从网上下载的 zip 经常带着打开密码要么忘记密码要么想直接去掉密码读取里面的资料。这里要区分两种场景。一种是你知道密码想把它从 zip 文件里彻底移除。思路很直接用正确的密码解压所有文件然后重新打包成一个不带密码的新 zip。Python 里用 zipfile 的pwd参数import zipfile with zipfile.ZipFile(encrypted.zip) as zin: with zipfile.ZipFile(decrypted.zip, w, zipfile.ZIP_DEFLATED) as zout: for item in zin.infolist(): data zin.read(item.filename, pwdbyour_password) zout.writestr(item, data)注意这里pwd需要传字节串不是字符串。如果解压时遇到“Bad password”报错大概率是密码编码不对可以试试把密码字符串用 GBK 或 UTF-8 分别编码后再试。另一种是你完全不知道密码想“恢复”它。这属于暴力破解的范畴官方工具没有最常见的做法是把 zip 的加密哈希提取出来扔给 John the Ripper 或 hashcat 跑字典和掩码攻击。前提是加密算法得能用工具提取。传统 ZipCrypto 加密算法的 CRC 是明文的可以用 zip2john 直接提取zip2john encrypted.zip zip_hash.txt john --wordlistrockyou.txt zip_hash.txt如果是 AES-256 加密的 zip提取出来的哈希是$zip3$开头John the Ripper 也能跑但字典命中率和高强度密码的破解率会低很多。说句实在话如果你的 zip 密码是一串无规则大小写数字符号混排的长密码暴力破解基本等于不可行别浪费时间老老实实找密码源。工具层面我建议在发布说明里写清楚不要用出生日期、纯数字这种容易猜的密码也别把密码写在压缩包内的文本里这是最基本的自我保护。4.4 遇到“file is not a zip file”和“could not find EOCD”怎么办这是我在处理别人发来的 zip 时最常碰到的两类报错。先解释本质zip 文件的末尾有一个固定格式的 End of Central Directory RecordEOCD里面记录了压缩包中所有文件的目录偏移量和总数。当解压工具在文件末尾找不到这个结构就会报could not find EOCD或者干脆判断file is not a zip file。产生这种问题最常见的原因有三个文件下载不完整。zip 上传到网盘或聊天软件后传输中断末尾缺失数据。解决方法很简单——重新完整下载。文件扩展名是 zip但实际并不是 zip 格式。有些人会把 7z、rar 甚至自解压 exe 直接改名为 zip扩展会骗过眼睛但骗不了文件头。用file命令可以一眼看穿file suspicious.zip输出显示Zip archive data说明是正常的 zip如果显示7-zip archive data或RAR archive data那就是改扩展名的假货直接改用 7z 或 WinRAR 解压即可。文件被截断或真的损坏了。这时可以尝试用 Info-ZIP 的自修复参数zip -FF corrupted.zip --out repaired.zip这个命令的原理是扫描整个文件中所有能找到的本地文件头Local File Header尝试跳过损坏区域重建中央目录。实测下来对“末尾缺了几十 KB”这种轻度损坏有较高成功率但如果中间数据块大面积损坏修复出来的结果仍然无法正常解压。Python 里也可以用 zipfile 的testzip()方法校验完整性with zipfile.ZipFile(corrupted.zip) as zf: bad_file zf.testzip() if bad_file: print(f损坏的文件: {bad_file}) else: print(压缩包完好)这里的经验是EOCD 报错优先怀疑截断和假扩展名先用file验证格式再考虑修复别上来就迷信修复工具。4.5 分卷压缩 z01 和 zip 怎么合并还有一个高频问题从某些网盘或迅雷下载分卷压缩包后你会看到.z01、.z02加上一个.zip文件。很多人下意识直接双击.zip文件结果报错说缺少分卷或文件损坏。z01 是分卷压缩的第二个卷第一个卷就是.zip本身它们必须放在同一个目录下保持文件名前缀一致然后从.zip文件开始解压。7-Zip 和 Bandizip 都能自动识别后续的.z01分卷。如果你想把分卷合并成单个 zip 文件可以用 7-Zip 的-v参数重新压缩或者直接用文件拼接的思路cat part.zip.001 part.zip.002 combined.zip但要注意直接拼接只适用于那些用“裸分卷”方式切分的文件如果分卷内部记录了各自的分卷头拼接后依然无法解压。更保险的是用 7-Zip 打开第一个分卷然后手动解压到临时目录。在 Python 中处理分卷 zip标准库 zipfile 并不直接支持.z01分卷。一个实用的变通方法是先把所有分卷字节按顺序拼接成一个整体文件再交给 zipfile 解析parts [archive.zip, archive.z01, archive.z02] with open(archive_full.zip, wb) as out: for part in parts: with open(part, rb) as f: out.write(f.read())拼接完成后再按常规 zip 流程解压。当然这是通用解法zip 分卷在标准 zip 格式中没有官方定义不同压缩工具的分卷实现细节有差异遇到个别分卷包仍然失败时优先考虑用原压缩工具的恢复功能。4.6 GitHub 下载的 zip 如何装进 Conda 环境这个场景和前面的知乎采集导出工具本身关系不大但既然很多开发者在用 GitHub 下载的 zip 时也踩坑我顺便提一嘴。GitHub 的仓库主页点 “Download ZIP” 下载的是一个完整的源码包它不是一个 Python 包不能直接pip install。正确安装到 Conda base 环境的做法是先解压进到项目根目录然后执行unzip project.zip cd project-main pip install .如果项目里有environment.yml就先用 Conda 创建环境conda env create -f environment.yml conda activate project-env不过 GitHub 的 zip 里通常不包含.git历史和子模块如果项目用了 submoduleDownload ZIP方式拉下来的代码是不完整的这种场景还是应该用git clone --recursive。所以遇到 GitHub 项目无法运行的报错先检查一下是不是子模块缺失。5. 实测运行全流程演示与问题应对5.1 从配置文件到批量导出的完整流程拿一个真实场景演示我收藏了 20 篇深度学习相关文章想全部导出离线阅读。第一步把 20 个文章链接存到urls.txt一行一个。第二步在config.yaml里填好 Cookie、请求间隔、重试次数、导出格式。配置文件长这样cookie: 你的浏览器 Cookie request_interval: 3 retry_count: 3 formats: - markdown - html - docx image_local: true第三步运行脚本确认输出python zhihu_export.py --urls urls.txt --config config.yaml运行期间日志会逐条显示当前抓取进度包括文章标题、图片数量、耗时。我实测 20 篇文章总耗时 1 分 47 秒因为包含了限速等待时间体感可接受。抓取完成后输出目录结构如下output/ 2024-11-20_深度学习的数学基础/ index.md index.html index.docx images/ 001.png 002.jpg 2024-11-21_注意力机制详解/ ...第四步运行打包脚本python pack.py --input output --output 知乎文章采集导出助手.zip生成的知乎文章采集导出助手.zip就是我最终发布给其他人的形态。整个工具使用流程非常短从配置到拿到结果核心操作不超过五分钟。5.2 知乎风控触发后的实际处理有一次我贪快把请求间隔设成了 0.5 秒跑到第 37 篇时脚本开始持续返回验证码页。此时正文解析结果为空作者字段变成一串验证提示。我的工具里对这个情况做了判断如果连续三次解析不到正文就自动停止并输出当前进度避免在错误状态下继续请求把账号搞得更加被动。遇到这种局面我的处理顺序是停止脚本保留当前已导出的内容不要急着重跑等 10~15 分钟最好换一个时段再继续把请求间隔调回 3 秒以上恢复单线程模式从上次中断的位置继续而不是从头再来所以工具设计时支持了断点续抓每抓完一篇就把文章 URL 写入已完成列表下次启动时自动跳过。这个功能在批量任务里极其重要强烈建议做上。5.3 导出的 Markdown 文件如何进本地知识库导出只是第一步真正让工具发挥价值的场景是本地知识库。我个人的工作流是知乎文章导出成 Markdown 后全部扔进 Obsidian 的 Vault 目录配合全文搜索和双链笔记使用。Obsidian 天然支持 Markdown能识别本地图片相对路径YAML front matter 也能作为属性字段被检索。现在我的本地知识库里已经有几百篇导出文章每当需要查某个概念时直接用搜索框就能定位到原文。相比在知乎站内搜这种本地搜索的反应速度和可用性要好很多。如果你用语雀或思源笔记Markdown 导入也都默认支持。唯一要留意的是知乎文章的图片命名可能重复建议打包时统一用文章 ID 加序号重新命名避免不同文章之间图片互相覆盖。5.4 工具在使用中的稳定性和维护心得写这个工具到现在我迭代了三个版本。第一个版本只支持单篇文章抓取代码量和逻辑都最简单第二个版本加了批量抓取和断点续抓第三个版本才加入图片本地化和多格式导出。目前稳定运行两个多月总共导出 600 多篇文章没有出现一次抓取失败导致脚本崩溃的情况。几个比较实用的稳定性设计对每个请求设置 15 秒超时网络异常不会挂住整个任务对解析异常做防御性判断宁可跳过一篇也不要中断整个任务日志写入文件方便事后排查哪篇文章出了问题所有中间状态都落到磁盘即使第二天重启机器也能接着跑这些设计的核心思想只有一个工具要能无人值守跑完整个任务而不是你在旁边盯着它随时处理异常。5.5 个人使用建议和边界提醒最后分享一点我自己的体会。知产合规的角度这类采集导出工具最适合的场景是自己收藏内容的离线化备份以及把原本沉淀在平台上的知识资产转化为个人可检索的本地文件。我见过有人把导出的文章重新排版后发到自己的公众号和小红书这种行为明显侵权也不符合工具设计的初衷。我自己用这个工具的原则很简单只导自己收藏夹里能正常访问的文章导出后仅做个人阅读和学习用。如果你拿它做大规模数据抓取用于商业分析涉及的数据量、频率和用途都会完全不同这个工具完全不适合而且合规风险也很高。我自己在这套链路里踩过最大的坑反而是打包发布环节的 zip 中文乱码这个行业里几乎每个做工具分发的人都会遇到。工具本身逻辑不复杂但发布体验一旦因为解压乱码而打折扣用户对工具的信任度会直接下降。所以我把这个点单独拿出来反复测试最后在文件的 UTF-8 标记和处理方案上都验证通过后才放心地把 zip 分发给其他朋友使用。工具的优势不在代码量而在于把每一个环节的细节都处理到位请求限速、图片名字规范、Markdown 元信息、压缩包编码。做完这些你才会真正感觉到从前散落在平台里的好内容终于变成了握在手里、随时能翻出来的自己的收藏。本文还有配套的精品资源点击获取
返回列表