Files
goodreads-book-search/Readme.md
2025-11-07 22:48:45 +03:00

15 KiB
Raw Blame History

📚 Unofficial Goodreads Book Search API

npm version License: MIT Node.js Version Build Status

🔍 A powerful Node.js library that enables you to retrieve comprehensive book information from Goodreads using only an ISBN number - no API key required!

This library intelligently analyzes Goodreads' HTML structure and returns detailed book information in a clean JSON format. Built with modern asynchronous JavaScript patterns and comprehensive error handling.


Key Features

  • 🔑 No API Key Required - Search Goodreads without authentication
  • 📖 Comprehensive Data - Extract detailed book information including:
    • 📕 Title & cover image
    • ✍️ Author details with profile links
    • 🌍 Translator information
    • 📝 Full book descriptions
    • 📄 Page count
    • Goodreads ratings
    • 🏷️ Genre classifications
    • 📅 Publication dates
  • 🚀 Modern JavaScript - Promise-based asynchronous operations
  • 🛡️ Error Resilient - Comprehensive error handling and validation
  • Performance Optimized - Configurable request delays and timeouts
  • 🧪 Well Tested - Complete test suite with Mocha and Chai
  • 📊 CI/CD Ready - Jenkins integration with automated testing
  • 🔧 Easy Configuration - Simple, intuitive API

🎯 Prerequisites

  • Node.js v14 or higher
  • NPM (usually comes with Node.js)
  • Internet connection (for Goodreads access)
  • Basic JavaScript knowledge (async/await patterns)

📦 Installation

# Install via npm
npm install szbk-goodreads-search-book

# Or using yarn
yarn add szbk-goodreads-search-book

🚀 Quick Start

Basic Usage

const GoodreadsBookSearch = require("szbk-goodreads-search-book");

async function searchBook() {
  try {
    const BookSearch = new GoodreadsBookSearch();
    const bookDetails = await BookSearch.getBookDetails("9944824453");

    console.log("📚 Book Found:", bookDetails);
  } catch (error) {
    console.error("❌ Error:", error.message);
  }
}

searchBook();

Example Output

{
  "title": "Dövmeli Adam",
  "thumbImage": "https://images.gr-assets.com/books/1348616986m/8631735.jpg",
  "authorName": {
    "author": {
      "name": "Peter V. Brett",
      "profileLink": "/author/show/306789.Peter_V_Brett"
    },
    "translators": ["Çevirmen Adı 1", "Çevirmen Adı 2"]
  },
  "description": "Kitap açıklaması burada yer alır. Kapsamlı kitap özeti...",
  "page": "640",
  "isbn": "9944824453",
  "date": "01 Sept 2008",
  "rate": "4.3",
  "genres": ["Fantasy", "Adventure", "Action"]
}

📖 Advanced Usage

Error Handling Best Practices

const GoodreadsBookSearch = require("szbk-goodreads-search-book");

async function robustBookSearch(isbn) {
  const BookSearch = new GoodreadsBookSearch();

  try {
    const bookDetails = await BookSearch.getBookDetails(isbn);

    // Validate the response
    if (!bookDetails.title) {
      throw new Error("Book title not found");
    }

    return bookDetails;

  } catch (error) {
    // Handle different error types
    if (error.message.includes("Detay bilgisi bulunamadı")) {
      console.log("📭 Book not found for ISBN:", isbn);
    } else if (error.message.includes("timeout")) {
      console.log("⏰ Request timeout. Please try again.");
    } else {
      console.log("❌ Unexpected error:", error.message);
    }

    return null;
  }
}

// Usage
robustBookSearch("9944824453").then(book => {
  if (book) {
    console.log("✅ Successfully retrieved:", book.title);
  }
});
async function searchMultipleBooks(isbnList) {
  const BookSearch = new GoodreadsBookSearch();
  const results = [];

  for (const isbn of isbnList) {
    try {
      console.log(`🔍 Searching for ISBN: ${isbn}`);
      const bookDetails = await BookSearch.getBookDetails(isbn);
      results.push({ isbn, success: true, data: bookDetails });
    } catch (error) {
      results.push({ isbn, success: false, error: error.message });
    }

    // Add delay between requests to be respectful
    await new Promise(resolve => setTimeout(resolve, 3000));
  }

  return results;
}

// Example usage
const isbnList = ["9944824453", "863173540X", "9780547928227"];
searchMultipleBooks(isbnList).then(results => {
  console.log("📊 Search Results:", results);
});

🏗️ Architecture & Project Structure

szbk-goodreads-search-book/
├── 📁 lib/                    # Core library files
│   ├── 📄 index.js           # Main GoodreadsBookSearch class
│   └── 📄 module.js          # Data extraction and parsing logic
├── 📁 config/                # Configuration files
│   └── 📄 index.js           # Application configuration
├── 📁 test/                  # Test suite
│   └── 📄 index.js           # Integration tests
├── 📄 index.js               # Library entry point
├── 📄 package.json           # Dependencies and metadata
├── 📄 package-lock.json      # Locked dependencies
├── 📄 Jenkinsfile           # CI/CD pipeline configuration
├── 📄 mocha-report-config.json # Test reporting configuration
└── 📄 README.md              # This documentation

Core Components

  • GoodreadsBookSearch Class: Main interface for book searches
  • HTML Parser: Uses Cheerio for robust HTML parsing
  • Data Extraction: Specialized methods for different book metadata
  • Error Handling: Comprehensive error catching and user-friendly messages
  • Configuration: Centralized settings for timeouts, headers, and URLs

⚙️ Configuration Options

The library includes built-in configuration that you can modify:

// Default configuration in config/index.js
{
  goodreadsBaseUrl: "https://www.goodreads.com/search?q=",
  headers: {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36..."
  },
  fetchTimeout: 2000  // Delay between requests in milliseconds
}

🧪 Testing

Run All Tests

# Install dependencies first
npm install

# Run the test suite
npm test

Test Coverage

The test suite includes:

  • ISBN validation
  • Title extraction accuracy
  • Publication date parsing
  • Page count verification
  • Error handling scenarios
  • Integration testing with live Goodreads data

Sample Test Output

🧠 Goodreads Book Search Integration Test
  ✓ Is the ISBN "9944824453" 🔥 (1500ms)
  ✓ Is the book title "Dövmeli Adam" 🚀 (1200ms)
  ✓ Is the book's publication date "1 September 2008" ⏰ (1100ms)
  ✓ Is the page count "640" 📋 (1300ms)

4 passing (5s)

📚 API Reference

GoodreadsBookSearch Class

Constructor

const BookSearch = new GoodreadsBookSearch();

Methods

getBookDetails(isbn)

Searches for a book using its ISBN number.

Parameters:

  • isbn (string): The ISBN number to search for

Returns:

  • Promise<Object>: Book details object

Example:

const details = await BookSearch.getBookDetails("9944824453");

Response Object Structure

interface BookDetails {
  title: string;                    // Book title
  thumbImage: string;               // Cover image URL
  authorName: {
    author?: {
      name: string;                 // Author name
      profileLink: string;          // Goodreads profile URL
    };
    translators?: string[];         // Translator names array
  };
  description: string;              // Book description
  page: string;                     // Page count as string
  isbn: string;                     // ISBN number
  date: string;                     // Publication date (DD MMM YYYY)
  rate: string;                     // Goodreads rating
  genres: string[];                 // Array of genre tags
}

🔄 Integration Examples

Express.js Integration

const express = require('express');
const GoodreadsBookSearch = require('szbk-goodreads-search-book');

const app = express();
app.use(express.json());

const BookSearch = new GoodreadsBookSearch();

// API endpoint for book search
app.get('/api/books/:isbn', async (req, res) => {
  try {
    const { isbn } = req.params;

    if (!isbn || isbn.length < 10) {
      return res.status(400).json({
        error: 'Invalid ISBN provided'
      });
    }

    const bookDetails = await BookSearch.getBookDetails(isbn);
    res.json({ success: true, data: bookDetails });

  } catch (error) {
    res.status(404).json({
      success: false,
      error: error.message
    });
  }
});

app.listen(3000, () => {
  console.log('📚 Book search API running on port 3000');
});

React Integration

import React, { useState } from 'react';
const GoodreadsBookSearch = require('szbk-goodreads-search-book');

function BookSearchApp() {
  const [isbn, setIsbn] = useState('');
  const [book, setBook] = useState(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState('');

  const searchBook = async () => {
    if (!isbn) return;

    setLoading(true);
    setError('');

    try {
      const BookSearch = new GoodreadsBookSearch();
      const bookDetails = await BookSearch.getBookDetails(isbn);
      setBook(bookDetails);
    } catch (err) {
      setError(err.message);
    } finally {
      setLoading(false);
    }
  };

  return (
    <div>
      <input
        value={isbn}
        onChange={(e) => setIsbn(e.target.value)}
        placeholder="Enter ISBN..."
      />
      <button onClick={searchBook} disabled={loading}>
        {loading ? 'Searching...' : 'Search'}
      </button>

      {error && <p style={{color: 'red'}}>{error}</p>}

      {book && (
        <div>
          <h2>{book.title}</h2>
          <p>Author: {book.authorName?.author?.name}</p>
          <p>Rating: {book.rate}/5</p>
          <img src={book.thumbImage} alt={book.title} />
        </div>
      )}
    </div>
  );
}

🚀 Deployment & CI/CD

Jenkins Integration

This project includes a pre-configured Jenkinsfile for automated testing:

  • Automated Triggers: Runs every 6 hours
  • Smart Dependencies: Only runs npm install when package.json changes
  • Test Reporting: Generates JUnit XML reports
  • Slack Integration: Sends build notifications to Slack channels
  • Cleanup: Automatically removes old test reports

Jenkins Pipeline Features

// Key features of the Jenkins pipeline
- Cron scheduling (H */6 * * *)
- Node.js 22.13.0 support
- Conditional dependency installation
- Automated test execution
- Test result publishing
- Slack notifications for success/failure

🔧 Development

Local Development Setup

# Clone the repository
git clone https://github.com/szbk/goodreads-book-search.git
cd goodreads-book-search

# Install dependencies
npm install

# Run tests in development mode
npm test

# Start development (if applicable)
npm run dev

Contributing Guidelines

  1. 🍴 Fork the repository
  2. 🌿 Create a feature branch (git checkout -b feature/amazing-feature)
  3. 📝 Make your changes with proper testing
  4. Ensure all tests pass
  5. 📤 Commit your changes (git commit -m 'Add amazing feature')
  6. 📤 Push to the branch (git push origin feature/amazing-feature)
  7. 🔃 Open a Pull Request

🛠️ Dependencies

Production Dependencies

Package Version Purpose
axios ^1.6.8 HTTP client for web requests
cheerio ^1.0.0-rc.12 HTML parsing and DOM manipulation
@google/generative-ai ^0.8.0 AI integration for enhanced descriptions
dotenv ^16.4.5 Environment variable management

Development Dependencies

Package Version Purpose
mocha ^11.0.1 Test framework
chai ^5.1.2 Assertion library
mocha-junit-reporter ^2.2.1 JUnit XML test reporting
mocha-multi-reporters ^1.5.1 Multiple test reporters support

FAQ

Q: Do I need a Goodreads API key?

A: No! This library works by analyzing Goodreads' public HTML structure, so no API key is required.

Q: Is this library officially supported by Goodreads?

A: No, this is an unofficial library. Use responsibly and in accordance with Goodreads' terms of service.

Q: What happens if Goodreads changes their HTML structure?

A: The library may need updates to work with new HTML structures. Report issues if you encounter problems.

Q: Can I use this in a commercial application?

A: Yes, under the MIT license. However, ensure compliance with Goodreads' terms of service.

Q: How can I avoid rate limiting?

A: The library includes a built-in 2-second delay between requests. You can modify this in the config file if needed.


  • This is an unofficial library and is not affiliated with Goodreads
  • Use responsibly and in accordance with Goodreads' terms of service
  • The library is provided "as-is" without warranties
  • Users are responsible for ensuring compliance with applicable laws and terms

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

MIT License

Copyright (c) 2024 szbk

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

🤝 Support & Community


📊 Version History

v1.1.2 (Current)

  • Enhanced HTML parsing stability
  • 🛡️ Improved error handling
  • 📝 Better documentation

v1.1.0

  • 🔧 Added configurable timeouts
  • 🧪 Enhanced test coverage
  • 🚀 Performance improvements

v1.0.0

  • 🎉 Initial release
  • 📚 Core Goodreads search functionality
  • 🔍 ISBN-based book lookup

🙏 Acknowledgments

  • Goodreads - For providing an amazing book database platform
  • Cheerio - Excellent HTML parsing library
  • Axios - Reliable HTTP client
  • Mocha & Chai - Great testing framework
  • The open-source community for inspiration and tools

If this project helped you, please give it a star on GitHub!

Made with ❤️ by szbk