45

I have converted a Jupyter/IPython notebook to HTML format and subsequently lost the original ipynb file.

Is there a simple way to generate the original notebook file from the converted HTML file?

4
  • Is copying the code from the html file into a new notebook not an option for you? I guess this is a rather unusual problem and I doubt that there is an easy way to do that. Commented Mar 10, 2015 at 20:26
  • 6
    @cel, yes, that is an option, just not terribly practical for large notebooks. But since the ipynb JSON file and the converted HTML have more or less the same info, I was wondering if there might be a converter available. Commented Mar 10, 2015 at 20:41
  • I don't believe there's a pre-canned converter available. Commented Mar 12, 2015 at 19:17
  • 1
    Yes, I also want to find a tool to do the conversation from html to ipynb. But no result yet. Commented Mar 14, 2017 at 5:38

3 Answers 3

54

I recently used BeautifulSoup and JSON to convert html notebook to ipynb. the trick is to look at the JSON schema of a notebook and emulate that. The code selects only input code cells and markdown cells

here is my code

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))

here is part of print(soup.div) output

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>

A screen shot of the resulting ipynb file, loaded on my local jupyter and after running all the cells

enter image description here

Sign up to request clarification or add additional context in comments.

9 Comments

That's great. Thanks for sharing.
Works like a charm! I just had to install lxml (pip install lxml) and ipynb created!
❤️extra basic how-to steps 1. create a new file intonotebook.py Open it code editor (not in Word) 2. copy-paste the first block of code from this answer. 3. Change the top line 4 to your file the web. but if file's on your computer, put # in front of lines 4 and 5, and remove # before line 7. Then change line 7 to where your html file is (# means a 'comment'). make sure there are no spaces at the beginning of lines you edited. save the file. 4. open terminal, go to the folder your created the file and type python intonotebook.py. 5. To change name of output file, change last line
Is it possible to keep the cell's output in the converted .ipynb file?
It seems mostly the new tags are what people are getting and so I have updated my version of the code to feature the new tags and referenced code to be used if you have the old tags.
|
3

Note the best answer may need some modification of the tags for it to work in late 2022 and forward

I'm adding this as an answer to highlight comments I made below the nice upvoted Answer.
Note that the current version of the awesome highly upvoted one won't probably work as the HTML tags signaling the various cells has changed. If you happen to have a really old version of HTML made, it may work. However, most of you will have have newer made HTML and you need the new tags to be in the code to distinguish the cells.

See my comments below that highly-voted on post (you'll need to click on 'Show more comments' option at the bottom to reveal all the comments) for a link to a place here to get an active Jupyter session where you can run the code demo right in your browser, without needing to sign in, via MyBinder service with the updated version of the code with the current tags used. See the fist code cell here for a direct source of a static representation of the code. (You don't want the cell magic line that begins %%writefile, just copy everything in that cell below that line.) The tags being different affects a few lines of the original code.

5 Comments

When i tried to run the code from the blog you linked in your answer I got this error. json.dumps(dictionary)) ^ SyntaxError: unmatched ')'
ok. I did something wrong at first, but now I went to the right place and when I go to cell 7 and replace "seaborn_demo.html" with my filename that I want to convert to ipynb I get FileNotFoundError. The same thing happens when I try to replace "seaborn_demo.html" with the file path. I don't know if that is the only thing I'm supposed to do or if there are more steps.
Are you running it via the launch badge I specify? If so, then you need to get your content on the remote machine where the session is running. Perhaps that isn't clear in the demo as written? The easiest way would be to open the seaborn_demo.html in the file browser and replace the content with yours. Or if you want to use your file as-is, you'd need to upload it to the remote session by clicking it & dragging it from your local machine to the file browser pane on the left side in the browser window and releasing your mouse. Then change the file name in the code to your file name.
thank you I replaced the seaborn file with mine and it worked
Thanks for trying it. I updated the demonstration notebook to try to make it clearer how you'd substitute in your own HTML content.
-3

Here's a trick: Save the html file as a .txt file and then open it in your code editor. Then rename the file extension as .ipynb That should do the trick.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.