575 lines
15 KiB
Markdown
575 lines
15 KiB
Markdown
# 📚 Unofficial Goodreads Book Search API
|
||
|
||
[](https://badge.fury.io/js/szbk-goodreads-search-book)
|
||
[](https://opensource.org/licenses/MIT)
|
||
[](https://nodejs.org/)
|
||
[](https://github.com/szbk/goodreads-book-search)
|
||
|
||
🔍 **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
|
||
|
||
```bash
|
||
# Install via npm
|
||
npm install szbk-goodreads-search-book
|
||
|
||
# Or using yarn
|
||
yarn add szbk-goodreads-search-book
|
||
```
|
||
|
||
---
|
||
|
||
## 🚀 Quick Start
|
||
|
||
### Basic Usage
|
||
|
||
```javascript
|
||
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
|
||
|
||
```json
|
||
{
|
||
"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
|
||
|
||
```javascript
|
||
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);
|
||
}
|
||
});
|
||
```
|
||
|
||
### Multiple Book Search
|
||
|
||
```javascript
|
||
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:
|
||
|
||
```javascript
|
||
// 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
|
||
|
||
```bash
|
||
# 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
|
||
```javascript
|
||
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:**
|
||
```javascript
|
||
const details = await BookSearch.getBookDetails("9944824453");
|
||
```
|
||
|
||
### Response Object Structure
|
||
|
||
```typescript
|
||
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
|
||
|
||
```javascript
|
||
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
|
||
|
||
```jsx
|
||
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
|
||
|
||
```groovy
|
||
// 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
|
||
|
||
```bash
|
||
# 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.
|
||
|
||
---
|
||
|
||
## 🔒 Legal & Disclaimer
|
||
|
||
- 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](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
|
||
|
||
- **GitHub Issues**: [Report bugs and request features](https://github.com/szbk/goodreads-book-search/issues)
|
||
- **GitHub Discussions**: [Community discussions and questions](https://github.com/szbk/goodreads-book-search/discussions)
|
||
- **NPM Page**: [Package information and version history](https://www.npmjs.com/package/szbk-goodreads-search-book)
|
||
|
||
---
|
||
|
||
## 📊 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
|
||
|
||
---
|
||
|
||
<div align="center">
|
||
|
||
**⭐ If this project helped you, please give it a star on GitHub!**
|
||
|
||
Made with ❤️ by [szbk](https://github.com/szbk)
|
||
|
||
</div> |