diff --git a/README.md b/README.md index d1aa3ba..6ea35b7 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,47 @@ -# Azur Lane - +# Azur Lane Ship Girl Information Scraper -Scrape Azur Lane ship girl information from [Azurlane WIKI](https://azurlane.koumakan.jp/) +![Shinano](https://i.imgur.com/PgPhVEc.png) + +
+Discord + npm +GitHub issues +GitHub Repo stars + GitHub +
+ +### The picture above is only an illustration + +This Node.js module allows you to scrape Azur Lane ship girl information from [Azurlane Wiki](https://azurlane.koumakan.jp/). ## Installation +You can install this module using npm: + ```bash npm install @rifzkhy/azur-lane ``` ## Example - +Here's an example of how to use this module in your Node.js code: ```javascript -const searchCharacter = require ("@rifzkhy/azur-lane"); +const azurlane = require("./index.js"); -const character = "shinano"; +const shipname = "shinano"; -searchCharacter(character) +azurlane(shipname) .then((result) => { console.log(result); }) .catch((error) => { console.error(error); }); - ``` ## Output - +The azurlane function returns detailed information about the specified ship girl. Here's an example of the output structure: ```javascript { - url: 'https://azurlane.koumakan.jp/w/index.php?search=shinano', banner: 'https://azurlane.netojuu.com/images/4/42/ShinanoBanner.png', skin: 'https://azurlane.netojuu.com/images/2/2f/ShinanoShipyardIcon.png', chibi: 'https://azurlane.netojuu.com/images/5/5f/ShinanoChibi.png', @@ -78,11 +89,14 @@ ship's AVI by 5% (15%). When the fleet this ship is NOT in starts its 3rd, 4th, name: 'Protector of the New Moon', description: "While this ship is afloat: increases the FP, EVA, and ASW of your DDs by 5% (15%). If the fleet this ship is in contains 3 (or more) Sakura Empire ships: decreases this ship's DMG taken from Main Guns and Aircraft by 10% (20%) and increases AVI and Accuracy by 5% (15%) for all your Sakura Empire CVs and CVLsIn-game only mentions CVs, but IJN CVLs are also affected by this buff." }, - skill4: { icon: '', name: '', description: '' }, - skill5: { icon: '', name: '', description: '' }, - skill6: { icon: '', name: '', description: '' } + skill4: { icon: undefined, name: undefined, description: undefined }, + skill5: { icon: undefined, name: undefined, description: undefined }, + skill6: { icon: undefined, name: undefined, description: undefined } } } ``` +This output provides comprehensive information about the specified ship girl's attributes, skills, and more. + +Feel free to customize and use this module to retrieve Azur Lane ship girl information for your applications. -## License [MIT](https://github.com/Rifzkhy/azur-lane/blob/main/LICENSE) \ No newline at end of file +I've improved the formatting and provided a more detailed explanation of the module and its output. You can replace the placeholder text with actual information as needed. \ No newline at end of file diff --git a/example.js b/example.js index 0249dc1..7d46ca4 100644 --- a/example.js +++ b/example.js @@ -1,8 +1,8 @@ -const searchCharacter = require ("./index.js"); +const azurlane = require("./index.js"); -const character = "shinano"; +const shipname = "shinano"; -searchCharacter(character) +azurlane(shipname) .then((result) => { console.log(result); }) diff --git a/index.js b/index.js index fff9883..8367770 100644 --- a/index.js +++ b/index.js @@ -1,14 +1,14 @@ -const request = require ("request"); -const cheerio = require ("cheerio"); +const cheerio = require("cheerio"); +const request = require("request"); -module.exports = searchCharacter = (character) =>{ +module.exports = async function azurlane(ship) { return new Promise((resolve, reject) => { - const source = `https://azurlane.koumakan.jp/w/index.php?search=${character}&title=Special%3ASearch&go=Go`; + const source = `https://azurlane.koumakan.jp/w/index.php?search=${ship}&title=Special%3ASearch&go=Go`; request(source, (error, response, html) => { if (error || response.statusCode !== 200) { reject(error); - return;e + return; } const $ = cheerio.load(html); @@ -25,7 +25,7 @@ module.exports = searchCharacter = (character) =>{ search(html, resolve, url); }); } else { - const url = `https://azurlane.koumakan.jp/w/index.php?search=${character}`; + const url = `https://azurlane.koumakan.jp/w/index.php?search=${ship}`; request(url, (error, response, html) => { if (error || response.statusCode !== 200) { reject(error); @@ -36,28 +36,28 @@ module.exports = searchCharacter = (character) =>{ } }); }); -} +}; function search(html, resolve, url) { const $ = cheerio.load(html); const shipbannerSearch = $(".shipgirl-banner span a img"); - const banner = shipbannerSearch.attr("src") || ""; //! banner + const banner = shipbannerSearch.attr("src") || undefined; //! banner const shipskinSearch = $(".ship-card img"); - const skin = shipskinSearch.attr("src") || ""; //! skin + const skin = shipskinSearch.attr("src") || undefined; //! skin const shipfactionSearch = $(".card-logo img"); - const faction = shipfactionSearch.attr("src") || ""; //! faction + const faction = shipfactionSearch.attr("src") || undefined; //! faction const shipcategorySearch = $(".card-class-stamp img"); - const category = shipcategorySearch.attr("src") || ""; //! category + const category = shipcategorySearch.attr("src") || undefined; //! category const shipvoiceSearch = $(".card-info-tbl .sm2_button"); - const voice = shipvoiceSearch.attr("href") || ""; //! voice + const voice = shipvoiceSearch.attr("href") || undefined; //! voice - const name = $(".mw-page-title-main").text().trim(); //! name + const name = $(".mw-page-title-main").text().trim() || undefined; //! name - const title = $(".card-headline span[lang=en]").text().trim(); //! title + const title = $(".card-headline span[lang=en]").text().trim() || undefined; //! title const galleryUrl = url + "/Gallery"; @@ -69,30 +69,31 @@ function search(html, resolve, url) { const $gallery = cheerio.load(html); const shipchibiSearch = $gallery(".shipskin-chibi img"); - const chibi = shipchibiSearch.attr("src") || ""; //! chibi + const chibi = shipchibiSearch.attr("src") || undefined; //! chibi // TODO: ship information - const shiprarity = $(".card-info-tbl tr:nth-child(2) td").text().trim(); //! rarity - const shipconstruction = $(".card-info-tbl tr:nth-child(1) td") - .text() - .trim(); //! construction - const shipclass = $(".card-info-tbl tr:nth-child(5) td") - .text() - .replace(/\n/g, "") - .trim(); //! class - const shipfaction = $(".card-info-tbl tr:nth-child(4) td").text().trim(); //! faction - const shipcategory = $(".card-info-tbl tr:nth-child(3) td") - .text() - .replace(/\n|→  Guided-missile Destroyer/g, "") - .trim(); //! category - const shipvoice = $(".card-info-tbl tr:nth-child(6) td") - .text() - .replace(/Play/g, "") - .trim(); //! voice - const shipillustrator = $(".card-info-tbl tr:nth-child(7) td") - .text() - .trim(); //! illustrator - const shipdrop = $(".drop-notes td").text().trim(); //! drop + const shiprarity = + $(".card-info-tbl tr:nth-child(2) td").text().trim() || undefined; //! rarity + const shipconstruction = + $(".card-info-tbl tr:nth-child(1) td").text().trim() || undefined; //! construction + const shipclass = + $(".card-info-tbl tr:nth-child(5) td").text().replace(/\n/g, "").trim() || + undefined; //! class + const shipfaction = + $(".card-info-tbl tr:nth-child(4) td").text().trim() || undefined; //! faction + const shipcategory = + $(".card-info-tbl tr:nth-child(3) td") + .text() + .replace(/\n|→  Guided-missile Destroyer/g, "") + .trim() || undefined; //! category + const shipvoice = + $(".card-info-tbl tr:nth-child(6) td") + .text() + .replace(/Play/g, "") + .trim() || undefined; //! voice + const shipillustrator = + $(".card-info-tbl tr:nth-child(7) td").text().trim() || undefined; //! illustrator + const shipdrop = $(".drop-notes td").text().trim() || undefined; //! drop const info = { rarity: shiprarity, @@ -106,20 +107,18 @@ function search(html, resolve, url) { }; // TODO: tech points - const techcollection = $(".ship-fleettech tr:nth-child(2) td:nth-child(3)") - .text() - .trim(); //! collection - const techmaxlimitbreak = $( - ".ship-fleettech tr:nth-child(3) td:nth-child(3)" - ) - .text() - .trim(); //! maxlimitbreak - const techlevel120 = $(".ship-fleettech tr:nth-child(4) td:nth-child(3)") - .text() - .trim(); //! level120 - const techtotal = $(".ship-fleettech tr:nth-child(2) td:nth-child(4)") - .text() - .trim(); //! total + const techcollection = + $(".ship-fleettech tr:nth-child(2) td:nth-child(3)").text().trim() || + undefined; //! collection + const techmaxlimitbreak = + $(".ship-fleettech tr:nth-child(3) td:nth-child(3)").text().trim() || + undefined; //! maxlimitbreak + const techlevel120 = + $(".ship-fleettech tr:nth-child(4) td:nth-child(3)").text().trim() || + undefined; //! level120 + const techtotal = + $(".ship-fleettech tr:nth-child(2) td:nth-child(4)").text().trim() || + undefined; //! total const techpoint = { collection: techcollection, @@ -129,20 +128,17 @@ function search(html, resolve, url) { }; // TODO: limit break - const firstlimitbreak = $(".ship-limit-break tr:nth-child(3) td") - .text() - .trim(); //! first - const secondlimitbreak = $(".ship-limit-break tr:nth-child(4) td") - .text() - .trim(); //! second - const thirdlimitbreak = $(".ship-limit-break tr:nth-child(5) td") - .text() - .trim(); //! third + const firstlimitbreak = + $(".ship-limit-break tr:nth-child(3) td").text().trim() || undefined; //! first + const secondlimitbreak = + $(".ship-limit-break tr:nth-child(4) td").text().trim() || undefined; //! second + const thirdlimitbreak = + $(".ship-limit-break tr:nth-child(5) td").text().trim() || undefined; //! third const limitbreak = { - first: firstlimitbreak, - second: secondlimitbreak, - third: thirdlimitbreak, + first: firstlimitbreak || undefined, + second: secondlimitbreak || undefined, + third: thirdlimitbreak || undefined, }; // TODO: skills @@ -152,22 +148,22 @@ function search(html, resolve, url) { const shipskilliconSearch = $( ".ship-skills tr:nth-child(" + i + ") td img" ); - const skillicon = shipskilliconSearch.attr("src") || ""; - const skillname = $(".ship-skills tr:nth-child(" + i + ") td b") - .text() - .trim(); - const skilldescription = $( - ".ship-skills tr:nth-child(" + i + ") td:last-child" - ) - .text() - .replace(/\(\) /g, "") - .replace(/\.mw-parser-output.*?}/g, "") - .replace(/body\..*?\s/g, "") - .replace(/body:not\(.+?\):not\(.+?\)\s*/g, "") - .replace(/ andIn-game[^;]*;/g, "") - .replace(/\s+/g, " ") - .replace(/↑[^.]*|\n/g, "") - .trim(); + const skillicon = shipskilliconSearch.attr("src") || undefined; + const skillname = + $(".ship-skills tr:nth-child(" + i + ") td b") + .text() + .trim() || undefined; + const skilldescription = + $(".ship-skills tr:nth-child(" + i + ") td:last-child") + .text() + .replace(/\(\) /g, "") + .replace(/\.mw-parser-output.*?}/g, "") + .replace(/body\..*?\s/g, "") + .replace(/body:not\(.+?\):not\(.+?\)\s*/g, "") + .replace(/ andIn-game[^;]*;/g, "") + .replace(/\s+/g, " ") + .replace(/↑[^.]*|\n/g, "") + .trim() || undefined; skills["skill" + (i - 1)] = { icon: skillicon, @@ -177,7 +173,6 @@ function search(html, resolve, url) { } resolve({ - url, banner, skin, chibi, diff --git a/package.json b/package.json index 05c664e..00e2507 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,25 @@ { "name": "@rifzkhy/azur-lane", - "version": "1.0.0", + "version": "1.0.1", "description": "Azurlane scraper", "main": "index.js", "scripts": { "test": "node example.js" }, + "repository": { + "type": "git", + "url": "git+https://github.com/Rifzkhy/azur-lane.git" + }, + "keywords": [ + "scraper", + "azurlane", + "azur-lane", + "shipgirl", + "shikikan", + "nodejs", + "cheerio", + "request" + ], "author": "@rifzkhy", "license": "MIT", "dependencies": { diff --git a/preview.webp b/preview.webp deleted file mode 100644 index 245a606..0000000 Binary files a/preview.webp and /dev/null differ