diff --git a/README.md b/README.md index 4c66ec6d..c3205928 100644 --- a/README.md +++ b/README.md @@ -163,7 +163,7 @@ EPUB 文件请使用相应阅读器阅读。 | [新笔趣阁](https://www.ibiquge.la/) | ✅ | ❎ | | | [69 书吧](https://www.69shu.com/) | ✅ | ❎ | | | [笔下文学](https://www.ywggzy.com/) | ✅ | ❎ | | -| [飘天文学](https://www.ptwxz.net/) | ✅ | ❎ | | +| [飘天文学网](https://www.piaotia.com/) | ✅ | ❎ | | | [红袖招](https://hongxiuzhao.me/) | ✅ | ❎ | | | [38 看书](https://www.mijiashe.com/) | ✅ | ❎ | | | [天天看小说](https://www.ttkan.co/) | ✅ | ❎ | | diff --git a/src/header.json b/src/header.json index 910029e7..4c2b62e0 100644 --- a/src/header.json +++ b/src/header.json @@ -196,8 +196,7 @@ "*://new-read.readmoo.com/mooreader/*", "*://www.iqingguo.com/book/detail/?id=*", "*://www.ywggzy.com/bxwx/*/", - "*://www.ptwxz.net/*/", - "*://www.ptwxz.net/list/*/", + "*://www.piaotia.com/html/*", "*://www.mbtxt.la/go/*/", "*://m.kuangguwenhua.com/bqg/*/", "*://m.kuangguwenhua.com/bqg/11365/index_*.html", diff --git a/src/router/download.ts b/src/router/download.ts index 6d2a3504..5d3ce138 100644 --- a/src/router/download.ts +++ b/src/router/download.ts @@ -386,9 +386,9 @@ export async function getRule(): Promise { ruleClass = novelup(); break; } - case "www.ptwxz.net": { + case "www.piaotia.com": { const { ptwxz } = await import( - "../rules/onePageWithMultiIndexPage/ptwxz" + "../rules/onePage/original/ptwxz" ); ruleClass = ptwxz(); break; diff --git a/src/router/ui.ts b/src/router/ui.ts index 8705235b..03cfdd69 100644 --- a/src/router/ui.ts +++ b/src/router/ui.ts @@ -267,7 +267,7 @@ export function getUI(): () => UIObject { } }; } - case "www.ptwxz.net": { + case "www.piaotia.com": { return () => { if (document.location.pathname.startsWith("/list/")) { return { diff --git a/src/rules/onePage/original/ptwxz.ts b/src/rules/onePage/original/ptwxz.ts new file mode 100644 index 00000000..d2f813ec --- /dev/null +++ b/src/rules/onePage/original/ptwxz.ts @@ -0,0 +1,61 @@ +import { mkRuleClass } from "../template"; + +export const ptwxz = () => + mkRuleClass({ + bookUrl: document.location.href, + bookname: + document.querySelector("h1")?.innerText.trim().replace('最新章节', '') ?? "", + author: + document.querySelector('.list')?.textContent?.split(' \u00A0')[0]?.replace('作者:', '')?.trim() ?? "", + introDom: document.querySelector("#intro") ?? undefined, + introDomPatch: (dom) => dom, + coverUrl: + document.location.href.replace(/(https:\/\/www\.piaotia\.com)\/html\/(\d+)\/(\d+)(\/index.html)?\/?$/, '$1/files/article/image/$2/$3/$3s.jpg'), + getAName: (aElem) => (aElem as HTMLElement).innerText.trim(), + aList: document.querySelectorAll('ul > li > a'), + getContent: (dom) => dom.body, + contentPatch: (dom) => { + const title = dom.querySelector('h1')?.textContent?.trim() ?? ''; + + // Find the and
or
, process it + if (currentNode.nodeType === Node.TEXT_NODE || (currentNode.nodeType === Node.ELEMENT_NODE && currentNode.nodeName.toLowerCase() !== 'table' && currentNode.nodeName.toLowerCase() !== 'div')) { + let textContent = currentNode.textContent || ''; + if (currentNode.nodeType === Node.ELEMENT_NODE && currentNode.nodeName.toLowerCase() === 'br') { + // Replace
with newlines + textContent = '\n'; + } + + // Split the text contents at newlines and wrap each line in

tags + textContent.split('\n').forEach((line) => { + const trimmedLine = line.trim(); + if (trimmedLine && title !== trimmedLine) { + content += `

${trimmedLine}

`; + } + }); + } + // Move to the next sibling node + currentNode = currentNode.nextSibling; + } + + // Create a new div and set its innerHTML to the processed content + const divElement = document.createElement('div'); + divElement.innerHTML = content; + + return divElement; + } + }); diff --git a/src/rules/onePageWithMultiIndexPage/ptwxz.ts b/src/rules/onePageWithMultiIndexPage/ptwxz.ts deleted file mode 100644 index 76acd219..00000000 --- a/src/rules/onePageWithMultiIndexPage/ptwxz.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { mkRuleClass } from "./template"; -import { getHtmlDOM } from "../../lib/http"; -import { nextPageParse } from "../../lib/rule"; -import { rm2 } from "../../lib/dom"; - -export const ptwxz = () => - mkRuleClass({ - bookUrl: document.location.href, - bookname: - document - .querySelector("#info h1") - ?.innerText.trim() ?? "", - author: - document - .querySelector( - "#info > p:nth-child(2) > a:nth-child(1)" - ) - ?.innerText.trim() ?? "", - introDom: document.querySelector("#intro") ?? undefined, - introDomPatch: (dom) => dom, - coverUrl: - document.querySelector("#fmimg > img")?.src ?? null, - getIndexUrls: async () => { - const base = document.location.pathname; - const listUrlBase = document.location.origin + "/list" + base; - const doc = await getHtmlDOM(listUrlBase, document.characterSet); - return Array.from( - doc.querySelectorAll("#indexselect > option") - ).map((o) => document.location.origin + o.getAttribute("value")); - }, - getAList: (doc) => doc.querySelectorAll('a[rel="chapter"]'), - getContentFromUrl: async ( - chapterUrl: string, - chapterName: string | null, - charset: string - ) => { - const { contentRaw } = await nextPageParse({ - chapterName, - chapterUrl, - charset, - selector: "#booktxt", - contentPatch: (content) => { - rm2(["本章未完,點選下一頁繼續閱讀。"], content); - return content; - }, - getNextPage: (doc) => - doc.querySelector("#next_url")?.href ?? "", - continueCondition: (content, nextLink) => { - if (nextLink === "") { - return false; - } - return nextLink.includes("_"); - }, - enableCleanDOM: false, - }); - return contentRaw; - }, - contentPatch: (dom) => dom, - });