【问题标题】:Get Kindle Library Book List获取 Kindle 图书馆书单
【发布时间】:2011-11-03 17:18:16
【问题描述】:

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

【问题讨论】:

  • 你的意思是像lendle.me
  • 有点……但不完全是。我正在建立一个私人服务。不涉及金钱。只是朋友借给朋友。然而,最大的部分是没有让用户告诉服务他们拥有哪些书籍。我希望用户只需登录,该服务就会自动扫描他们的亚马逊图书馆。 Lendle 强制用户一一添加每本书(可能 b/c 我正在尝试做的事情不可用)。

标签: api amazon kindle


【解决方案1】:

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

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

这与@user2493694 提议的做法类似,但使用底层数据而不是解析页面。

【讨论】:

  • 这是一个很好的解决方案,截至 2020 年 11 月 24 日有效。
  • 这是迄今为止我见过的最好的解决方案。终于设法使用这种导出方法将我的阅读导入到 goodreads.com。
  • 请注意,截至 2021 年 5 月 8 日,数据库版本现在为 5,必须在 gist 中更改才能正常工作:var db = openDatabase('K4W', '5', 'thedatabase', 1024 * 1024);
【解决方案2】:

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

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

【讨论】:

  • 不错!为什么我没有想到:D
  • 不确定这是否可能,但您会认为您可以查找您的订单并查找该商品的交付设备。这也可能是另一种选择。
【解决方案3】:

【讨论】:

  • 谢谢,@Chris。我看到了这个网站,但找不到任何专门用于列出用户私人内容的内容(也许我忽略了它?)。我想过让用户创建一个公共愿望清单,并让他们用他们拥有的内容填充它。然后我可以扫描公共列表,但我想要求用户尽可能少做。
  • 啊,我明白了。对,亚马逊只允许你搜索他们的 Kindle 图书库。它无法透露用户购买了哪些书籍。但是,产品广告 API 至少可以让您搜索一本书,这样您就可以执行自动完成等功能,以便用户轻松添加他们的图书。
【解决方案4】:

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

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

我已将它上传到 https://github.com/msuozzo/Lector,如果有任何反馈或功能请求,我将不胜感激。

【讨论】:

    【解决方案5】:

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

    【讨论】:

      【解决方案6】:

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

      【讨论】:

      • 谢谢,使用 Kindle 云阅读器的想法太棒了!我已经发布了使用 FireFox 手动翻录列表的详细步骤以及一些用于以编程方式翻录列表的 C# 代码(也可以直接用作 LINQPad 脚本)。
      【解决方案7】:

      FireFox 有一个内置的 Inspector 工具,可用于从亚马逊云阅读器图书馆页面中提取完整的书单,正如 user2493694 所建议的那样:

      • 转到https://read.amazon.com/ 并显示图书馆页面
      • 在工具 > Web 开发人员 (Ctrl+Shift+C) 下调用检查器工具
      • 选择实际列表部分 (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)手动调用列表保存代码,以防在 JavaScript 实际加载图书列表之前触发 DocumentCompleted 事件。

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

      【讨论】:

        猜你喜欢
        • 2022-07-20
        • 2016-02-05
        • 1970-01-01
        • 2015-05-27
        • 1970-01-01
        • 2012-09-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多