Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Amazon Kindle Export
// The following data should be run in the console while viewing the page https://read.amazon.com/
// It will export a CSV file called "download" which can (and should) be renamed with a .csv extension
var db = openDatabase('K4W', '3', 'thedatabase', 1024 * 1024);
getAmazonCsv = function() {
// Set header for CSV export line - change this if you change the fields used
var csvData = "ASIN,Title,Authors,PurchaseDate\n";
db.transaction(function(tx) {
tx.executeSql('SELECT * FROM bookdata;', [], function(tx, results) {
var len = results.rows.length;
for (i = 1; i < len; i++) {
// Get the data
var asin = results.rows.item(i).asin;
var title = results.rows.item(i).title;
var authors = JSON.parse(results.rows.item(i).authors);
var purchaseDate = new Date(results.rows.item(i).purchaseDate).toLocaleDateString();
// Remove double quotes from titles to not interfere with CSV double-quotes
title = title.replace(/"/g, '');
// Concatenate the authors list - uncomment the next line to get all authors separated by ";"
// var authorList = authors.join(';');
// OR Take only first author - comment the next line if you uncommented the previous one
var authorList = authors[0];
// Write out the CSV line
csvData += '"' + asin + '","' + title + '","' + authorList + '","' + purchaseDate + '"\n'
}
// "Export" the data
window.location = 'data:text/csv;charset=utf8,' + encodeURIComponent(csvData);
console.log("Sample Row:");
console.log(results.rows.item(1));
});
});
};
getAmazonCsv();
@ravivyas84
Copy link

ravivyas84 commented May 10, 2019

Provides the following errors now:
VM37:1 Uncaught DOMException: Failed to execute 'openDatabase' on 'Window': unable to open database, version mismatch, '2' does not match the currentVersion of '3'
at :1:10

Change

var db = openDatabase('K4W', '2', 'thedatabase', 1024 * 1024);

to

var db = openDatabase('K4W', '3', 'thedatabase', 1024 * 1024);

and it works

@Soderborg-Bonnie
Copy link

Soderborg-Bonnie commented May 17, 2019

Thank you! What a huge time saver!

@compwron
Copy link

compwron commented Dec 21, 2019

It still works, with the minor change of replacing var db = openDatabase('K4W', '2', 'thedatabase', 1024 * 1024); '2' with '3' :)
Thank you so much :)

@ianmack-byte
Copy link

ianmack-byte commented Jan 11, 2020

Great Script, been looking for something like this for ages

@meddulla
Copy link

meddulla commented Mar 8, 2020

Chrome only (does not work in firefox). Awesome, thanks :)

@monahancj
Copy link

monahancj commented May 25, 2020

This worked great! Thanks for sharing it.

I did get an error on the db version, but I changed openDatabase parameter from 2 to 3 and was fine.

VM73:1 unable to open database, version mismatch, '2' does not match the currentVersion of '3'
(anonymous) @ VM73:1
VM73:1 Uncaught DOMException: Failed to execute 'openDatabase' on 'Window': unable to open database, version mismatch, '2' does not match the currentVersion of '3'
at :1:10

@jkubecki
Copy link
Author

jkubecki commented Jun 9, 2020

All, thanks for the feedback! @ravivyas84, @compwron, and @monahancj - finally got around to updating my gist to use v3 of the database now, thanks for the quick fix!

@sserrato
Copy link

sserrato commented Aug 31, 2020

This is fantastic

@nexnovati
Copy link

nexnovati commented Sep 2, 2020

Chrome deprecated and removed Top-frame navigations to data URLs, so "window.location" doesn't work anymore in DevTools.
Following these suggestions: https://groups.google.com/a/chromium.org/g/blink-dev/c/GbVcuwg_QjM?pli=1
I replaced

window.location = 'data:text/csv;charset=utf8,' + encodeURIComponent(csvData);

with the following:

booklist = 'data:text/csv;charset=utf8,' + encodeURIComponent(csvData);
var win = window.open();
win.document.write('<iframe src="' + booklist + '" frameborder="0" style="border:0; top:0px; left:0px; bottom:0px; right:0px; width:100%; height:100%;" allowfullscreen></iframe>');

And it worked.

Thank you for your useful script!

@johnnew2019
Copy link

johnnew2019 commented Sep 20, 2020

I featured your excellent code in this Amazon Forum comment. Thanks very much for making it available.

@david-bakin
Copy link

david-bakin commented Nov 25, 2020

Hallelujah! I've been looking for this or something quite like this for literally (🡄 yes literally, not figuratively) years, thank you! Grabbed the all important database open and select transaction, added a console save utility and in about 2 minutes total time got my 1882 Kindle books in a sweet json file, ready to further process to dump into my book database.

(Amazon lets you download order reports with all your physical purchases - why they still don't allow you to download a report with all your digital purchases is beyond me. I send them an email about it every year but it is always ignored. Sad!)

Use with @nexnovati 's fix.

Thank you!

[P.S.: here's my version]

@tjluoma
Copy link

tjluoma commented Jan 26, 2021

With the change suggested by @nexnovati at https://gist.github.com/jkubecki/d61d3e953ed5c8379075b5ddd8a95f22#gistcomment-3439531 this worked fine for me today. 👍 Thank you!

@alexmac05
Copy link

alexmac05 commented Mar 18, 2021

amazing. thank you

@aprilbrown
Copy link

aprilbrown commented Apr 8, 2021

I've been looking for something like this for years. I was close to resorting to making my own javascript script to do it but now I don't have too. Thanks.

@anesone
Copy link

anesone commented Apr 19, 2021

I noticed this script dumped all but one of my books. I changed the code from:
for (i = 1; i < len; i++) {
to
for (i = 0; i < len; i++) {
and now they all show up.

Thanks for this fantastic script!

@RobertBernstein
Copy link

RobertBernstein commented May 9, 2021

Note that as of 8 May 2021, the database version is now 5 and must be changed in the gist to work:

var db = openDatabase('K4W', '5', 'thedatabase', 1024 * 1024);

@david-bakin
Copy link

david-bakin commented May 10, 2021

Note that as of 8 May 2021, the database version is now 5 and must be changed in the gist to work:

var db = openDatabase('K4W', '5', 'thedatabase', 1024 * 1024);

Works, thanks!

@RobertBernstein
Copy link

RobertBernstein commented May 10, 2021

Excellent!

@astrotau99
Copy link

astrotau99 commented May 18, 2021

Hi all..
I am a heavy user of kindle and I DESPERATELY need this function to create a quick and smart list of my >1000 books.
I am not easy with Console, JS, etc.
I tried to cut and paste the "Kubecki tool" but it doesn't work for me.
I executed the routine with Ctrl+Shift+J. Is it ok? Apparently the routine works and the console disappear.
I don't get any message but I don't get the output file neither ("download.csv"?); in which folder should I look?
If there are errors, how can I see the LOG? Is the NEXNOVATI change mandatory for EDGE?
I use Microsoft EDGE in a Windows 10 PRO, on a Surface GO PC.
Please help!

@matthewpoe
Copy link

matthewpoe commented Jun 25, 2021

This is so amazing and helpful -- I think they updated the read page, but I can still get this to run by changing the database version from 3 to 5 in line 4 -- however, it only exports data through mid-March of 2021 for me. Anyone else seeing this?? Anyone figured out a workaround to get the most recent rows of data? Thanks again for this fantastic tool!

@david-bakin
Copy link

david-bakin commented Jun 25, 2021

@matthewpoe
Copy link

matthewpoe commented Jun 26, 2021

Ah yeah, that must be it exactly -- I probably last successfully ran it in mid-Mar so that version is cached, while the current version of the read.kindle.com site uses a new database. Hmph! Well, this tool was so great/genius while it lasted!!

@Vladyak
Copy link

Vladyak commented Jun 27, 2021

Hi, great code and is working fine! Is it possible to extend number of fields such as ISBN and Lending?

@darryllee
Copy link

darryllee commented Aug 12, 2021

Hi all - I never ran this in the past, but after changing the database version to 5, I still only get <- undefined after copy/pasting the code.

So I'm not sure the database is there at all for me.

But after clicking Books (so I wouldn't get Samples) and poking around in Developer Tools, I did find this:
https://read.amazon.com/kindle-library/search?query=&libraryType=BOOKS&sortType=recency&resourceType=EBOOK&querySize=50

And as I scrolled through my list of books, I found links like this:
https://read.amazon.com/kindle-library/search?query=&libraryType=BOOKS&paginationToken=47&sortType=recency&resourceType=EBOOK&querySize=50

So basically these are JSON files with all of what used to be in the database. I took the slow brute-force approach of opening those links in separate tabs, and saving them as files. If you look at the end of each file, it will have a new paginationToken, incremented by 50, so, 97, 147, 197, 247, and so on. So I simply updated the paginationToken with the next token, loaded that page, and saved. The last page will not have a paginationToken. That's how you know you're done.

Once I got the JSON files (for me there were 14 files, containing 714 books). I named them books00.json, books01.json, and so on.

I then was able to use the excellent tool, jq (https://stedolan.github.io/jq/) to convert the JSON to a CSV. I used this command:

jq -r '.itemsList[]|([.title, .authors[0], .asin, .productUrl] | @csv)' books*.json > allbooks.csv

The JSON data does not have purchaseDate, but it does have percentageRead AND a link to a picture of the book cover, which I guess is... something. (Actually in Google Sheets you can use the IMAGE(URL) macro to display the covers, so that's kind of cool.)

Anywho, here's a sample record:

{
      "asin": "B002ACNYFY",
      "webReaderUrl": "https://read.amazon.com/?asin=B002ACNYFY",
      "productUrl": "https://m.media-amazon.com/images/I/51+7sA25W-L._SY300_.jpg",
      "title": "The Pains (Mind Over Matter)",
      "percentageRead": 0,
      "authors": [
        "Sundman, John Damien:Cheeseburger Brown:"
      ],
      "resourceType": "EBOOK",
      "originType": "PURCHASE"
    },

I suspect that somebody better versed in Javascript than me could write some code to automatically download each JSON file, and read the paginationToken from that, and then continue downloading the files until complete.

Actually somebody better versed in Javascript could probably download the JSON files, extract the data and export it directly to CSV.

But that's not me. :-}

Hope this helps somebody until Amazon breaks it again.

@usayamadx
Copy link

usayamadx commented Aug 14, 2021

@darryllee
Hi, can you run this code?
https://gist.github.com/usayamadx/9c638d9b70bc714d6dd6043fcd54085f

I was able to write this code by your good comment (^^)b

@johnnew2019
Copy link

johnnew2019 commented Aug 14, 2021

@usayamadx
Thanks for this. I ran the code. It retrieved the ASIN and title of 2150 of my 10,000 or so books. Then got this message: Uncaught RangeError: Maximum call stack size exceeded.

@heathkat
Copy link

heathkat commented Aug 17, 2021

@usayamadx the code you posted worked for me! Thank you! I got most of my books. I did get an error near the end of the list: VM1374:10 Uncaught RangeError: Maximum call stack size exceeded.
at getItemsList (:10:7)
at XMLHttpRequest.xhr.onreadystatechange (:31:11) ...

@darryllee
Copy link

darryllee commented Aug 19, 2021

Hey @usayamadx, 1) THIS IS AWESOME!, 2) Yes, I ran it. Found one bug, and had some feature request. I will comment on your gist directly.

@rgla
Copy link

rgla commented Apr 25, 2022

Hi,

doesn't work for me ... I get the following error-code for using it for my library:
VM143:4 unable to open database, version mismatch, '3' does not match the currentVersion of '5'
(anonymous) @ VM143:4
VM143:4 Uncaught DOMException: Failed to execute 'openDatabase' on 'Window': unable to open database, version mismatch, '3' does not match the currentVersion of '5'
at :4:10

Would be nice if you could find the time to have a look ...

Best regards
R.

@onimaru
Copy link

onimaru commented Aug 16, 2022

@darryllee Hi, can you run this code? https://gist.github.com/usayamadx/9c638d9b70bc714d6dd6043fcd54085f

I was able to write this code by your good comment (^^)b

This worked for me, thank you :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment