pixiv

https://www.pixiv.net/

采集机器人 (2)2023/04/06

该用户很懒,什么介绍也没有写!
二维码导入
{
    "bookSourceComment": "pixiv本体",
    "bookSourceGroup": "🔞 Pixiv",
    "bookSourceName": "pixiv",
    "bookSourceType": 0,
    "bookSourceUrl": "https:\/\/www.pixiv.net\/",
    "bookUrlPattern": "",
    "customOrder": 0,
    "enabled": true,
    "enabledCookieJar": false,
    "enabledExplore": true,
    "enabledReview": false,
    "exploreUrl": "推荐小说::https:\/\/www.pixiv.net\/ajax\/top\/novel?mode=all&lang=zh\n收藏小说::https:\/\/www.pixiv.net\/ajax\/user\/{{cache.get(\"pixiv:uid\")}}\/novels\/bookmarks?tag=&offset={{(page-1)*24}}&limit=24&rest=show&lang=zh\n关注用户::https:\/\/www.pixiv.net\/ajax\/user\/{{cache.get(\"pixiv:uid\")}}\/following?offset={{(page-1)*24}}&limit=24&rest=show&tag=&acceptingRequests=0&lang=zh",
    "header": "",
    "lastUpdateTime": 1674101510940,
    "loginCheckJs": "let uid = java.getResponse().headers().get(\"x-userid\")\nif (uid != null) {\n    cache.put(\"pixiv:uid\", uid)\n}\njava.getStrResponse(null, null)",
    "loginUrl": "https:\/\/accounts.pixiv.net\/login",
    "respondTime": 180000,
    "ruleBookInfo": {
        "author": "author",
        "coverUrl": "coverUrl",
        "init": "@js:\n\nvar util = {}\n\nfunction init() {\n    let u = {}\n\n    u.cacheGetAndSet = (key, supplyFunc) => {\n        let v = cache.get(key)\n        if (v === undefined || v === null) {\n            v = JSON.stringify(supplyFunc())\n            \/\/ 缓存10分钟\n            cache.put(key, v, 600)\n        }\n        return JSON.parse(v)\n    }\n    u.debugFunc = (func) => {\n        if (String(source.getVariable()) === \"debug\") {\n            func()\n        }\n    }\n\n    u.urlNovelDetailed = (nid) => {\n        return `https:\/\/www.pixiv.net\/ajax\/novel\/${nid}`\n    }\n    u.urlSeries = (seriesId) => {\n        return `https:\/\/www.pixiv.net\/ajax\/novel\/series\/${seriesId}?lang=zh`\n    }\n    u.urlSeriesNovels = (seriesId, limit, offset) => {\n        if (limit > 30) {\n            limit = 30\n        }\n\n        if (limit < 10) {\n            limit = 10\n        }\n\n        return `https:\/\/www.pixiv.net\/ajax\/novel\/series_content\/${seriesId}?limit=${limit}&last_order=${offset}&order_by=asc&lang=zh`\n    }\n    util = u\n    java.put(\"util\", objStringify(u))\n}\n\nfunction objStringify(obj) {\n    return JSON.stringify(obj, (n, v) => {\n        if (typeof v == \"function\")\n            return v.toString();\n        return v;\n    });\n}\n\n(() => {\n    if (result.startsWith(\"<!DOCTYPE html>\")) {\n        return {}\n    }\n\n    init()\n    \/\/ java.log(`详情信息:${result}`)\n    let res = JSON.parse(result).body\n    info = {}\n    info.author = book.author\n    info.name = book.name\n    info.tags = book.kind\n    info.wordCount = book.wordCount\n    info.latestChapter = null\n    info.desc = book.intro\n    info.coverUrl = book.coverUrl\n    info.catalogUrl = util.urlNovelDetailed(res.id)\n    return info\n})();",
        "intro": "desc",
        "kind": "tags",
        "name": "name",
        "tocUrl": "catalogUrl",
        "wordCount": "wordCount"
    },
    "ruleContent": {
        "content": "@js:\n(() => {\n    let res = JSON.parse(result).body\n    let content = res.content\n\n    let hasEmbeddedImages = res.textEmbeddedImages !== undefined && res.textEmbeddedImages !== null\n    if (hasEmbeddedImages) {\n        Object.keys(res.textEmbeddedImages).forEach((key) => {\n            \/\/todo 使用了linpx的图片代理 目前只能想到这样解决\n            content = content.replace(`[uploadedimage:${key}]`, `<img src=\"https:\/\/linpxapi.linpicio.com\/proxy\/pximg?url=${res.textEmbeddedImages[key].urls.original}\">`)\n        })\n    }\n    return content\n})()",
        "nextContentUrl": ""
    },
    "ruleExplore": {
        "author": "userName",
        "bookList": "@js:\n\n\/\/ 存储seriesID 有BUG无法处理翻页\nvar seriesSet = new Set();\n\nfunction urlCoverUrl(url) {\n    return `${url},{\"headers\": {\"Referer\":\"https:\/\/www.pixiv.net\/\"}}`\n}\n\n\/\/ 将多个长篇小说解析为一本书\nfunction combineNovels(novels) {\n    return novels.filter(novel => {\n        \/\/单本直接解析为一本书\n        if (novel.seriesId === undefined || novel.seriesId === null) {\n            return true\n        }\n\n        \/\/集合中没有该系列解析为一本书\n        if (!seriesSet.has(novel.seriesId)) {\n            seriesSet.add(novel.seriesId)\n            return true\n        }\n\n        return false\n    })\n}\n\nfunction urlNovelDetailed(nid) {\n    return `https:\/\/www.pixiv.net\/ajax\/novel\/${nid}`\n}\n\n\nfunction handNovels(novels) {\n    novels.forEach(novel => {\n        if (novel.tags === undefined || novel.tags === null) {\n            novel.tags = []\n        }\n\n        if (novel.seriesId === undefined || novel.seriesId === null) {\n            novel.tags.unshift(\"单本\")\n        } else {\n            novel.tags.unshift(\"长篇\")\n            \/\/ todo 暂时不做字数统计\n            novel.textCount = null\n        }\n    })\n\n    return novels\n}\n\nfunction formatNovels(novels) {\n    novels.forEach(novel => {\n        novel.detailedUrl = urlNovelDetailed(novel.id)\n        novel.tags = novel.tags.join(\",\")\n        novel.coverUrl = urlCoverUrl(novel.url)\n    })\n    return novels\n}\n\nfunction handlerFactory() {\n    let cookie = String(java.getCookie(\"https:\/\/www.pixiv.net\/\", null))\n    if (cookie === null || cookie === undefined || cookie === \"\") {\n        return handlerNoLogin()\n    }\n    if (baseUrl.indexOf(\"\/bookmark\") !== -1) {\n        return handlerBookMarks()\n    }\n\n    if (baseUrl.indexOf(\"\/top\") !== -1) {\n        return handlerRecommend()\n    }\n\n    if (baseUrl.indexOf(\"\/following\") !== -1) {\n        return handlerFollowing()\n    }\n}\n\nfunction handlerFollowing() {\n    return () => {\n        let novelList = []\n        JSON.parse(result).body.users\n            .filter(user => user.novels.length > 0)\n            .map(user => user.novels)\n            .forEach(novels => {\n                return novels.forEach(novel => {\n                    novelList.push(novel)\n                })\n            })\n        return formatNovels(handNovels(novelList))\n    }\n}\n\nfunction handlerRecommend() {\n    return () => {\n        let res = JSON.parse(result)\n        const recommend = res.body.page.recommend\n        const novels = res.body.thumbnails.novel\n        let nidSet = new Set(recommend.ids)\n        \/\/ java.log(nidSet.size)\n        let list = novels.filter(novel => nidSet.has(String(novel.id)))\n        \/\/ java.log(`过滤结果:${JSON.stringify(list)}`)\n        return formatNovels(handNovels(combineNovels(list)))\n    }\n}\n\nfunction handlerNoLogin() {\n    return () => {\n        java.longToast(\"此功能需要在书源登录后才能使用\")\n        return []\n    }\n}\n\nfunction handlerBookMarks() {\n    return () => {\n        let resp = JSON.parse(result).body.works\n        if (resp === undefined || resp.length === 0) {\n            \/\/流程无法本环节中止 只能交给下一流程处理\n            return []\n        }\n\n        return formatNovels(handNovels(resp))\n    }\n}\n\n(() => {\n    return handlerFactory()()\n})()",
        "bookUrl": "detailedUrl",
        "coverUrl": "coverUrl",
        "intro": "description",
        "kind": "tags",
        "lastChapter": "latestChapter",
        "name": "title",
        "wordCount": "textCount"
    },
    "ruleSearch": {
        "author": "userName",
        "bookList": "@js:\nvar util = {};\n\nfunction objStringify(obj) {\n    return JSON.stringify(obj, (n, v) => {\n        if (typeof v == \"function\")\n            return v.toString();\n        return v;\n    });\n}\n\nfunction urlCoverUrl(url) {\n    return `${url},{\"headers\": {\"Referer\":\"https:\/\/www.pixiv.net\/\"}}`\n}\n\n\/\/ 完全匹配用户名\nfunction urlSearchUser(username) {\n    return `https:\/\/www.pixiv.net\/search_user.php?s_mode=s_usr&nick=${encodeURI(username)}&nick_mf=1`\n}\n\nfunction urlUserAllWorks(uid) {\n    return `https:\/\/www.pixiv.net\/ajax\/user\/${uid}\/profile\/all?lang=zh`\n}\n\nfunction urlUserNovels(uid, nidList) {\n    return `https:\/\/www.pixiv.net\/ajax\/user\/${uid}\/novels?${nidList.map(v => \"ids[]=\" + v).join(\"&\")}`\n}\n\nvar first = true;\n\n\/\/ 存储seriesID\nvar seriesSet = {\n    keywords: \"Pixiv:Search\",\n    has: (value) => {\n        let page = Number(java.get(\"page\"))\n        if (page === 1 && first) {\n            first = false\n            cache.deleteMemory(this.keywords)\n            return false\n        }\n\n        let v = cache.getFromMemory(this.keywords)\n        if (v === undefined || v === null) {\n            return false\n        }\n        let set = new Set(JSON.parse(v))\n        return set.has(value)\n    },\n\n    add: (value) => {\n        let v = cache.getFromMemory(this.keywords)\n        if (v === undefined || v === null) {\n            cache.putMemory(this.keywords, JSON.stringify([value]))\n\n        } else {\n            let arr = JSON.parse(v)\n            if (typeof arr === \"string\") {\n                arr = Array(arr)\n            }\n            arr.push(value)\n            cache.putMemory(this.keywords, JSON.stringify(arr))\n        }\n    },\n};\n\n\/\/ 将多个长篇小说解析为一本书\nfunction combineNovels(novels) {\n    return novels.filter(novel => {\n        \/\/单本直接解析为一本书\n        if (novel.seriesId === undefined || novel.seriesId === null) {\n            return true\n        }\n\n        \/\/集合中没有该系列解析为一本书\n        if (!seriesSet.has(novel.seriesId)) {\n            seriesSet.add(novel.seriesId)\n            return true\n        }\n\n        return false\n    })\n}\n\n\/\/处理novels列表\n\/\/查询作者\nfunction handNovels(novels) {\n    novels.forEach(novel => {\n        if (novel.tags === undefined || novel.tags === null) {\n            novel.tags = []\n        }\n\n        if (novel.seriesId === undefined || novel.seriesId === null) {\n            novel.tags.unshift(\"单本\")\n        } else {\n            let userAllWorks = getAjaxJson(urlUserAllWorks(novel.userId)).body\n            for (let series of userAllWorks.novelSeries) {\n                if (series.id === novel.seriesId) {\n                    \/\/ let series = getAjaxJson(util.urlSeries(novel.seriesId)).body\n                    novel.textCount = series.publishedTotalCharacterCount\n                    novel.url = series.cover.urls[\"480mw\"]\n                    novel.title = series.title\n                    novel.tags = series.tags\n                    novel.description = series.caption\n\n                    \/\/ 发送请求获取第一章 获取标签与简介\n                    if (novel.tags.length === 0 || novel.description === \"\") {\n                        let firstNovel = getAjaxJson(util.urlNovelDetailed(series.firstNovelId)).body\n                        if (novel.tags.length === 0) {\n                            novel.tags = firstNovel.tags.tags.map(item => item.tag)\n                        }\n\n                        if (novel.description === \"\") {\n                            novel.description = firstNovel.description\n                        }\n                    }\n\n                    novel.tags.unshift(\"长篇\")\n                    break\n                }\n            }\n        }\n    })\n    util.debugFunc(() => {\n        java.log(`处理小说完成`)\n    })\n    return novels\n}\n\nfunction formatNovels(novels) {\n    novels.forEach(novel => {\n        novel.detailedUrl = util.urlNovelDetailed(novel.id)\n        novel.tags = novel.tags.join(\",\")\n        novel.coverUrl = urlCoverUrl(novel.url)\n    })\n    return novels\n}\n\nfunction getAjaxJson(url) {\n    return util.cacheGetAndSet(url, () => {\n        return JSON.parse(java.ajax(url))\n    })\n}\n\nfunction getWebviewJson(url, parseFunc) {\n    return util.cacheGetAndSet(url, () => {\n        let html = java.webView(null, url, null)\n        return JSON.parse(parseFunc(html))\n    })\n}\n\nfunction isLogin() {\n    let cookie = String(java.getCookie(\"https:\/\/www.pixiv.net\/\", null))\n    return typeof cookie === \"string\" && cookie !== \"\"\n}\n\nfunction getUserNovels(username) {\n    if (!isLogin()) {\n        return []\n    }\n\n    let html = java.ajax(urlSearchUser(username))\n    \/\/ java.log(html)\n    \/\/ 仅匹配有投稿作品的用户\n    let match = html.match(new RegExp(\"\/users\/\\\\d+\/novels\"))\n    if (match === null || match.length === 0) {\n        return []\n    }\n\n    let regNumber = new RegExp(\"\\\\d+\")\n    let uidList = match.map(v => {\n        return v.match(regNumber)[0]\n    })\n\n    \/\/ 仅限3个作者\n    if (uidList.length >= 3) {\n        uidList.length = 3\n    }\n\n    let novels = []\n    let page = Number(java.get(\"page\"))\n\n    uidList.forEach(id => {\n        let r = getAjaxJson(urlUserAllWorks(id))\n        let novelsId = Object.keys(r.body.novels).reverse().slice((page - 1) * 20, page * 20)\n        let url = urlUserNovels(id, novelsId)\n        \/\/ java.log(`发送的Ajax请求:${url}`)\n        let userNovels = getWebviewJson(url, html => {\n            return (html.match(new RegExp(\">\\\\{.*?}<\"))[0].replace(\">\", \"\").replace(\"<\", \"\"))\n        }).body\n        novels = novels.concat(Object.values(userNovels))\n    })\n\n\n    util.debugFunc(() => {\n        java.log(`获取用户搜索小说结束`)\n    })\n    return novels\n}\n\n\/\/ 存储函数方便其他页面调用\nfunction init() {\n    let u = {}\n\n    u.cacheGetAndSet = (key, supplyFunc) => {\n        let v = cache.get(key)\n        if (v === undefined || v === null) {\n            v = JSON.stringify(supplyFunc())\n            \/\/ 缓存10分钟\n            cache.put(key, v, 600)\n        }\n        return JSON.parse(v)\n    }\n    u.debugFunc = (func) => {\n        if (String(source.getVariable()) === \"debug\") {\n            func()\n        }\n    }\n\n    u.urlNovelDetailed = (nid) => {\n        return `https:\/\/www.pixiv.net\/ajax\/novel\/${nid}`\n    }\n    u.urlSeries = (seriesId) => {\n        return `https:\/\/www.pixiv.net\/ajax\/novel\/series\/${seriesId}?lang=zh`\n    }\n    u.urlSeriesNovels = (seriesId, limit, offset) => {\n        if (limit > 30) {\n            limit = 30\n        }\n\n        if (limit < 10) {\n            limit = 10\n        }\n\n        return `https:\/\/www.pixiv.net\/ajax\/novel\/series_content\/${seriesId}?limit=${limit}&last_order=${offset}&order_by=asc&lang=zh`\n    }\n    util = u\n    java.put(\"util\", objStringify(u))\n}\n\n(() => {\n    \/\/作者 TAG 书名都要支持\n    init()\n    let resp = JSON.parse(result);\n    let novelsList = getUserNovels(String(java.get(\"key\")))\n    novelsList = novelsList.concat(resp.body.novel.data)\n    return formatNovels(handNovels(combineNovels(novelsList)))\n})();",
        "bookUrl": "detailedUrl",
        "coverUrl": "coverUrl",
        "intro": "description",
        "kind": "tags",
        "lastChapter": "latestChapter",
        "name": "title",
        "wordCount": "textCount"
    },
    "ruleToc": {
        "chapterList": "@js:\n\nvar util = objParse(String(java.get(\"util\")))\n\nfunction objParse(obj) {\n    return JSON.parse(obj, (n, v) => {\n        if (typeof v == \"string\" && v.match(\"()\")) {\n            return eval(`(${v})`)\n        }\n        return v;\n    })\n}\n\nfunction seriesHandler(res) {\n    const limit = 30\n    let returnList = [];\n    let seriesID = res.seriesNavData.seriesId\n    let allChaptersCount = (() => {\n        let result = util.cacheGetAndSet(util.urlSeries(seriesID), () => {\n            return JSON.parse(java.ajax(util.urlSeries(seriesID)))\n        }).body.total\n        util.debugFunc(() => {\n            java.log(`本目录一共有:${result} 章节`);\n        })\n        return result;\n    })();\n\n    \/\/发送请求获得相应数量的目录列表\n    function sendAjaxForGetChapters(lastIndex) {\n        let url = util.urlSeriesNovels(seriesID, limit, lastIndex)\n        res = util.cacheGetAndSet(url, () => {\n            return JSON.parse(java.ajax(url))\n        })\n        res = res.body.page.seriesContents\n        res.forEach(v => {\n            v.chapterUrl = util.urlNovelDetailed(v.id)\n        })\n        return res;\n    }\n\n    \/\/逻辑控制者 也就是使用上面定义的两个函数来做对应功能\n    \/\/要爬取的总次数\n    let max = (allChaptersCount \/ limit) + 1\n    for (let i = 0; i < max; i++) {\n        \/\/java.log(\"i的值:\"+i)\n        let list = sendAjaxForGetChapters(i * limit);\n        \/\/取出每个值\n        returnList = returnList.concat(list)\n    }\n    return returnList\n}\n\nfunction aloneHandler() {\n    return [{title: book.name, chapterUrl: baseUrl}]\n}\n\n(() => {\n    let res = JSON.parse(result).body\n    if (res.seriesNavData === null || res.seriesNavData === undefined) {\n        return aloneHandler()\n    }\n    return seriesHandler(res)\n})()",
        "chapterName": "title",
        "chapterUrl": "chapterUrl"
    },
    "searchUrl": "@js:\njava.put(\"page\",page);java.put(\"key\",key);\n`https:\/\/www.pixiv.net\/ajax\/search\/novels\/${encodeURI(key)}?word=${encodeURI(key)}&order=date_d&mode=all&p=${page}&s_mode=s_tag&lang=zh`;",
    "weight": 0
}
广告