Get Kindle Library Book List
Asked Answered
W

6

49

Does anyone know of a way to programmaticly get a list of books from a user's Amazon Kindle Library? I would like to build a service for lending books. Ideally users would be able to export a list of books they are willing to lend without having to type each one individually. I believe Amazon may have some sort of API for this but have been unable to find any documentation. I am more or less language agnostic on this one.

Whitmire answered 25/8, 2011 at 13:42 Comment(3)
You mean like lendle.me ?Hazelhazelnut
Sort of... but not exactly. I am building a private service. No money is involved. Just friends lending to friends. However the biggest part is not having the user to tell the service which books they own. I want the user to just login and the service will scan their Amazon Library automatically. Lendle forces the user to add each book one by one (probably b/c what I am trying to do is not available).Whitmire
I've created a Gist of a javascript function which will take export a full list of all books using read.amazon.com. The Amazon Kindle Reader web app uses Web SQL to store the full list of your books locally (no need to "download" them), and the gist basically exports the list of books to a CSV file. I've commented some notes in the Gist, so you can customize it to fit your needs: gist.github.com/jkubecki/d61d3e953ed5c8379075b5ddd8a95f22 This is similar to what @user2493694 was proposing to do, but using the underlying data instead of parsing the page.Wiersma
W
10

Solution: The user is given an option to mount their kindle as a removable drive, and further to drag/drop all of their ebook files onto the page. I then parse all the file names which contain the ASIN. Using the ASIN, I can search Amazon for the book information including if it is lendable or not.

This is not exactly what I was hoping for, but it works good enough. If someone comes up with a more eloquent solution, I would be very interested!

Whitmire answered 5/9, 2011 at 18:11 Comment(2)
Nice! Why didn't I think of that :DHazelhazelnut
not sure if this is possible but would think that you can lookup your orders and look for what device the item was delivered too. That could also be another option.Neidaneidhardt
H
7

You're looking for the Amazon Product Advertising API.

https://affiliate-program.amazon.com/gp/advertising/api/detail/main.html

Hazelhazelnut answered 25/8, 2011 at 13:46 Comment(2)
Thanks, @Chris. I saw this site but was not able to find anything specifically for listing a user's private content (Maybe I overlooked it?). I thought about having the user create a public wish list and have them populate it with the content they own. I could then scan the public list but I would like to require the user to do as little as possible.Whitmire
Ah, I see. Right, Amazon only allows you to search their library of kindle books. It cannot reveal what books users have purchased. However, it is the Product Advertising API that lets you at least search for a book so you can do features like autocomplete, etc to make it easy for the user to add their books.Hazelhazelnut
N
6

I saw this post a few weeks ago while looking for an API for my Kindle. I realize I'm digging up a pretty old post but, after seeing the answer from user2493694, I figured I could cook up something like what she described.

The project is still in development but, as of now, is a functional Kindle API in Python. Its primary focus is on the user's current reading position (this was the subject of my original interest in a Kindle API) but it has the potential to extract all publicly available Kindle data.

I've uploaded it at https://github.com/msuozzo/Lector and would greatly appreciate any feedback or feature requests.

Nephelinite answered 18/8, 2015 at 22:37 Comment(0)
T
5

I've been considering parsing the content page of the Kindle Cloud Reader (https://read.amazon.com) in order to obtain a list of the books in my kindle library.

Ticket answered 17/6, 2013 at 14:1 Comment(1)
Thanks, the idea of using the Kindle cloud reader is brilliant! I've posted detailed steps for ripping the list manually with FireFox as well as some C# code for ripping the list programmatically (which can also be used directly as a LINQPad script).Liverpool
C
4

I don't know how they do it exactly - but Shelfari will import a user's Kindle books based on purchase history if they login with their Amazon account (I think I've seen somewhere that Amazon partially owns Shelfari or they are somehow affiliated). Anyway the Shelfari interface - which is basically a social network for readers also has the capability to create a CSV with your virtual shelves. That file is basically a simple spreadsheet with the identifying data for the books. I have used this process for transferring my Kindle library catalog before because it is too cumbersome to do one by one. The CSV file is usually importable by other sites or readable by excel so that you can copy and paste the data in larger groups.

Carryingon answered 2/2, 2014 at 7:12 Comment(0)
L
2

FireFox has a builtin Inspector tool that can be used to rip the complete book list from the Amazon cloud reader Library page, as suggested by user2493694:

  • go to https://read.amazon.com/ and display the Library page
  • call up the Inspector tool under Tools > Web Developer (Ctrl+Shift+C)
  • select the actual list part (div #titles_inner_wrapper), which is the immediate parent of all the book entries
  • in the HTML pane of the Inspector dashboard, copy the HTML for the selected part

Selecting the list part is most easily done by activating the element picker (Ctrl+Shift+C or left-most icon in the Inspector dashboard), hovering the mouse over the top left book icon and then moving it slowly up or left until the selection expands to the whole inner part of the list (at which point the selection caption will say div #titles_inner_wrapper). A left-click at this point selects the corresponding node in the HTML pane of the Inspector dashboard so that Ctrl+C will copy the HTML to the clipboard. This is the same as Copy > Outer HTML in the right-click menu for the node.

This gives the full book list as an HTML fragment with an easily parsed structure, including ASIN:

<div id="titles_inner_wrapper" style="font-size: 191.25px;">
    <div id="B00DJI3HWS" class="book_container">
        <div class="book_cover">
            <img class="book_image book_click_area" src="https://images-na.ssl-images-amazon.com/images/P/B00DJI3HWS.01._SX255_SY255_TTXW_SCLZZZZZZZ_.jpg" title="I Bastardi di Pizzofalcone (Italian Edition)">
            <div class="alt_title book_click_area"></div>
        </div>
        <div class="book_details">
            <div class="book_title book_click_area">I Bastardi di Pizzofalcone (Italian Edition)</div>
            <div class="book_author book_click_area">Maurizio de Giovanni</div>
        </div>
    </div>
    ...
</div>

This manual procedure takes just a small handful of mouse clicks and key strokes.

Downloading the list programmatically is a little more involved than issuing an HTTP GET and dissecting the result, since the cloud reader requires authentication and uses a lot of JavaScript. Here's some proof-of-concept code for downloading + saving the list using the .NET WebBrowser control. The code can be compiled as a .cs file but it can also be pasted into LINQPad and run as is (see #ifdefs). It uses a visible browser control on a form because it may be necessary to log in to the cloud reader.

You should review/modify the filename template before running this script.

class KindleBookListProgram
{
    const string FILENAME_TEMPLATE = "x:\\kindle_library_{0:yyyyMMdd}.lst";  // gets DateTime.Now as parameter
    const string READ_AMAZON_COM = "https://read.amazon.com/";
    const string USERAGENT = "Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko";
    const int URLMON_OPTION_USERAGENT = 0x10000001;

    static void Main ()
    {
        // setting the user agent in the Navigate() call works only once;
        // this works for the whole session
        UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, USERAGENT, USERAGENT.Length, 0);
    
        using (var form = new BrowserForm())
        {
            form.ShowDialog();
        }
    }

    [DllImport("urlmon.dll", CharSet = CharSet.Ansi)]
    private static extern int UrlMkSetSessionOption (
        int dwOption, string pBuffer, int dwBufferLength, int dwReserved );
    
    class BrowserForm: Form
    {
        WebBrowser m_browser;
    
        public BrowserForm ()
        {   
            Width = 800;
            Height = 600;
    
            m_browser = new WebBrowser();
            m_browser.DocumentCompleted += handle_browser_DocumentCompleted;
            m_browser.Dock = DockStyle.Fill;
            Controls.Add(m_browser);
    
            KeyPreview = true;
            KeyDown += handle_KeyDown;
    
            m_browser.Navigate(READ_AMAZON_COM);
        }

        void find_and_save_book_list_frame (WebBrowser browser)
        {
            foreach (HtmlWindow frame in browser.Document.Window.Frames)
            {
                var elt = frame.Document.GetElementById("titles_inner_wrapper");
            
                if (elt != null)
                {
                    var text = elt.InnerHtml;

                    if (string.IsNullOrEmpty(text))
                    {
                        this.Text = "Book list is empty!";
#if LINQPAD
                        Console.WriteLine("{0} book list empty!\n", DateTime.Now);
#endif
                    }
                    else
                    {
                        var filename = string.Format(FILENAME_TEMPLATE, DateTime.Now);
#if LINQPAD
                        Console.WriteLine("##### {0} ######\n\n{1}\n\n", filename, text);
#endif
                        File.WriteAllText(filename, text, Encoding.UTF8);

                        this.Text = filename + " saved!";
                    }
                }
            }
        }

        void handle_browser_DocumentCompleted (object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            find_and_save_book_list_frame(sender as WebBrowser);
        }

        void handle_KeyDown (object sender, KeyEventArgs e)
        {
            if (e.Control && e.KeyValue == 17)  // ^S
            {
                e.SuppressKeyPress = true;
                find_and_save_book_list_frame(m_browser);
            }   
        }
    }
}

This little script loads the cloud reader and saves the book list if it finds it when the DocumentCompleted event fires (i.e. when the browser thinks it is done loading). The list save code can be invoked manually via the ^S hotkey (a.k.a. Ctrl+S), in case the DocumentCompleted event fires before the book list is actually loaded by the JavaScript.

Note: the automatic event-based saving is likely to result in incomplete lists, so it is better to always save manually once the dust has settled. Or set a generous timer in the DocumentCompleted event so that automatic saving is only tried after the dust has settled somewhat, and do the actual saving only if the result has proved stable for several seconds. I've posted a version of the code that does this at PasteBin.

Liverpool answered 16/9, 2020 at 9:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.