Jupyter (IPython) 笔记本:将 HTML 笔记本转换为 ipynb

41

我已经将一个Jupyter/IPython笔记本转换为HTML格式,并且随后丢失了原始的ipynb文件。

是否有一种简单的方法可以从转换后的HTML文件生成原始的notebook文件呢?


将代码从HTML文件复制到新笔记本中不是您的选择吗?我猜这是一个相当不寻常的问题,我怀疑是否有简单的方法可以解决。 - cel
6
@cel,是的,那是一个选项,只是对于大型笔记本来说不是特别实用。但由于ipynb JSON文件和转换后的HTML基本上具有相同的信息,我想知道是否有可用的转换器。 - foglerit
我不相信有现成的转换器可用。 - Thomas K
1
是的,我也想找一个工具将HTML转换为IPYNB。但是目前还没有结果。 - Zhifei
3个回答

50

我最近使用了BeautifulSoup和JSON将HTML笔记本转换为ipynb格式。关键是要查看笔记本的JSON模式并模仿它。这段代码仅选择输入代码单元格和Markdown单元格。

这是我的代码:

from bs4 import BeautifulSoup
import json
import urllib.request
url = 'http://nbviewer.jupyter.org/url/jakevdp.github.com/downloads/notebooks/XKCD_plots.ipynb'
response = urllib.request.urlopen(url)
#  for local html file
# response = open("/Users/note/jupyter/notebook.html")
text = response.read()

soup = BeautifulSoup(text, 'lxml')
# see some of the html
print(soup.div)
dictionary = {'nbformat': 4, 'nbformat_minor': 1, 'cells': [], 'metadata': {}}
for d in soup.findAll("div"):
    if 'class' in d.attrs.keys():
        for clas in d.attrs["class"]:
            if clas in ["text_cell_render", "input_area"]:
                # code cell
                if clas == "input_area":
                    cell = {}
                    cell['metadata'] = {}
                    cell['outputs'] = []
                    cell['source'] = [d.get_text()]
                    cell['execution_count'] = None
                    cell['cell_type'] = 'code'
                    dictionary['cells'].append(cell)

                else:
                    cell = {}
                    cell['metadata'] = {}

                    cell['source'] = [d.decode_contents()]
                    cell['cell_type'] = 'markdown'
                    dictionary['cells'].append(cell)
open('notebook.ipynb', 'w').write(json.dumps(dictionary))

这里是print(soup.div)输出结果的一部分

div class="container">
<div class="navbar-header">
<button class="navbar-toggle collapsed" data-target=".navbar-collapse" data-toggle="collapse" type="button">
<span class="sr-only">Toggle navigation</span>
<i class="fa fa-bars"></i>
</button>
<a class="navbar-brand" href="/">
<img src="/static/img/nav_logo.svg?v=479cefe8d932fb14a67b93911b97d70f" width="159"/>
</a>
</div>
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav navbar-right">
<li>
<a class="active" href="http://jupyter.org">JUPYTER</a>
</li>
<li>
<a href="/faq" title="FAQ">
<span>FAQ</span>

加载所有单元格后,在我的本地Jupyter上打开的结果ipynb文件的屏幕截图

图片描述


5
太好了,谢谢分享。 - foglerit
4
运作得非常好!我只需要安装 lxmlpip install lxml),就创建出了 ipynb! - mdev
4
  1. 创建一个名为 intonotebook.py 的新文件,并在代码编辑器中打开它(不要在 Word 中)。
  2. 从这个答案中复制粘贴第一块代码。
  3. 将顶部的第4行改为你的文件网络位置。但如果文件在你的电脑上,就在第4和第5行前加上 #,并在第7行前删除 #。然后将第7行更改为你的HTML文件所在位置(# 表示“注释”)。确保你编辑的行开头没有空格。保存文件。
  4. 打开终端,进入你创建的文件所在的文件夹,输入 python intonotebook.py
  5. 要更改输出文件的名称,请更改最后一行。
- drpawelo
能否在转换后的 .ipynb 文件中保留单元格的输出? - THN
删除行 cell['outputs'] = [] 应该可以保留输出。 - sgDysregulation
显示剩余5条评论

2

请注意,最佳答案可能需要修改标签才能在2022年及以后的版本中正常工作

我将这个作为答案添加是为了强调我在受欢迎的回答下面发表的评论。
请注意,当前版本的受欢迎答案可能不起作用,因为HTML标记信号各个单元格的方式已经改变。如果你恰好有一个非常旧的HTML版本,它可能会起作用。然而,大多数人都会使用更新的HTML版本,并且需要在代码中使用新标记来区分单元格。

请查看我在高赞回答下面的评论(您需要点击底部的“显示更多评论”选项才能显示所有评论),其中包含一个链接,可以通过MyBinder服务在活动Juptyer会话中直接在浏览器中运行它,无需登录,使用当前标记的更新版本的代码。(请参见第一个代码单元here以获取直接源。标记的不同影响了原始代码的几行。


-2

这里有一个技巧: 将HTML文件保存为.txt文件,然后在您的代码编辑器中打开它。 然后将文件扩展名更改为.ipynb 这应该就可以了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接