Get Kindle Library Book List

时光毁灭记忆、已成空白 提交于 2020-11-30 02:25:24

问题


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. Thanks in advance for anyone who has any suggestions.


回答1:


I've created a Gist of a javascript function which will take export a full list of all books using https://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:

https://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.




回答2:


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!




回答3:


You're looking for the Amazon Product Advertising API.

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




回答4:


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.




回答5:


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.




回答6:


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.




回答7:


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.



来源:https://stackoverflow.com/questions/7191429/get-kindle-library-book-list

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!