ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Jupyter Notebook 入门:从安装到实战的 Python 数据分析指南

Jupyter Notebook 入门:从安装到实战的 Python 数据分析指南 1. Jupyter Notebook 是什么为什么数据分析离不开它1.1 Jupyter Notebook 的基本概念很多刚开始接触 Python 数据分析的朋友可能都有过这样的经历用 VS Code 或者 PyCharm 写了一段数据处理的脚本运行完之后想看看中间某个变量的取值又得重新跑一遍想把分析思路和结果整理给同事看还得专门去找图表工具截图、贴文档过程非常繁琐。如果这个场景你遇到过那 Jupyter Notebook 就是绕不开的一个工具。Jupyter Notebook 是一个基于 Web 的交互式开发环境名字由 Julia、Python 和 R 三门编程语言的名称组合而来虽然它早期主要服务于这三种语言但现在已经支持几十种语言内核。它的核心特征是把代码、运行结果、图表、说明文字整合在同一个文档里这种文档就是 Notebook 文件后缀名为.ipynb全称是 Interactive Python Notebook。和传统 IDE 最大的区别是Jupyter Notebook 按照“单元格”Cell来组织内容。你可以把一段代码放在一个单元格里只运行这一格然后立刻看到输出结果也可以在两个代码单元格之间插入 Markdown 文本写下分析结论。这种交互方式非常契合数据分析工作的推进节奏读取数据、清洗数据、画图、验证假设、记录结论每一步都可以边做边看、边看边改。对于数据分析新人来说Jupyter Notebook 还有一个很大的优势不需要一开始就掌握完整的 Python 工程化能力比如模块拆分、打包、测试这些内容。它让你先把精力集中在数据本身用最短的时间完成数据探索和可视化代码的“草稿”属性天然适合这个场景。1.2 Jupyter Notebook 与 JupyterLab 的区别在搜索 Jupyter Notebook 相关教程的时候你一定会看到一个词JupyterLab。它们到底是什么关系很多初学者容易混淆。简单来说JupyterLab 是 Jupyter Notebook 的下一代界面产品。老版 Jupyter Notebook 是单文档界面也就是一个浏览器标签页里只能打开一个.ipynb文件。而 JupyterLab 是集成式开发界面它更像 VS Code 那种布局左侧是文件树右侧可以同时打开多个 Notebook、Python 文件、终端、CSV 预览表格窗口还能自由拖拽分栏。如果只是做基础的数据分析和可视化用传统的 Jupyter Notebook 完全可以胜任操作也更简单适合刚入门的朋友。但如果你经常需要在多个文件之间切换或者需要一边写数据处理脚本一边打开终端执行命令那 JupyterLab 的工作效率会更高。目前Anaconda 发行版默认自带的通常就是 JupyterLab 和经典版 Notebook 两个入口。本文后面的操作主要以经典版 Jupyter Notebook 为例展开安装方式完全兼容 JupyterLab读者可以根据自己的界面偏好选择。1.3 Jupyter Notebook 的典型应用场景Jupyter Notebook 的使用场景很广下面这些是比较典型的数据清洗与探索加载 CSV、Excel 数据库文件查看字段类型、缺失值、分布情况用 pandas 做聚合统计。数据可视化结合 Matplotlib、Seaborn、Plotly 等库把数据分布、趋势、相关性画成图。教学与演示很多高校的 Python 数据分析课程、线上教程都直接用 Notebook 作为教材因为它能同时展示代码、输出和讲解文字读者可以一边阅读一边运行。算法原型验证做机器学习模型时可以先在 Notebook 里快速验证思路确认效果后再把代码工程化。数据分析报告把分析过程、结论、图表整合到一个 Notebook 文件里导出为 HTML 或 PDF 分享给团队。2. 环境准备与安装步骤2.1 安装方式选型Anaconda、Miniconda、pip安装 Jupyter Notebook 有几种常见路径先搞清楚它们的区别再选适合自己的方式会更好。第一种是安装 Anaconda。它是一个 Python 发行版预装了 Python、Jupyter Notebook、JupyterLab 以及 pandas、NumPy、Matplotlib 等约 250 个常用数据科学包。适合新手安装完几乎不用再为依赖操心缺点是安装包较大占用磁盘空间相对多。第二种是安装 Miniconda。它只包含 conda 环境和 Python 基础环境不预装 Anaconda 自带的数据科学包你可以按需创建环境并用 conda 安装自己需要的库。体积小、更灵活适合对依赖管理有一定熟悉度的人。第三种是直接用 pip 安装。如果你电脑上已经装了 Python可以直接用 pip 安装 Jupyter Notebook。这种方式最轻量不引入额外的环境管理工具但后续安装数据分析库时依赖冲突的概率会更高一些建议搭配虚拟环境使用。对于没有任何 Python 基础、目标是做数据分析的朋友我更推荐直接安装 Anaconda这是当前最省心的方案。本机 Python 环境已经比较干净并且希望尽量少装东西的读者也可以用 pip 方式安装。2.2 通过 Anaconda 安装 Python 与 Jupyter NotebookAnaconda 的安装流程比较直观。先到 Anaconda 官网下载对应操作系统的安装包Windows 下载.exe文件macOS 下载.pkg或.sh文件Linux 下载.sh文件。版本需要根据你的操作系统和安装时间选择官网展示的即为当前最新稳定版本文重点演示安装后的配置思路不建议提前锁定某个旧版本号。Windows 安装时有一个容易忽视的选项安装到当前用户还是所有用户。建议选择“Just Me”安装到当前用户目录这可以避免之后因为权限不足导致无法创建虚拟环境。另一个选项是“Add Anaconda3 to my PATH environment variable”官方默认不建议勾选因为把 conda 加入全局 PATH 可能会影响系统其他软件依赖的 Python 环境。如果安装时没有勾选使用 Anaconda PromptAnaconda 自带的命令行工具来执行命令即可不需要手动修改 PATH。安装完成后在开始菜单中找到 Anaconda Prompt打开后执行conda --version能看到 conda 版本输出说明环境安装成功。接着安装或确认 Jupyter Notebook。Anaconda 默认已经自带 Jupyter如果某个环境里没有可以执行conda install jupyter也可以安装带科研常用扩展的版本conda install jupyter notebook输入y确认安装依赖后等待完成即可。2.3 通过 pip 安装 Jupyter Notebook如果选择 pip 方式建议先创建并激活一个虚拟环境避免把 Jupyter 装到全局 Python 环境里。下面在命令行中执行python -m venv myenvWindows 激活虚拟环境myenv\Scripts\activatemacOS 或 Linux 激活虚拟环境source myenv/bin/activate激活后命令行前面会出现(myenv)标记然后安装pip install notebook如果想使用 JupyterLab可以执行pip install jupyterlab国内网络环境下pip 下载速度慢时可以临时指定镜像源pip install notebook -i https://pypi.tuna.tsinghua.edu.cn/simple2.4 检查安装是否成功安装完成后在命令行执行jupyter notebook --version正常会输出类似6.x.x或7.x.x的版本号。注意如果看到的是命令未找到jupyter 不是内部或外部命令说明 Jupyter 的可执行文件没有被加入当前命令行环境的 PATH这种情况用 Anaconda Prompt 打开即可。接着启动 Jupyter Notebookjupyter notebook正常情况下命令行会打印类似下面的日志然后自动打开默认浏览器。[I 2024-01-01 10:00:00.123 LabApp] Jupyter Server 2.x.x is running at: [I 2024-01-01 10:00:00.123 LabApp] http://localhost:8888/tree这里的http://localhost:8888/tree就是 Notebook 的首页地址启动后建议先不要关闭那个命令行窗口因为它同时承担着服务进程的作用窗口关闭服务就会停止。3. Jupyter Notebook 核心概念与基本操作3.1 理解 Cell、Kernel 与 OutputJupyter Notebook 的学习曲线其实很平缓最难的部分往往不是界面操作而是理解几个核心概念。第一个概念是 Cell单元格。Notebook 页面里的每个输入框就是一个 Cell最常见的是两种类型Code代码单元格和 Markdown文本单元格。代码单元格里写 Python 代码按 Shift Enter 运行后会显示输出Markdown 单元格里写格式化文本运行后会将文本渲染成带标题、列表、链接的排版内容。第二个概念是 Kernel内核。Kernel 可以理解为 Notebook 背后的 Python 解释器进程。每打开一个 NotebookJupyter 会启动一个对应的 Kernel代码是在 Kernel 里执行的Notebook 页面只是前端展示界面。点击界面上的 Restart 按钮实际上就是重启了 Python 解释器变量会被清空代码运行状态也被重置。第三个概念是 Output输出区。每次运行代码单元格结果会显示在 Cell 下方。输出可以分为文本输出、错误信息、富文本输出比如表格、图片、交互式控件。理解这三种状态日常排错会轻松很多有输出不一定说明代码正确还要看输出本身是否为异常信息。3.2 命令模式与编辑模式Jupyter Notebook 的操作界面和普通文本编辑器不同它有模式区分。用鼠标点一下 Cell 内部进入的是“编辑模式”此时可以在里面输入代码或文本Cell 边框通常显示为绿色。按 Esc 键退出编辑模式进入“命令模式”此时可以通过键盘快捷键操作 Cell 本身边框显示为蓝色。很多人一开始不知道这个模式概念就会遇到“为什么按快捷键没反应”“为什么按 Esc 不能退出程序”这类问题。记住一个口诀编辑模式管内容命令模式管结构。要删除一个 Cell先鼠标点一下 Cell按 Esc 进入命令模式再按两次 d 键要新增一个 Cell在命令模式下按 a在上方插入或者 b在下方插入。3.3 常用快捷键Jupyter Notebook 高频快捷键并不多下面列出最常用的几个操作快捷键使用说明运行当前 CellShift Enter运行代码/渲染文本并跳转到下一个 Cell运行但不跳转Ctrl Enter运行当前 Cell焦点留在原处插入上方 CellEsc A在当前位置上方新增一个 Cell插入下方 CellEsc B在当前位置下方新增一个 Cell删除选中 CellEsc D D连续按两次 d 键切换为代码 CellEsc Y将当前 Cell 类型改为 Code切换为 Markdown CellEsc M将当前 Cell 类型改为 Markdown打开帮助面板Esc H显示快捷键列表这些快捷键没必要一次全记住先用熟 Shift Enter 和 a、b、dd其他遇到的时候再查帮助面板就行。3.4 Markdown 单元格使用技巧Markdown 单元格是 Notebook 区别于普通脚本文件的灵魂它可以让代码和说明相互配合形成“带讲解的可运行文档”。在 Markdown 单元格里比较常用的语法包括# 这是一级标题 ## 这是二级标题 **这是加粗文字** *这是斜体文字* - 列表项一 - 列表项二 1. 有序列表一 2. 有序列表二 [链接文字](https://example.com) 行内代码运行 Markdown 单元格后文字会按照排版格式渲染出来。双击渲染后的文本区域可以回到编辑状态继续修改。更实用的是Markdown 单元格支持 LaTeX 数学公式比如输入$$ y ax b $$可以渲染出专业的数学公式排版这在机器学习算法推导笔记中非常有用。4. Python 数据分析实战从数据读取到可视化4.1 创建第一个 Notebook启动 Jupyter Notebook 后在首页右上角点击“New”选择 Python 3就会创建一个新的 Notebook 文件。Jupyter 为默认的 Untitled 文件建议先将它重命名为数据分析实战.ipynb保存在一个专门的工作目录中。接下来先运行一个最简单的代码单元验证环境是否正常print(Hello Jupyter)输出Hello Jupyter看到这行输出说明 Notebook 环境已就绪。4.2 导入数据分析常用库做 Python 数据分析最常用的三个基础库是 pandas、NumPy 和 Matplotlib。pandas提供 DataFrame 数据结构用于读取、清洗、聚合表格数据。NumPy提供多维数组与数学函数是 pandas 和很多科学计算库的底层依赖。Matplotlib最经典的静态绘图库用来生成折线图、柱状图、散点图等图表。如果使用的是 Anaconda这三个库默认已安装如果用的是 pip 纯净环境需要先安装pip install pandas numpy matplotlib然后在 Notebook 第一个代码单元格中导入通常添加%matplotlib inline让图表直接显示在 Notebook 内import pandas as pd import numpy as np import matplotlib.pyplot as plt %matplotlib inline plt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] False这里设置字体是为了解决一个中文绘图常见问题直接在图上标记中文标题或坐标轴标签时默认字体可能显示为方框乱码。设置SimHei字体并将负号显示调整为unicode_minusFalse是大多数场景下的可行方案。但需要注意不同操作系统上可用中文字体不同macOS 可以改用Arial Unicode MS或PingFang SCUbuntu 可以改用WenQuanYi Micro Hei需要按实际环境调整。4.3 数据读取与基本探索为了演示我们生成一份模拟的销售订单数据字段包括日期、商品类别、销售额、利润然后用 pandas 构建 DataFrame。# 生成模拟数据 np.random.seed(42) date_rng pd.date_range(start2024-01-01, end2024-12-31, freqD) categories [电子产品, 家居用品, 服装, 食品] data { 日期: np.random.choice(date_rng, size500), 商品类别: np.random.choice(categories, size500), 销售额: np.random.uniform(50, 5000, size500).round(2), 利润: np.random.uniform(5, 800, size500).round(2), } df pd.DataFrame(data) df.head()运行后你会看到 DataFrame 的前 5 行输出这就是 Notebook 里最常见的“表格输出”。pandas 会自动以格式化的 HTML 表格展示数据非常直观。接下来用 pandas 查看数据基本情况df.info()输出显示每列的非空数量、数据类型和内存占用这是接手任何新数据集时最先要做的一步。再查看描述性统计df.describe()describe()对数值列会计算计数、均值、标准差、最小值、四分位数和最大值可以快速掌握销售额和利润的分布量级。4.4 数据可视化示例完成基础探索后用 Matplotlib 画图是 Jupyter Notebook 数据分析的高光时刻。先看商品类别的销售额汇总# 按商品类别汇总销售额和利润 category_summary df.groupby(商品类别)[[销售额, 利润]].sum().sort_values(销售额, ascendingFalse) category_summary然后绘制柱状图category_summary.plot(kindbar, figsize(10, 6)) plt.title(各商品类别销售额与利润汇总) plt.xlabel(商品类别) plt.ylabel(金额) plt.xticks(rotation0) plt.show()运行后Notebook 会直接显示柱状图并且图表下方保留代码单元格方便随时修改参数重新运行。再看销售额的时间分布。按月份重采样后画折线图# 将日期设为索引按月汇总销售额 df_monthly df.set_index(日期).resample(ME)[销售额].sum() df_monthly.plot(figsize(12, 5), markero) plt.title(2024年每月销售额变化趋势) plt.xlabel(月份) plt.ylabel(销售额) plt.grid(True, linestyle--, alpha0.5) plt.show()需要注意pandas 1.x 与 2.x 在时间重采样频率别名上存在差异。旧版本常用的resample(M)已经标记为弃用新版本推荐使用resample(ME)。如果你在运行时报错提示M已移除或警告建议升级 pandas 或改用ME。最后画一个销售额与利润的散点图观察它们之间是否存在正相关plt.figure(figsize(8, 6)) plt.scatter(df[销售额], df[利润], alpha0.5) plt.title(销售额与利润关系散点图) plt.xlabel(销售额) plt.ylabel(利润) plt.show()这一系列代码跑完后你就完成了一次标准的数据分析流程生成数据、查看结构、分组聚合、可视化、从图表中读取结论。4.5 结果说明与导出运行完上述代码后Notebook 中会依次保留每个单元格的输出包括汇总表格和图表。这意味着你最终拥有的不是零散的代码片段而是一份带过程、带结果、带讲解的分析报告。如果想要把 Notebook 分享给别人可以直接将.ipynb文件发给对方对方在本地 Jupyter 中打开即可继续运行修改。也可以导出为静态格式点击菜单栏 File → Download as选择 HTML 或 PDF。HTML 适合直接浏览器查看PDF 适合归档或提交报告。带代码和不带代码的 Markdown 导出也取决于你的需要通常给团队汇报时推荐导出为 HTML 或 PDF。5. Jupyter Notebook 常见问题与排查思路5.1 Jupyter Notebook 打开后空白页面这是搜索热度很高的问题之一。现象是启动命令后浏览器自动打开但页面长时间空白或者一直处于加载状态。常见原因和排查顺序如下问题现象常见原因解决思路页面完全空白浏览器缓存或扩展冲突强制刷新 Ctrl F5或用无痕模式打开地址白屏且控制台报 500 错误Notebook 服务配置文件异常检查启动日志定位错误信息卡在 Loading 界面Jupyter 版本与浏览器不兼容升级 Jupyter 版本或更换 Chrome/Edge 最新版长时间无响应端口被占用导致服务启动失败换端口启动jupyter notebook --port8889如果以上排查无效可以查看启动 Jupyter 的命令行窗口里面会打印具体的报错堆栈这是最有价值的排查线索。比如提示Permission denied很可能是项目目录没有写权限换个目录再启动试试。5.2 如何在其他浏览器打开 Jupyter NotebookJupyter 默认用系统默认浏览器打开但有些人更习惯用 Chrome 或 Edge 作为开发浏览器。这时不需要每次手动复制地址可以指定浏览器启动。一个常规做法是生成 Jupyter 配置文件然后修改浏览器启动命令。在命令行执行jupyter notebook --generate-config然后在生成的jupyter_notebook_config.py中搜索NotebookApp.browser按自己的操作系统写入对应内容。Windows 下以 Chrome 为例c.NotebookApp.browser C:/Program Files/Google/Chrome/Application/chrome.exe %s%s是 Jupyter 自动替换为 Notebook 地址的占位符不能省略。保存后重启 Jupyter 即可生效。5.3 Kernel 连接失败或崩溃现象是代码单元格右上角显示为灰色、运行时提示“Kernel died”或“Connection lost”。这种问题大多是内核运行环境出了问题最常见的是Notebook 是旧环境创建的但现在 conda 或 Python 环境已经变化导致找不到内核。解决思路是重启内核再看错误类型。另外如果代码中使用了会耗尽内存的操作比如直接读取一个非常大的数据集也可能导致 Kernel 被系统杀掉。此时优先检查是不是数据量过大或者代码里是否存在无限循环。排查时可以在命令行启动 Notebook 的窗口里看到 Kernel 退出时的日志。5.4 安装 pandas、numpy 时下载慢或失败使用 pip 安装依赖包时下载慢甚至超时通常是因为默认源是国外地址。可以临时指定国内镜像源或者把镜像写进全局配置pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple设置之后后续 pip install 都会优先走清华镜像。如果使用 conda也可以配置 conda 的国内 channel但需要谨慎修改避免混用不同 channel 造成依赖解析异常。6. 最佳实践与工程建议6.1 用虚拟环境隔离项目依赖Jupyter Notebook 让“快速编码”变得很便利但随之而来的依赖管理问题也容易被忽视。如果所有项目都共用一个 Python 环境可能遇到两个项目需要不同版本 pandas 的尴尬局面。更合理的做法是每个项目创建独立的虚拟环境然后在 Jupyter 中注册这个环境的内核。创建并注册内核的参考流程# 创建虚拟环境 python -m venv myproject_env # 激活环境 source myproject_env/bin/activate # 安装 ipykernel pip install ipykernel # 注册为 Jupyter 内核 python -m ipykernel install --user --name myproject_env --display-name Python (myproject_env)之后在 Jupyter Notebook 新建文件时Kernel 菜单里就能看到Python (myproject_env)这个选项。切换到对应内核后Notebook 中运行代码使用的就是该环境下的依赖包。6.2 配置文件的常用设置jupyter_notebook_config.py是 Jupyter 的核心配置文件。除了可以指定浏览器还有几个建议关注的配置项c.ServerApp.port修改默认端口。默认端口 8888 经常会被占用改成其他端口可以减少冲突。c.NotebookApp.notebook_dir设置 Notebook 默认工作目录。比如设置为D:/workspace/notebooks启动后就直接定位到这个目录避免每次都要切换路径。c.ServerApp.password设置访问密码。如果打算在局域网内的其他电脑上访问 Notebook这一步非常有必要。c.ServerApp.allow_remote_access开启远程访问。局域网使用场景下需要配合防火墙安全策略使用。这些配置项的详细位置可以在配置文件中用搜索找到。修改后需要重启 Notebook 才能生效。6.3 安全边界与生产环境注意事项Jupyter Notebook 的默认设计是单机本地使用它启动时不带加密身份验证。因此有一个重要提醒不要在不设密码的情况下把 Jupyter Notebook 绑定到0.0.0.0对外网提供服务。一旦暴露到公网就等于把服务器上的 Python 执行权限开放给了任何人风险非常高。如果确实需要远程访问建议优先选择如下方式通过 SSH 隧道进行端口转发不直接对外开放 8888 端口配置强密码和 HTTPS 证书采用 JupyterHub 等具备多用户认证功能的部署方案遵循最小权限原则使用独立低权限用户运行 Notebook 服务。涉及生产环境、数据库或敏感数据时不要在 Notbook 代码中直接硬编码数据库密码、API Key 等凭据。推荐使用环境变量或本地密钥管理工具读取。同时执行删除类操作前必须确认数据已备份并且操作对象是测试环境或经过授权批准的正式环境。6.4 使用 Notebook 的组织与版本管理Notebook 虽然方便但.ipynb文件本质上是 JSON 格式如果直接在 Git 等版本控制工具中提交会面临 diff 不直观的问题代码改动很难一行行审查。对于团队协作项目以下几点建议值得参考把 Notebook 当作“探索和报告工具”把可复用的业务逻辑尽量抽取成.py模块通过import引入保证核心代码可以单测、可以复用。使用jupytext等工具把 Notebook 同步为.py脚本实现更好的版本对比体验。在提交之前执行 Kernel → Restart Run All确保 Notebook 从头到尾可以完整运行减少“在我电脑上能跑”的问题。定义好 Notebook 的编号命名规范比如01_data_explore.ipynb、02_feature_engineering.ipynb避免文件名毫无规律。6.5 性能优化建议Notebook 运行较慢时不一定要直接升级机器先检查几个常见问题是否在循环中频繁调用print导致输出区被大量文本拖慢。是否重复运行了具有耗时操作的代码而没有使用变量缓存。是否对整个 DataFrame 做了高成本操作比如多次遍历、过多apply复杂函数。是否读取了超大文件但没有做分块处理。对数据分析任务建议先用.sample()抽样数据验证思路确认流程没有问题后再跑全量数据这个习惯能节省大量时间。另外不要频繁重启 Kernel因为变量会被清空全部代码需要重新执行更合理的做法是尽量把耗时步骤的结果保存为中间文件避免每次重启后从头计算。7. 总结与下一步学习建议到这里你已经完成了 Jupyter Notebook 从安装到实际使用的完整闭环。回顾一下本文帮助你理解了 Jupyter Notebook 的基本概念和组织形式区分了 Jupyter Notebook 与 JupyterLab 的不同定位介绍了 Anaconda 与 pip 两种安装方式掌握了 Cell、Kernel、Output 三个核心概念和常用快捷键并通过一个完整的 Python 数据分析与可视化案例体验了从数据读取、分组聚合到绘图输出的全过程。与此同时我们也梳理了 Jupyter Notebook 常见的问题类型比如打开空白页面、内连失败、包安装缓慢等这些都是在学习过程中高频出现的坑点。最后围绕虚拟环境、配置文件、安全边界、代码组织和性能优化给出了一些工程层面的建议。这些内容虽然短期内不会全部用到但会在你真正开始做项目时帮助你少走很多弯路。接下来你可以继续学习的路线可以这样安排如果你刚入门 Python建议先掌握 pandas 的常用操作比如groupby、merge、pivot_table这些都是数据分析的高频方法。如果你对可视化有兴趣可以学习 Seaborn 和 PlotlySeaborn 在统计图表上更简洁美观Plotly 则支持交互式图表。如果你想进入机器学习方向可以熟悉 scikit-learn 的基本建模流程配合 Notebook 做特征工程和模型对比非常方便。如果你想解决“在 VS Code 中使用 Jupyter 而不是浏览器”的问题可以学习 VS Code 的 Jupyter 扩展它可以在编辑器内运行 Notebook调试体验更接近传统 IDE。Jupyter Notebook 是工具数据分析能力才是核心。多找几个真实数据集无论是 Kaggle 上的公开数据、学校实验数据还是业务脱敏数据用它完成几次完整的“读数据、清洗数据、分析数据、输出图表”流程你对 Notebook 的理解会迅速超越教程本身。如果本文对你有帮助可以点赞收藏后续遇到 Jupyter 相关问题也可以回来翻一翻。动手打开命令提示符新建一个 Notebook 试一试吧。
返回列表