43

有谁知道以编程方式从用户的 Amazon Kindle 图书馆获取书籍列表的方法?我想建立一个借书服务。理想情况下,用户将能够导出他们愿意借出的书籍列表,而无需单独键入每一本书。我相信亚马逊可能为此提供了某种 API,但找不到任何文档。我或多或少对这个语言不可知论者。提前感谢任何有任何建议的人。

4

7 回答 7

16

我创建了一个 javascript 函数的要点,它将使用https://read.amazon.com导出所有书籍的完整列表。Amazon Kindle Reader 网络应用程序使用 Web SQL 在本地存储您的完整图书列表(无需“下载”它们),并且 gist 基本上将图书列表导出为 CSV 文件。我在 Gist 中评论了一些注释,因此您可以对其进行自定义以满足您的需求:

https://gist.github.com/jkubecki/d61d3e953ed5c8379075b5ddd8a95f22

这类似于@user2493694 建议做的事情,但使用底层数据而不是解析页面。

于 2016-10-10T13:01:37.130 回答
10

解决方案:用户可以选择将其 Kindle 安装为可移动驱动器,并进一步将其所有电子书文件拖放到页面上。然后我解析所有包含 ASIN 的文件名。使用 ASIN,我可以在亚马逊上搜索图书信息,包括它是否可以借出。

这不完全是我所希望的,但它工作得很好。如果有人提出更雄辩的解决方案,我会非常感兴趣!

于 2011-09-05T18:11:31.053 回答
6

您正在寻找亚马逊产品广告 API。

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

于 2011-08-25T13:46:05.957 回答
6

几周前我在为我的 Kindle 寻找 API 时看到了这篇文章。我意识到我正在挖掘一个相当古老的帖子,但是在看到user2493694 的答案后,我想我可以制作出她所描述的东西。

该项目仍在开发中,但截至目前,它是 Python 中的一个功能性 Kindle API。它主要关注用户当前的阅读位置(这是我最初对 Kindle API 感兴趣的主题),但它有可能提取所有公开可用的 Kindle 数据。

我已将它上传到https://github.com/msuozzo/Lector,非常感谢任何反馈或功能请求。

于 2015-08-18T22:37:29.980 回答
4

我不知道他们到底是怎么做到的——但是如果用户使用亚马逊账户登录,Shelfari 将根据购买历史导入用户的 Kindle 书籍(我想我在某处看到亚马逊部分拥有 Shelfari 或者他们以某种方式附属)。无论如何,Shelfari 界面——它基本上是一个面向读者的社交网络,还能够使用您的虚拟书架创建 CSV。该文件基本上是一个简单的电子表格,其中包含书籍的识别数据。我之前用过这个流程来转移我的Kindle图书馆目录,因为一个一个做起来太麻烦了。CSV 文件通常可由其他站点导入或由 excel 读取,以便您可以在更大的组中复制和粘贴数据。

于 2014-02-02T07:12:45.403 回答
3

我一直在考虑解析 Kindle Cloud Reader ( https://read.amazon.com ) 的内容页面,以获取我的 Kindle 图书馆中的书籍列表。

于 2013-06-17T14:01:27.860 回答
1

正如user2493694所建议的,FireFox 有一个内置的 Inspector 工具,可用于从 Amazon 云阅读器库页面中提取完整的图书列表:

  • 转到https://read.amazon.com/并显示图书馆页面
  • 在 Tools > Web Developer (Ctrl+Shift+C) 下调用 Inspector 工具
  • 选择实际列表部分 ( div #titles_inner_wrapper),它是所有书籍条目的直接父级
  • 在 Inspector 仪表板的 HTML 窗格中,复制所选部件的 HTML

选择列表部分最容易通过激活元素选择器(Ctrl+Shift+C 或 Inspector 仪表板中最左侧的图标),将鼠标悬停在左上角的书本图标上,然后缓慢向上或向左移动直到选择扩展到列表的整个内部(此时选择标题将显示div #titles_inner_wrapper)。此时左键单击会在 Inspector 仪表板的 HTML 窗格中选择相应的节点,以便 Ctrl+C 将 HTML 复制到剪贴板。这与节点右键菜单中的 Copy > Outer HTML 相同。

这将完整的图书列表作为 HTML 片段提供,具有易于解析的结构,包括 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>

这个手动过程只需要少量的鼠标点击和击键。

以编程方式下载列表比发出 HTTP GET 和分析结果要复杂一些,因为云阅读器需要身份验证并使用大量 JavaScript。这是一些使用 .NET WebBrowser控件下载+保存列表的概念验证代码。该代码可以编译为 .cs 文件,但也可以粘贴到 LINQPad 中并按原样运行(请参阅#ifdefs)。它在表单上使用可见的浏览器控件,因为可能需要登录到云阅读器。

您应该在运行此脚本之前查看/修改文件名模板。

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

DocumentCompleted这个小脚本加载云阅读器并在事件触发时(即当浏览器认为它已完成加载时)找到图书列表时保存它。列表保存代码可以通过^S热键(又名 Ctrl+S)手动调用,以防DocumentCompleted事件在 JavaScript 实际加载图书列表之前触发。

注意:基于事件的自动保存可能会导致列表不完整,因此最好在尘埃落定后始终手动保存。或者在事件中设置一个大的计时器,DocumentCompleted以便只有在尘埃落定后才尝试自动保存,并且只有在结果证明几秒钟内稳定后才进行实际保存。我已经在 PasteBin发布了执行此操作的代码版本。

于 2020-09-16T09:53:12.890 回答