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。