This is an old topic, but considering the lack of other useful information out there it might be helpful to someone yet.
I just converted some notes from Keep to Evernote. The rough procedure was:
use Google Takeout to get a zipfile of all notes. You get a folder full of html files, one per note. The filenames roughly correspond to note titles, but they don't matter.
export some similar notes from Evernote desktop to get sample .enex files (evernote xml export)
write python code:
write an XML prologue
parse an HTML file, extracting note title, timestamp, tags, and content
emit a <note/> element representing the note in that html file
repeat for another file
write an XML epilogue
save this as a .enex file
import the enex into evernote desktop. This creates a new notebook which is not synced, but you can move the successful notes out.
The files from Keep are badly formatted HTML files. They declare themselves as XHTML but actually do not validate as XML, so using a real XML parser is difficult. It seems that they're generated by a line-by-line procedure though. In parsing the file, I could go line by line up to the content start marker, then read the rest of the file, strip out the content end marker and everything after, and process the content HTML into XML.
A few things about the conversion:
The <note> element you convert to has a <content> element whose value should be a CDATA.
The value of the CDATA must parse as an XML document too. This is the trickiest part, converting broken XHTML content to valid XML, but at least you don't need to escape anything.
An XML processor treats the CDATA as opaque binary content, so validating your final XML will not reveal parse issues in your content CDATA XML. You just need to get it right.
The CDATA should contain, in addition to an <xml... header, a doctype and an <en-note> element. You can see this in the samples you export from Evernote. Within the <en-note> you can pretty much just use HTML, as far as I can tell. However...
Keep will format todo lists as follows:
<div class="listitem checked"><div class="bullet">☑</div> [line break + list item content]
<div class="listitem"><div class="bullet">☐</div> [line break + list item content]
These should be converted to <en-todo checked="true|false"/>
. Note that this is a closed element followed by content. Content is not a child node of the element.
I had only 84 notes, and the procedure took enough fiddling that I'm not sure whether it would scale well to 1200. But in the end I had only one note that required a manual tweak to load.
My code is pretty bad — it's just a couple hours' quick hack — but I'll attach it in case it's a useful foundation for someone else.