有谁知道以编程方式从用户的 Amazon Kindle 图书馆获取书籍列表的方法?我想建立一个借书服务。理想情况下,用户将能够导出他们愿意借出的书籍列表,而无需单独键入每一本书。我相信亚马逊可能为此提供了某种 API,但找不到任何文档。我或多或少对这个语言不可知论者。提前感谢任何有任何建议的人。
7 回答
我创建了一个 javascript 函数的要点,它将使用https://read.amazon.com导出所有书籍的完整列表。Amazon Kindle Reader 网络应用程序使用 Web SQL 在本地存储您的完整图书列表(无需“下载”它们),并且 gist 基本上将图书列表导出为 CSV 文件。我在 Gist 中评论了一些注释,因此您可以对其进行自定义以满足您的需求:
https://gist.github.com/jkubecki/d61d3e953ed5c8379075b5ddd8a95f22
这类似于@user2493694 建议做的事情,但使用底层数据而不是解析页面。
解决方案:用户可以选择将其 Kindle 安装为可移动驱动器,并进一步将其所有电子书文件拖放到页面上。然后我解析所有包含 ASIN 的文件名。使用 ASIN,我可以在亚马逊上搜索图书信息,包括它是否可以借出。
这不完全是我所希望的,但它工作得很好。如果有人提出更雄辩的解决方案,我会非常感兴趣!
您正在寻找亚马逊产品广告 API。
https://affiliate-program.amazon.com/gp/advertising/api/detail/main.html
几周前我在为我的 Kindle 寻找 API 时看到了这篇文章。我意识到我正在挖掘一个相当古老的帖子,但是在看到user2493694 的答案后,我想我可以制作出她所描述的东西。
该项目仍在开发中,但截至目前,它是 Python 中的一个功能性 Kindle API。它主要关注用户当前的阅读位置(这是我最初对 Kindle API 感兴趣的主题),但它有可能提取所有公开可用的 Kindle 数据。
我已将它上传到https://github.com/msuozzo/Lector,非常感谢任何反馈或功能请求。
我不知道他们到底是怎么做到的——但是如果用户使用亚马逊账户登录,Shelfari 将根据购买历史导入用户的 Kindle 书籍(我想我在某处看到亚马逊部分拥有 Shelfari 或者他们以某种方式附属)。无论如何,Shelfari 界面——它基本上是一个面向读者的社交网络,还能够使用您的虚拟书架创建 CSV。该文件基本上是一个简单的电子表格,其中包含书籍的识别数据。我之前用过这个流程来转移我的Kindle图书馆目录,因为一个一个做起来太麻烦了。CSV 文件通常可由其他站点导入或由 excel 读取,以便您可以在更大的组中复制和粘贴数据。
我一直在考虑解析 Kindle Cloud Reader ( https://read.amazon.com ) 的内容页面,以获取我的 Kindle 图书馆中的书籍列表。
正如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发布了执行此操作的代码版本。