您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
なろうの小説トップページ上にAPIから取得した作品情報を表示、キーワード強調、作者マイページリンクボタンも情報ボックス内に表示
当前为
// ==UserScript== // @name Narou API Info + Author Page Button (in Box) // @namespace haaarug // @version 2.5 // @description なろうの小説トップページ上にAPIから取得した作品情報を表示、キーワード強調、作者マイページリンクボタンも情報ボックス内に表示 // @license CC0 // @match https://ncode.syosetu.com/* // @grant GM_xmlhttpRequest // @connect api.syosetu.com // @run-at document-end // ==/UserScript== (function () { 'use strict'; const NGwords = ["残酷", "NG2", "NG3", "NG4", "NG5"]; const OKwords = ["異世界", "OK2", "OK3", "OK4", "OK5"]; // 話数ページではなく作品トップページかを確認 const pathSegments = location.pathname.split('/').filter(Boolean); if (pathSegments.length !== 1) return; const match = pathSegments[0].match(/^(n\d+[a-z]+)$/i); if (!match) return; const ncode = match[1].toLowerCase(); const apiUrl = `https://api.syosetu.com/novelapi/api/?out=json&ncode=${encodeURIComponent(ncode)}`; // 作者リンクの要素を探す const authorLinkEl = document.querySelector('a.c-under-nav__item[href^="https://mypage.syosetu.com/"]'); const authorPageUrl = authorLinkEl ? authorLinkEl.href : null; // APIリクエスト GM_xmlhttpRequest({ method: 'GET', url: apiUrl, headers: { 'Accept': 'application/json' }, onload: function (response) { try { const json = JSON.parse(response.responseText); if (json.length < 2) return; const data = json[1]; const title = data.title || '不明'; const writer = data.writer || '不明'; const status = data.end === 0 ? '完結' : '連載中❌'; const eternal = data.isstop === 0 ? '' : '⚠️エタ?⚠️'; const keywords = data.keyword || '不明'; // NGワード, OKワードを含むキーワードを目立たせる const highlightedKeywords = keywords.split(" ").map(word => { if (NGwords.some(ng => word.includes(ng))) { // NGワードを含む return `<span style="color: red; font-weight: bold; font-size: 22px;">${word}</span>`; } else if (OKwords.some(ok => word.includes(ok))) { // OKワードと完全一致 return `<span style="color: green;">${word}</span>`; } else { // どちらにも該当しない return `${word}`; } }).join(" "); const length = data.length ? data.length.toLocaleString() + '文字' : '不明'; const general_lastup = data.general_lastup || '不明'; const general_all_no = data.general_all_no ? data.general_all_no.toLocaleString() + '話' : '不明'; const genreMap = { 0: '未選択〔未選択〕', 101: '異世界〔恋愛〕', 102: '現実世界〔恋愛〕', 201: 'ハイファンタジー〔ファンタジー〕', 202: 'ローファンタジー〔ファンタジー〕', 301: '純文学〔文芸〕', 302: 'ヒューマンドラマ〔文芸〕', 303: '歴史〔文芸〕', 304: '推理〔文芸〕', 305: 'ホラー〔文芸〕', 306: 'アクション〔文芸〕', 307: 'コメディー〔文芸〕', 401: 'VRゲーム〔SF〕', 402: '宇宙〔SF〕', 403: '空想科学〔SF〕', 404: 'パニック〔SF〕', 9901: '童話〔その他〕', 9902: '詩〔その他〕', 9903: 'エッセイ〔その他〕', 9904: 'リプレイ〔その他〕', 9999: 'その他〔その他〕', 9801: 'ノンジャンル〔ノンジャンル〕' }; const genreText = genreMap[data.genre] || '不明ジャンル'; // 開閉ボタン const toggleButton = document.createElement('button'); toggleButton.textContent = 'ℹ️'; toggleButton.style.cssText = ` position: fixed; top: 10px; left: 10px; z-index: 10000; padding: 5px 5px; font-size: 14px; border-radius: 5px; border: 1px solid #888; background: #f0f0f0; cursor: pointer; `; // 情報表示ボックス const infoBox = document.createElement('div'); infoBox.style.cssText = ` background-color: #f5f5f5; border: 1px solid #ccc; width: 333px; height: auto; position: fixed; top: 50px; left: 0px; z-index: 9999; font-size: 18px; line-height: 1.6; color: #333; padding: 15px; overflow-y: auto; box-shadow: 0 4px 8px rgba(0,0,0,0.2); border-radius: 8px; `; // 作者マイページボタン(存在する場合のみ追加) const authorButton = authorPageUrl ? ` <a href="${authorPageUrl}" target="_blank" style=" font-size: 14px; text-align: center; ">▶ 作者マイページへ</a> ` : ''; infoBox.innerHTML = ` <strong>📚</strong> ${title}<br> <strong>🖋️</strong> ${writer}<br> ${authorButton}<br> <div style="height: 10px;"></div> <strong>📝</strong> ${genreText}<br> <strong>🔑</strong> ${highlightedKeywords}<br> <div style="height: 10px;"></div> <strong>🔤 文字数:</strong> ${length}<br> <strong>📖 全</strong> ${general_all_no}<br> <strong>📅 最新掲載日:</strong> ${general_lastup}<br> <strong>✍️ </strong> ${status} <strong style="color: red;">${eternal}</strong><br> `; toggleButton.onclick = () => { infoBox.style.display = infoBox.style.display === 'none' ? 'block' : 'none'; }; document.body.appendChild(toggleButton); document.body.appendChild(infoBox); } catch (e) { console.error('JSON解析エラー:', e); } }, onerror: function (err) { console.error('API通信エラー:', err); } }); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址