Node.JS client for nhentai.net undocumented APIs.
Node.JS module for handling nhentai.net API.
Features
- Objective-oriented API abstraction.
- Bidirectional inspecting (get image from book/get book from image).
- Easy proxy support by using custom Agent (like this one).
- Return URLs for binary data (images).
Install
Install via yarn:
yarn add nhentai-api
Install via npm:
npm i nhentai-api
Docs
Read the docs on GitHub pages.
Example
Import
CommonJS
const { API, TagTypes, } = require('nhentai-api');
ES6
import { API, TagTypes, } from 'nhentai-api';
Use
Initialize API client
const api = new API();
Get the book
api.getBook(177013).then(book => {
api.getImageURL(book.cover); // https://t.nhentai.net/galleries/987560/cover.jpg
api.getImageURL(book.pages[1]); // https://i.nhentai.net/galleries/987560/2.jpg
});
Get random book
await api.getRandomBook(); // Book instance
Search for the books
api.search('test').then(async search => {
console.log(search); /*
Search {
api: API { hosts: [Object], ssl: true, agent: [Agent] },
query: 'test',
page: 1,
perPage: 25,
books: [
[Book], [Book], [Book], [Book],
[Book], [Book], [Book], [Book],
[Book], [Book], [Book], [Book],
[Book], [Book], [Book], [Book],
[Book], [Book], [Book], [Book],
[Book], [Book], [Book], [Book],
[Book]
],
pages: 67
} */
search = await search.getNextPage(); // Same as api.search('text', 2);
console.log(search); /*
Search {
// Same as above
page: 2,
// Same as above
books: [
// Books from 2nd page of search
],
// Same as above
} */
});
In case you need to change API implementation (e.g. change proxy) you can pass api
to
search.getNextPage(api);
You can also use async generator:
// Get first 2 pages
for await (const search of api.searchGenerator('test')) {
console.log(search);
if (search.page >= 2)
break;
}
Working with tags
book.tags
has type of TagsArray
, it is just an Array<Tag>
with helper methods.
const tag = book.tags[0]; // Tag
Get tag id
tag.id;
Get tag name (without count)
tag.name;
// or
tag.toString();
Get tag name (with count)
tag.toString(true);
Get tag type (as string)
tag.type.type;
// or
tag.type.toString();
Pre-filtered tags
book.pureTags; // pure tags (with type 'tag')
book.categories; // category tags
book.artists; // artist tags
book.parodies; // parody tags
book.characters; // character tags
book.groups; // group tags
book.languages; // language tags
Filter tags
Get artists:
book.artists;
// or
book.getTagsWith({
type: TagTypes.Artist, // you may also use Tag.types.Artist or Tag.types.get('artist')
}); // TagsArray (subclass of Array<Tag>)
// or
book.getTagsWith({ type: 'artist', }); // TagsArray (subclass of Array<Tag>)
Get tag with name english
:
book.getTagsWith({ name: 'english', }); // TagsArray (subclass of Array<Tag>)
Get categories
book.categories;
// or
book.getTagsWith({ type: TagTypes.Category, }); // Recommended
// or
book.getTagsWith({ type: Tag.types.Category, });
// or
book.getTagsWith({ type: Tag.types.get('category'), });
// or
book.getTagsWith({ type: 'category', });
Get tags comma separated
Without counts:
book.tags.toNames().join(', ');
// or
book.tags.join(', ');
With counts:
book.tags.toNames(true).join(', ');
// or
book.tags.map(tag => tag.toString(true)).join(', ')
Get all artists:
// With counts
book.artists.toNames(true).join(', ');
// or
book.getTagsWith({ type: TagTypes.Artist, }).toNames(true).join(', ');
// Without counts
book.artists.join(', ');
// or
book.artists.toNames().join(', ');
// or
book.getTagsWith({ type: TagTypes.Artist, }).join(', ');