diff --git a/docs/en/other.md b/docs/en/other.md index 5ecd0c63c..00306cb50 100644 --- a/docs/en/other.md +++ b/docs/en/other.md @@ -238,3 +238,13 @@ Type | all | rec | + +## 裏垢女子まとめ + +### Homepage + + + +### User + + diff --git a/docs/other.md b/docs/other.md index a384dda4f..be1f00bfb 100644 --- a/docs/other.md +++ b/docs/other.md @@ -613,11 +613,11 @@ type 为 all 时,category 参数不支持 cost 和 free ### 主页 - + ### 用户 - + ## 律师事务所文章 diff --git a/lib/router.js b/lib/router.js index fe938fdbc..6c60021c1 100644 --- a/lib/router.js +++ b/lib/router.js @@ -1378,9 +1378,9 @@ router.get('/blogs/wang54/:id?', lazyloadRouteHandler('./routes/blogs/wang54')); // WordPress router.get('/blogs/wordpress/:domain/:https?', lazyloadRouteHandler('./routes/blogs/wordpress')); -// 裏垢女子まとめ -router.get('/uraaka-joshi', lazyloadRouteHandler('./routes/uraaka-joshi/uraaka-joshi')); -router.get('/uraaka-joshi/:id', lazyloadRouteHandler('./routes/uraaka-joshi/uraaka-joshi-user')); +// 裏垢女子まとめ migrated to v2 +// router.get('/uraaka-joshi', lazyloadRouteHandler('./routes/uraaka-joshi/uraaka-joshi')); +// router.get('/uraaka-joshi/:id', lazyloadRouteHandler('./routes/uraaka-joshi/uraaka-joshi-user')); // 西祠胡同 router.get('/xici/:id?', lazyloadRouteHandler('./routes/xici')); diff --git a/lib/routes/uraaka-joshi/uraaka-joshi-user.js b/lib/routes/uraaka-joshi/uraaka-joshi-user.js deleted file mode 100644 index fab365311..000000000 --- a/lib/routes/uraaka-joshi/uraaka-joshi-user.js +++ /dev/null @@ -1,28 +0,0 @@ -const buildData = require('@/utils/common-config'); - -module.exports = async (ctx) => { - const params = ctx.params; - const link = `https://www.uraaka-joshi.com/users/${params.id}`; - ctx.state.data = await buildData({ - link, - url: link, - title: `$('.top-profile-card-name-link').text() + '@${params.id} - 裏垢女子まとめ'`, - item: { - item: '.content-main .stream .stream-item .post', - title: `$('.post-name').text() + '@${params.id} - 裏垢女子まとめ'`, - link: `https://www.uraaka-joshi.com/users/${params.id}`, - description: `$('.context *').removeAttr('onclick'); - $('.context *').removeAttr('onerror'); - $('.context *').removeAttr('style'); - $('.context video').each((video) => { - const poster = $(video).attr('poster') - const src = $(video).attr('src') - $(video).attr('poster', 'https:' + poster) - $(video).attr('src', 'https:' + src) - }); - $('.context').html();`, - pubDate: `new Date($('.post-time').attr('datetime')).toUTCString()`, - guid: `new Date($('.post-time').attr('datetime')).getTime()`, - }, - }); -}; diff --git a/lib/routes/uraaka-joshi/uraaka-joshi.js b/lib/routes/uraaka-joshi/uraaka-joshi.js deleted file mode 100644 index aa3509c67..000000000 --- a/lib/routes/uraaka-joshi/uraaka-joshi.js +++ /dev/null @@ -1,30 +0,0 @@ -const buildData = require('@/utils/common-config'); - -module.exports = async (ctx) => { - const link = `https://www.uraaka-joshi.com/`; - ctx.state.data = await buildData({ - link, - url: link, - title: `%title%`, - params: { - title: '裏垢女子まとめ', - }, - item: { - item: '.content-main .stream .stream-item .post', - title: `$('.post-account-group').text() + ' - %title%'`, - link: `$('.post-account-group').attr('href')`, - description: `$('.context *').removeAttr('onclick'); - $('.context *').removeAttr('onerror'); - $('.context *').removeAttr('style'); - $('.context video').each((video) => { - const poster = $(video).attr('poster') - const src = $(video).attr('src') - $(video).attr('poster', 'https:' + poster) - $(video).attr('src', 'https:' + src) - }); - $('.context').html();`, - pubDate: `new Date($('.post-time').attr('datetime')).toUTCString()`, - guid: `new Date($('.post-time').attr('datetime')).getTime()`, - }, - }); -}; diff --git a/lib/v2/uraaka-joshi/maintainer.js b/lib/v2/uraaka-joshi/maintainer.js new file mode 100644 index 000000000..7b2bbf67d --- /dev/null +++ b/lib/v2/uraaka-joshi/maintainer.js @@ -0,0 +1,4 @@ +module.exports = { + '/': ['SettingDust', 'Halcao'], + '/:id': ['SettingDust', 'Halcao'], +}; diff --git a/lib/v2/uraaka-joshi/radar.js b/lib/v2/uraaka-joshi/radar.js new file mode 100644 index 000000000..07285e081 --- /dev/null +++ b/lib/v2/uraaka-joshi/radar.js @@ -0,0 +1,19 @@ +module.exports = { + 'uraaka-joshi.com': { + _name: '裏垢女子まとめ', + '.': [ + { + title: '主页', + docs: 'https://docs-rsshub.pages.dev/other.html#li-gou-nu-zi-まとめ', + source: ['/'], + target: '/uraaka-joshi', + }, + { + title: '用户', + docs: 'https://docs-rsshub.pages.dev/other.html#li-gou-nu-zi-まとめ', + source: ['/:id'], + target: '/uraaka-joshi/:id', + }, + ], + }, +}; diff --git a/lib/v2/uraaka-joshi/router.js b/lib/v2/uraaka-joshi/router.js new file mode 100644 index 000000000..f4c4775db --- /dev/null +++ b/lib/v2/uraaka-joshi/router.js @@ -0,0 +1,4 @@ +module.exports = (router) => { + router.get('/', require('./uraaka-joshi')); + router.get('/:id', require('./uraaka-joshi-user')); +}; diff --git a/lib/v2/uraaka-joshi/uraaka-joshi-user.js b/lib/v2/uraaka-joshi/uraaka-joshi-user.js new file mode 100644 index 000000000..8f6ede029 --- /dev/null +++ b/lib/v2/uraaka-joshi/uraaka-joshi-user.js @@ -0,0 +1,89 @@ +const cheerio = require('cheerio'); +const { parseDate } = require('@/utils/parse-date'); +const config = require('@/config').value; + +module.exports = async (ctx) => { + const { id } = ctx.params; + const link = `https://www.uraaka-joshi.com/user/${id}`; + + const response = await ctx.cache.tryGet( + link, + async () => { + const browser = await require('@/utils/puppeteer')(); + const page = await browser.newPage(); + + await page.goto(link); + await page.waitForSelector('#pickup03 .grid-cell'); + await page.waitForSelector('#pickup04 .grid-cell'); + await page.waitForSelector('#main-block .grid-cell'); + + const html = await page.evaluate(() => document.documentElement.innerHTML); + browser.close(); + return html; + }, + config.cache.routeExpire, + false + ); + + const $ = cheerio.load(response); + const items = $('#main-block .grid .grid-cell') + .toArray() + .map((item) => { + item = $(item); + + // remove event and styles + item.find('*').removeAttr('onclick'); + item.find('*').removeAttr('onerror'); + item.find('*').removeAttr('style'); + + // format account style + const account = item.find('.account-group-link-row'); + account.html(account.text()); + + // extract video tag from its player + item.find('.plyr--video').each((_, player) => { + player = $(player); + + const v = player.find('video'); + player.replaceWith(v); + v.attr('poster', 'https:' + v.attr('data-poster')); + v.find('source').attr('src', 'https:' + v.find('source').attr('src')); + }); + + // correct src of img tags + item.find('img').each((_, i) => { + i = $(i); + i.attr('src', 'https:' + i.attr('data-src').split('?resize')[0]); + i.removeAttr('data-src'); + }); + + const author = item.find('.account-group').text(); + const categories = item + .find('.hashtag-item .hashtag') + .toArray() + .map((c) => $(c).text().trim()); + const link = item.find('.account-group-link-row').attr('href'); + const date = parseDate(item.find('.profile-char').attr('datetime')); + const guid = item.find('a.tap-image').attr('data-tweet-id') || item.find('video[class^="js-player-"]').attr('data-tweet-id'); + + item.find('.grow-room').remove(); + item.find('div.profile-group.mt10.prl2').eq(1).remove(); + + return { + title: item.find('.profile-text').text(), + description: item.html(), + link, + pubDate: date, + guid, + category: categories, + author, + }; + }); + + ctx.state.data = { + title: $('title').text(), + description: $('meta[name="description"]').attr('content'), + link, + item: items, + }; +}; diff --git a/lib/v2/uraaka-joshi/uraaka-joshi.js b/lib/v2/uraaka-joshi/uraaka-joshi.js new file mode 100644 index 000000000..7c657fde4 --- /dev/null +++ b/lib/v2/uraaka-joshi/uraaka-joshi.js @@ -0,0 +1,71 @@ +const cheerio = require('cheerio'); +const { parseDate } = require('@/utils/parse-date'); + +module.exports = async (ctx) => { + const link = `https://www.uraaka-joshi.com/`; + const title = `裏垢女子まとめ`; + + const browser = await require('@/utils/puppeteer')(); + + const page = await browser.newPage(); + await page.goto(link); + + await page.waitForSelector('#pickup03 .grid-cell'); + await page.waitForSelector('#pickup04 .grid-cell'); + await page.waitForSelector('#main-block .grid-cell'); + + const bodyHandle = await page.$('body'); + const html = await page.evaluate((body) => body.innerHTML, bodyHandle); + browser.close(); + const $ = cheerio.load(html); + const list = $('.grid-cell'); + + ctx.state.data = { + title, + link, + item: + list && + list + .map((index, item) => { + item = $(item); + + // remove event and styles + item.find('*').removeAttr('onclick'); + item.find('*').removeAttr('onerror'); + item.find('*').removeAttr('style'); + + // format account style + const account = item.find('.account-group-link-row'); + account.html(account.text()); + + // extract video tag from its player + item.find('.plyr--video').each((_, player) => { + player = $(player); + + const video = player.find('video'); + player.replaceWith(video); + const poster = video.attr('data-poster'); + video.attr('poster', 'https:' + poster); + + const source = video.find('source'); + const src = source.attr('src'); + source.attr('src', 'https:' + src); + }); + + // correct src of img tags + item.find('img').each((_, image) => { + const src = $(image).attr('data-src'); + $(image).attr('src', 'https:' + src); + }); + + return { + title: item.find('.account-group').text() + ` - ${title}`, + description: item.html(), + link: item.find('.account-group-link-row').attr('href'), + pubDate: parseDate(item.find('.profile-char').attr('datetime')), + guid: item.find('a.tap-image').attr('data-tweet-id') || item.find('video[class^="js-player-"]').attr('data-tweet-id') || parseDate(item.find('.profile-char').attr('datetime')).getTime(), + }; + }) + .get(), + }; +};