我如何使用 Goodreads API 来选择下一本阅读书籍欢迎选择一本书👋

2025-06-07

我如何使用 Goodreads API 来选择下一本阅读书籍

欢迎选择一本书 👋

介绍

我喜欢读书,而且非常喜欢。而且(令人惊讶的是)我还喜欢编程。所以不久前,当我萌生了将这两个兴趣结合起来的想法时,我查阅了Goodreads API 文档,看看能找到哪些类型的数据。在仔细阅读了文档之后(也就是说,由于文档界面不太友好,我不停地敲着 Command + F 键来查找),我决定编写一个小程序,帮我挑选下一本要读的书。

入门

由于我已经选择了要使用的语言,所以我直接在桌面上创建了项目目录并使用 Git 对其进行了初始化。

如果你将本文作为教程,并且之前从未使用过 JavaScript,则应该下载Node.js并获取一个包管理器。我目前使用 npm。

我还从文档中了解到,我需要获取一个 API 密钥。作为 Goodreads 用户,我只需登录即可获取。我相信非 Goodreads 用户需要创建一个帐户才能访问。

开始谈正事

为此,我需要的只是一个待读书架上的书籍列表。在前面提到的“command + f”之后,我找到了一个 GET 请求,用于“获取会员书架上的书籍” ,这让我想到使用request promise包,除了之前的经验之外,没有任何理由

此时,我还决定安装dotenv,以便我可以传递我的 API 密钥和其他我不想硬编码的信息。

我按照以下格式设置了我的 .env 文件:

KEY=YOUR_GOODREADS_KEY
SECRET=YOUR_GOODREADS_SECRET
USER_ID=YOUR_GOODREADS_ID
VERSION=2
PER_PAGE=200
SHELF=to-read

然后我创建了 main.js 文件。我的第一个目标是输出 Goodreads 请求返回的内容。令我惊讶的是,我的终端里竟然有一大段 XML 文件。

劳伦·康拉德发出“哇哦!”的动图

劳伦·康拉德说:“哇哦。” via GIPHY

该文档的优点之一是,如果您已登录并拥有 API 密钥,当您单击要发出的请求的示例 URL 时,它将显示 API 返回的内容。

var request = require('request-promise');

require('dotenv').config();

let options = {
    method: 'GET',
    uri: `https://www.goodreads.com/review/list/${process.env.USER_ID}.xml`,
    qs: {
        key: process.env.KEY,
        v: process.env.VERSION,
        shelf: process.env.SHELF,
        per_page: process.env.PER_PAGE
    }
}

request(options).then((shelf) => {
    console.log(shelf);
}).catch(err => console.error(err));

尽管我已经看过示例 URL 及其返回的内容,但看到终端中的 XML 时我仍然感到惊讶,因此我快速浏览了 Goodreads 开发者论坛,看看是否有 JSON 端点。

剧透警告:没有。

《欢乐满屋》的 DJ 夸张地叹了口气

《欢乐满屋》 (Full House) 的 DJ 夸张地叹了口气。via GIPHY

经过一些快速搜索后,我决定安装xml2js,以便我能够将响应转换为更易于管理和可读的格式。

我喜欢逐步地工作,因此在需要新的包之后var xml2js = require('xml2js');,我修改了我的.then()块以解析响应并注销了最终结果。

request(options).then((shelf) => {
    xml2js.parseString(shelf, function (err, result) {
        console.log(result);
    });
}).catch(err => console.error(err));

现在我已经有了一些不错的 JavaScript 对象操作,剩下的只是弄清楚如何访问数组和对象中的标题。

我的第一步是获取书籍列表:

let books = result['GoodreadsResponse']['reviews'][0]['review'];

书籍存储在一个数组中,这意味着随机选择一个索引值只是从 0 到数组中的最后一个索引中选择一个数字。

let index = Math.floor(Math.random() * books.length);

通常,我喜欢在遍历密集对象和数组时设置中间变量,但由于我唯一需要的是标题,而且我不会再进行任何其他操作,所以我想我会跳过中间变量并将其全部放入标题的分配中。

let title = books[index]['book'][0]['title'][0];

此时,唯一要做的就是打印出标题并运行应用程序!

var request = require('request-promise');
var xml2js = require('xml2js');

require('dotenv').config();

let options = {
    method: 'GET',
    uri: `https://www.goodreads.com/review/list/${process.env.USER_ID}.xml`,
    qs: {
        key: process.env.KEY,
        v: process.env.VERSION,
        shelf: process.env.SHELF,
        per_page: process.env.PER_PAGE
    }
}

request(options).then((shelf) => {
    xml2js.parseString(shelf, function (err, result) {
        let books = result['GoodreadsResponse']['reviews'][0]['review'];
        let index = Math.floor(Math.random() * books.length);
        let title = books[index]['book'][0]['title'][0];
        console.log(title);
    });

}).catch(err => console.error(err));

后续步骤

虽然我并不认为自己是个设计师,也不擅长创作视觉效果惊艳的作品,但我认为下一步我会做一个能显示更多信息的 UI,比如封面、作者和评分,然后部署到 Heroku。我甚至可能会做一个有趣的功能,让用户输入他们的 Goodreads 用户 ID,让它从他们的待读书架中随机选择一本书。

最后的想法

我一直觉得在工作之余做些副业很困难,因为我总找不到一个自己喜欢到足以投入时间去做的点子,因为我本来可以利用空闲时间读书或做其他喜欢的事情。但我觉得这是一个有趣的方式,能把两件我喜欢的事情结合成一个我可能真正用得上的项目。

文章来源:https://dev.to/tara/how-i-used-the-goodreads-api-to-pick-my-next-read-2le9
PREV
现代工程团队如何利用 Entelligence AI 获得清晰度
NEXT
🤓 十大 JavaScript 代码简洁技巧